X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lnet%2Fselftest%2Ftimer.c;h=4b8ad60f8068cc87da30a740a4566b94087a682a;hp=97d92970542aebec26f8ac4eb2e8a7c85db68a03;hb=9fb46705ae86aa2c0ac29427f0ff24f923560eb7;hpb=776615e6825e2c90c2635c8b55e7bb02da33726c diff --git a/lnet/selftest/timer.c b/lnet/selftest/timer.c index 97d9297..4b8ad60 100644 --- a/lnet/selftest/timer.c +++ b/lnet/selftest/timer.c @@ -1,17 +1,45 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * Author: Isaac Huang + * Copyright (c) 2011, Whamcloud, Inc. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lnet/selftest/timer.c * + * Author: Isaac Huang */ #define DEBUG_SUBSYSTEM S_LNET -#include -#include -#include - #include "selftest.h" @@ -22,49 +50,50 @@ * sorted by increasing expiry time. The number of slots is 2**7 (128), * to cover a time period of 1024 seconds into the future before wrapping. */ -#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ -#define STTIMER_SLOTTIME (1 << STTIMER_MINPOLL) -#define STTIMER_SLOTTIMEMASK (~(STTIMER_SLOTTIME - 1)) -#define STTIMER_NSLOTS (1 << 7) -#define STTIMER_SLOT(t) (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \ +#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ +#define STTIMER_SLOTTIME (1 << STTIMER_MINPOLL) +#define STTIMER_SLOTTIMEMASK (~(STTIMER_SLOTTIME - 1)) +#define STTIMER_NSLOTS (1 << 7) +#define STTIMER_SLOT(t) (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \ (STTIMER_NSLOTS - 1))]) struct st_timer_data { - spinlock_t stt_lock; + spinlock_t stt_lock; /* start time of the slot processed previously */ - cfs_time_t stt_prev_slot; - struct list_head stt_hash[STTIMER_NSLOTS]; + cfs_time_t stt_prev_slot; + cfs_list_t stt_hash[STTIMER_NSLOTS]; int stt_shuttingdown; #ifdef __KERNEL__ + cfs_waitq_t stt_waitq; int stt_nthreads; #endif } stt_data; void -stt_add_timer (stt_timer_t *timer) +stt_add_timer(stt_timer_t *timer) { - struct list_head *pos; + cfs_list_t *pos; - spin_lock(&stt_data.stt_lock); + spin_lock(&stt_data.stt_lock); #ifdef __KERNEL__ LASSERT (stt_data.stt_nthreads > 0); #endif LASSERT (!stt_data.stt_shuttingdown); LASSERT (timer->stt_func != NULL); - LASSERT (list_empty(&timer->stt_list)); + LASSERT (cfs_list_empty(&timer->stt_list)); LASSERT (cfs_time_after(timer->stt_expires, cfs_time_current_sec())); /* a simple insertion sort */ - list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) { - stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list); + cfs_list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) { + stt_timer_t *old = cfs_list_entry(pos, stt_timer_t, stt_list); if (cfs_time_aftereq(timer->stt_expires, old->stt_expires)) break; } - list_add(&timer->stt_list, pos); + cfs_list_add(&timer->stt_list, pos); - spin_unlock(&stt_data.stt_lock); + spin_unlock(&stt_data.stt_lock); } /* @@ -79,47 +108,47 @@ stt_add_timer (stt_timer_t *timer) int stt_del_timer (stt_timer_t *timer) { - int ret = 0; + int ret = 0; - spin_lock(&stt_data.stt_lock); + spin_lock(&stt_data.stt_lock); #ifdef __KERNEL__ LASSERT (stt_data.stt_nthreads > 0); #endif LASSERT (!stt_data.stt_shuttingdown); - if (!list_empty(&timer->stt_list)) { + if (!cfs_list_empty(&timer->stt_list)) { ret = 1; - list_del_init(&timer->stt_list); + cfs_list_del_init(&timer->stt_list); } - spin_unlock(&stt_data.stt_lock); - return ret; + spin_unlock(&stt_data.stt_lock); + return ret; } /* called with stt_data.stt_lock held */ int -stt_expire_list (struct list_head *slot, cfs_time_t now) +stt_expire_list (cfs_list_t *slot, cfs_time_t now) { int expired = 0; stt_timer_t *timer; - while (!list_empty(slot)) { - timer = list_entry(slot->next, stt_timer_t, stt_list); + while (!cfs_list_empty(slot)) { + timer = cfs_list_entry(slot->next, stt_timer_t, stt_list); if (cfs_time_after(timer->stt_expires, now)) break; - list_del_init(&timer->stt_list); - spin_unlock(&stt_data.stt_lock); + cfs_list_del_init(&timer->stt_list); + spin_unlock(&stt_data.stt_lock); - expired++; - (*timer->stt_func) (timer->stt_data); - - spin_lock(&stt_data.stt_lock); - } + expired++; + (*timer->stt_func) (timer->stt_data); - return expired; + spin_lock(&stt_data.stt_lock); + } + + return expired; } int @@ -132,16 +161,16 @@ stt_check_timers (cfs_time_t *last) now = cfs_time_current_sec(); this_slot = now & STTIMER_SLOTTIMEMASK; - spin_lock(&stt_data.stt_lock); + spin_lock(&stt_data.stt_lock); - while (cfs_time_aftereq(this_slot, *last)) { - expired += stt_expire_list(STTIMER_SLOT(this_slot), now); - this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME); - } + while (cfs_time_aftereq(this_slot, *last)) { + expired += stt_expire_list(STTIMER_SLOT(this_slot), now); + this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME); + } - *last = now & STTIMER_SLOTTIMEMASK; - spin_unlock(&stt_data.stt_lock); - return expired; + *last = now & STTIMER_SLOTTIMEMASK; + spin_unlock(&stt_data.stt_lock); + return expired; } #ifdef __KERNEL__ @@ -149,23 +178,27 @@ stt_check_timers (cfs_time_t *last) int stt_timer_main (void *arg) { + int rc = 0; UNUSED(arg); + SET_BUT_UNUSED(rc); + cfs_daemonize("st_timer"); cfs_block_allsigs(); while (!stt_data.stt_shuttingdown) { stt_check_timers(&stt_data.stt_prev_slot); - set_current_state(CFS_TASK_INTERRUPTIBLE); - cfs_schedule_timeout(CFS_TASK_INTERRUPTIBLE, - cfs_time_seconds(STTIMER_SLOTTIME)); + cfs_waitq_wait_event_timeout(stt_data.stt_waitq, + stt_data.stt_shuttingdown, + cfs_time_seconds(STTIMER_SLOTTIME), + rc); } - spin_lock(&stt_data.stt_lock); - stt_data.stt_nthreads--; - spin_unlock(&stt_data.stt_lock); - return 0; + spin_lock(&stt_data.stt_lock); + stt_data.stt_nthreads--; + spin_unlock(&stt_data.stt_lock); + return 0; } int @@ -175,14 +208,14 @@ stt_start_timer_thread (void) LASSERT (!stt_data.stt_shuttingdown); - pid = cfs_kernel_thread(stt_timer_main, NULL, 0); + pid = cfs_create_thread(stt_timer_main, NULL, 0); if (pid < 0) return (int)pid; - spin_lock(&stt_data.stt_lock); - stt_data.stt_nthreads++; - spin_unlock(&stt_data.stt_lock); - return 0; + spin_lock(&stt_data.stt_lock); + stt_data.stt_nthreads++; + spin_unlock(&stt_data.stt_lock); + return 0; } #else /* !__KERNEL__ */ @@ -210,15 +243,16 @@ stt_startup (void) stt_data.stt_shuttingdown = 0; stt_data.stt_prev_slot = cfs_time_current_sec() & STTIMER_SLOTTIMEMASK; - spin_lock_init(&stt_data.stt_lock); + spin_lock_init(&stt_data.stt_lock); for (i = 0; i < STTIMER_NSLOTS; i++) CFS_INIT_LIST_HEAD(&stt_data.stt_hash[i]); #ifdef __KERNEL__ stt_data.stt_nthreads = 0; + cfs_waitq_init(&stt_data.stt_waitq); rc = stt_start_timer_thread(); if (rc != 0) - CERROR ("Can't spawn timer, stt_startup() has failed: %d\n", rc); + CERROR ("Can't spawn timer thread: %d\n", rc); #endif return rc; @@ -229,19 +263,19 @@ stt_shutdown (void) { int i; - spin_lock(&stt_data.stt_lock); + spin_lock(&stt_data.stt_lock); for (i = 0; i < STTIMER_NSLOTS; i++) - LASSERT (list_empty(&stt_data.stt_hash[i])); + LASSERT (cfs_list_empty(&stt_data.stt_hash[i])); stt_data.stt_shuttingdown = 1; #ifdef __KERNEL__ + cfs_waitq_signal(&stt_data.stt_waitq); lst_wait_until(stt_data.stt_nthreads == 0, stt_data.stt_lock, "waiting for %d threads to terminate\n", stt_data.stt_nthreads); #endif - spin_unlock(&stt_data.stt_lock); - return; + spin_unlock(&stt_data.stt_lock); }