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"
21 #include "../rx/rx_kcommon.h"
22 #include "../rx/rx_kmutex.h"
23 #include "../rx/rx_kernel.h"
27 void afs_mutex_init(afs_kmutex_t *l)
29 #if defined(AFS_LINUX24_ENV)
37 void afs_mutex_enter(afs_kmutex_t *l)
41 osi_Panic("mutex_enter: 0x%x held by %d", l, l->owner);
42 l->owner = current->pid;
45 int afs_mutex_tryenter(afs_kmutex_t *l)
47 if (down_trylock(&l->sem))
49 l->owner = current->pid;
53 void afs_mutex_exit(afs_kmutex_t *l)
55 if (l->owner != current->pid)
56 osi_Panic("mutex_exit: 0x%x held by %d",
63 * CV_WAIT and CV_TIMEDWAIT rely on the fact that the Linux kernel has
64 * a global lock. Thus we can safely drop our locks before calling the
65 * kernel sleep services.
68 int afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *l, int sigok)
70 int isAFSGlocked = ISAFS_GLOCK();
72 #ifdef DECLARE_WAITQUEUE
73 DECLARE_WAITQUEUE(wait, current);
75 struct wait_queue wait = { current, NULL };
78 add_wait_queue(cv, &wait);
79 set_current_state(TASK_INTERRUPTIBLE);
81 if (isAFSGlocked) AFS_GUNLOCK();
85 spin_lock_irq(¤t->sigmask_lock);
86 saved_set = current->blocked;
87 sigfillset(¤t->blocked);
88 recalc_sigpending(current);
89 spin_unlock_irq(¤t->sigmask_lock);
93 remove_wait_queue(cv, &wait);
96 spin_lock_irq(¤t->sigmask_lock);
97 current->blocked = saved_set;
98 recalc_sigpending(current);
99 spin_unlock_irq(¤t->sigmask_lock);
102 if (isAFSGlocked) AFS_GLOCK();
105 return (sigok && signal_pending(current)) ? EINTR : 0;
108 void afs_cv_timedwait(afs_kcondvar_t *cv, afs_kmutex_t *l, int waittime)
110 int isAFSGlocked = ISAFS_GLOCK();
111 long t = waittime * HZ / 1000;
112 #ifdef DECLARE_WAITQUEUE
113 DECLARE_WAITQUEUE(wait, current);
115 struct wait_queue wait = { current, NULL };
118 add_wait_queue(cv, &wait);
119 set_current_state(TASK_INTERRUPTIBLE);
121 if (isAFSGlocked) AFS_GUNLOCK();
124 t = schedule_timeout(t);
125 remove_wait_queue(cv, &wait);
127 if (isAFSGlocked) AFS_GLOCK();