2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * rx_kmutex.c - mutex and condition variable macros for kernel environment.
13 * Linux implementation.
16 #include <afsconfig.h>
17 #include "afs/param.h"
22 #include "rx/rx_kcommon.h"
23 #include "rx_kmutex.h"
24 #include "rx/rx_kernel.h"
26 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
29 afs_mutex_init(afs_kmutex_t * l)
31 #if defined(AFS_LINUX24_ENV)
40 afs_mutex_enter(afs_kmutex_t * l)
44 osi_Panic("mutex_enter: 0x%x held by %d", l, l->owner);
45 l->owner = current->pid;
49 afs_mutex_tryenter(afs_kmutex_t * l)
51 if (down_trylock(&l->sem))
53 l->owner = current->pid;
58 afs_mutex_exit(afs_kmutex_t * l)
60 if (l->owner != current->pid)
61 osi_Panic("mutex_exit: 0x%x held by %d", l, l->owner);
66 /* CV_WAIT and CV_TIMEDWAIT sleep until the specified event occurs, or, in the
67 * case of CV_TIMEDWAIT, until the specified timeout occurs.
68 * - NOTE: that on Linux, there are circumstances in which TASK_INTERRUPTIBLE
69 * can wake up, even if all signals are blocked
70 * - TODO: handle signals correctly by passing an indication back to the
71 * caller that the wait has been interrupted and the stack should be cleaned
72 * up preparatory to signal delivery
75 afs_cv_wait(afs_kcondvar_t * cv, afs_kmutex_t * l, int sigok)
77 int isAFSGlocked = ISAFS_GLOCK();
79 #ifdef DECLARE_WAITQUEUE
80 DECLARE_WAITQUEUE(wait, current);
82 struct wait_queue wait = { current, NULL };
85 add_wait_queue(cv, &wait);
86 set_current_state(TASK_INTERRUPTIBLE);
94 saved_set = current->blocked;
95 sigfillset(¤t->blocked);
96 RECALC_SIGPENDING(current);
101 remove_wait_queue(cv, &wait);
105 current->blocked = saved_set;
106 RECALC_SIGPENDING(current);
114 return (sigok && signal_pending(current)) ? EINTR : 0;
118 afs_cv_timedwait(afs_kcondvar_t * cv, afs_kmutex_t * l, int waittime)
120 int isAFSGlocked = ISAFS_GLOCK();
121 long t = waittime * HZ / 1000;
122 #ifdef DECLARE_WAITQUEUE
123 DECLARE_WAITQUEUE(wait, current);
125 struct wait_queue wait = { current, NULL };
128 add_wait_queue(cv, &wait);
129 set_current_state(TASK_INTERRUPTIBLE);
135 t = schedule_timeout(t);
136 remove_wait_queue(cv, &wait);