First pass at better signal handling:
authorNickolai Zeldovich <kolya@mit.edu>
Fri, 1 Feb 2002 20:29:59 +0000 (20:29 +0000)
committerNickolai Zeldovich <kolya@mit.edu>
Fri, 1 Feb 2002 20:29:59 +0000 (20:29 +0000)
  -- Add afs_osi_SleepSig, which returns EINTR when interrupted by signal.
  -- Similar CV_WAIT_SIG for Rx code.
  -- Implement afs_osi_SleepSig and CV_WAIT_SIG for Linux, Solaris.
  -- Use afs_osi_SleepSig in afs_{UFS,Mem}Read, allowing user to interrupt
     an AFS read if it's being handled by background daemon.
  -- Balance the number of open & close braces in CV_TIMEDWAIT macros,
     even though noone uses them.
  -- Untangle parts of the macro forest by moving some of the Rx CV code
     into rx_kmutex.c.

31 files changed:
src/afs/AIX/osi_sleep.c
src/afs/DARWIN/osi_sleep.c
src/afs/DUX/osi_sleep.c
src/afs/FBSD/osi_sleep.c
src/afs/HPUX/osi_sleep.c
src/afs/IRIX/osi_sleep.c
src/afs/LINUX/osi_sleep.c
src/afs/NBSD/osi_sleep.c
src/afs/SOLARIS/osi_sleep.c
src/afs/UKERNEL/afs_usrops.c
src/afs/VNOPS/afs_vnop_read.c
src/libafs/Makefile.common.in
src/libuafs/Makefile.common.in
src/rx/AIX/rx_kmutex.c [new file with mode: 0644]
src/rx/DARWIN/rx_kmutex.c [new file with mode: 0644]
src/rx/DARWIN/rx_kmutex.h
src/rx/DUX/rx_kmutex.c [new file with mode: 0644]
src/rx/DUX/rx_kmutex.h
src/rx/FBSD/rx_kmutex.c [new file with mode: 0644]
src/rx/FBSD/rx_kmutex.h
src/rx/HPUX/rx_kmutex.c [new file with mode: 0644]
src/rx/IRIX/rx_kmutex.c [new file with mode: 0644]
src/rx/LINUX/rx_kmutex.c [new file with mode: 0644]
src/rx/LINUX/rx_kmutex.h
src/rx/Makefile.in
src/rx/NBSD/rx_kmutex.c [new file with mode: 0644]
src/rx/NBSD/rx_kmutex.h
src/rx/SOLARIS/rx_kmutex.c [new file with mode: 0644]
src/rx/SOLARIS/rx_kmutex.h
src/rx/UKERNEL/rx_kmutex.c [new file with mode: 0644]
src/rx/UKERNEL/rx_kmutex.h

index 13eb885..bee54e6 100644 (file)
@@ -148,6 +148,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index ceac98d..83bb904 100644 (file)
@@ -144,6 +144,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index 94c70a9..3c38401 100644 (file)
@@ -141,6 +141,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index 11f26ed..1b018a5 100644 (file)
@@ -142,6 +142,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index 248c858..f586fe7 100644 (file)
@@ -106,3 +106,9 @@ int afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
     } while (osi_Time() < endTime);
     return code;
 }
+
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
index 7437974..a4eb686 100644 (file)
@@ -143,6 +143,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index b5b5e96..cf30788 100644 (file)
@@ -203,12 +203,15 @@ static void afs_addevent(char *event)
 /* Release the specified event */
 #define relevent(evp) ((evp)->refcount--)
 
-/* afs_osi_Sleep -- waits for an event to be notified. */
-
-void afs_osi_Sleep(char *event)
+/* afs_osi_SleepSig
+ *
+ * Waits for an event to be notified, returning early if a signal
+ * is received.  Returns EINTR if signaled, and 0 otherwise.
+ */
+int afs_osi_SleepSig(char *event)
 {
     struct afs_event *evp;
-    int seq;
+    int seq, retval;
 
     evp = afs_getevent(event);
     if (!evp) {
@@ -217,31 +220,43 @@ void afs_osi_Sleep(char *event)
          * allocator then return immediately.  We'll find the new event next
          * time around without dropping the GLOCK. */
         afs_addevent(event);
-        return;
+        return 0;
     }
 
     seq = evp->seq;
+    retval = 0;
 
     while (seq == evp->seq) {
-       sigset_t saved_set;
-
        AFS_ASSERT_GLOCK();
        AFS_GUNLOCK();
-       spin_lock_irq(&current->sigmask_lock);
-       saved_set = current->blocked;
-       sigfillset(&current->blocked);
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-
        interruptible_sleep_on(&evp->cond);
-
-       spin_lock_irq(&current->sigmask_lock);
-       current->blocked = saved_set;
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
        AFS_GLOCK();
+       if (signal_pending(current)) {
+           retval = EINTR;
+           break;
+       }
     }
     relevent(evp);
+    return retval;
+}
+
+/* afs_osi_Sleep -- waits for an event to be notified, ignoring signals. */
+void afs_osi_Sleep(char *event)
+{
+    sigset_t saved_set;
+
+    spin_lock_irq(&current->sigmask_lock);
+    saved_set = current->blocked;
+    sigfillset(&current->blocked);
+    recalc_sigpending(current);
+    spin_unlock_irq(&current->sigmask_lock);
+
+    afs_osi_SleepSig(event);
+
+    spin_lock_irq(&current->sigmask_lock);
+    current->blocked = saved_set;
+    recalc_sigpending(current);
+    spin_unlock_irq(&current->sigmask_lock);
 }
 
 /* osi_TimedSleep
index 11f26ed..1b018a5 100644 (file)
@@ -142,6 +142,12 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
index 9ae0b09..97b95d4 100644 (file)
@@ -136,6 +136,24 @@ void afs_osi_Sleep(char *event)
     relevent(evp);
 }
 
+int afs_osi_SleepSig(char *event)
+{
+    struct afs_event *evp;
+    int seq, code = 0;
+
+    evp = afs_getevent(event);
+    seq = evp->seq;
+    while (seq == evp->seq) {
+       AFS_ASSERT_GLOCK();
+       if (cv_wait_sig(&evp->cond, &afs_global_lock) == 0) {
+           code = EINTR;
+           break;
+       }
+    }
+    relevent(evp);
+    return code;
+}
+
 /* osi_TimedSleep
  * 
  * Arguments:
@@ -158,7 +176,7 @@ static int osi_TimedSleep(char *event, afs_int32 ams, int aintok)
 
     AFS_ASSERT_GLOCK();
     if (aintok) {
-       if (cv_timedwait_sig(&evp->cond, &afs_global_lock, ticks) == -1)
+       if (cv_timedwait_sig(&evp->cond, &afs_global_lock, ticks) == 0)
            code = EINTR;
     } else {
        cv_timedwait(&evp->cond, &afs_global_lock, ticks);
index c64484d..57fcff0 100644 (file)
@@ -487,6 +487,13 @@ caddr_t x;
     }
 }
 
+int afs_osi_SleepSig(x)
+    caddr_t x;
+{
+    afs_osi_Sleep(x);
+    return 0;
+}
+
 int afs_osi_Wakeup(x)
 caddr_t x;
 {
index 8fa980b..a0222f4 100644 (file)
@@ -192,24 +192,33 @@ tagain:
                        ConvertWToSLock(&tdc->mflock);
                        /* don't use bp pointer! */
                    }
+                   code = 0;
                    ConvertSToRLock(&tdc->mflock);
-                   while (tdc->mflags & DFFetchReq) {
+                   while (!code && tdc->mflags & DFFetchReq) {
                        /* don't need waiting flag on this one */
                        ReleaseReadLock(&tdc->mflock);
                        ReleaseReadLock(&tdc->lock);
                        ReleaseReadLock(&avc->lock);
-                       afs_osi_Sleep(&tdc->validPos);
+                       code = afs_osi_SleepSig(&tdc->validPos);
                        ObtainReadLock(&avc->lock);
                        ObtainReadLock(&tdc->lock);
                        ObtainReadLock(&tdc->mflock);
                    }
                    ReleaseReadLock(&tdc->mflock);
+                   if (code) {
+                       error = code;
+                       break;
+                   }
                }
            }
            /* now data may have started flowing in (if DFFetching is on).  If
-            * data is now streaming in, then wait for some interesting stuff. */
-           while ((tdc->dflags & DFFetching) && tdc->validPos <= filePos) {
-               /* too early: wait for DFFetching flag to vanish, or data to appear */
+            * data is now streaming in, then wait for some interesting stuff.
+            */
+           code = 0;
+           while (!code && (tdc->dflags & DFFetching) &&
+                  tdc->validPos <= filePos) {
+               /* too early: wait for DFFetching flag to vanish,
+                * or data to appear */
                afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
                                ICL_TYPE_STRING, __FILE__,
                                ICL_TYPE_INT32, __LINE__,
@@ -217,10 +226,14 @@ tagain:
                                ICL_TYPE_INT32, tdc->dflags);
                ReleaseReadLock(&tdc->lock);
                ReleaseReadLock(&avc->lock);
-               afs_osi_Sleep(&tdc->validPos);
+               code = afs_osi_SleepSig(&tdc->validPos);
                ObtainReadLock(&avc->lock);
                ObtainReadLock(&tdc->lock);
            }
+           if (code) {
+               error = code;
+               break;
+           }
            /* fetching flag gone, data is here, or we never tried (BBusy for instance) */
            if (tdc->dflags & DFFetching) {
                /* still fetching, some new data is here: compute length and offset */
@@ -711,24 +724,33 @@ tagain:
                        }
                        ConvertWToSLock(&tdc->mflock);
                    }
+                   code = 0;
                    ConvertSToRLock(&tdc->mflock);
-                   while (tdc->mflags & DFFetchReq) {
+                   while (!code && tdc->mflags & DFFetchReq) {
                        /* don't need waiting flag on this one */
                        ReleaseReadLock(&tdc->mflock);
                        ReleaseReadLock(&tdc->lock);
                        ReleaseReadLock(&avc->lock);
-                       afs_osi_Sleep(&tdc->validPos);
+                       code = afs_osi_SleepSig(&tdc->validPos);
                        ObtainReadLock(&avc->lock);
                        ObtainReadLock(&tdc->lock);
                        ObtainReadLock(&tdc->mflock);
                    }
                    ReleaseReadLock(&tdc->mflock);
+                   if (code) {
+                       error = code;
+                       break;
+                   }
                }
            }
            /* now data may have started flowing in (if DFFetching is on).  If
-            * data is now streaming in, then wait for some interesting stuff. */
-           while ((tdc->dflags & DFFetching) && tdc->validPos <= filePos) {
-               /* too early: wait for DFFetching flag to vanish, or data to appear */
+            * data is now streaming in, then wait for some interesting stuff.
+            */
+           code = 0;
+           while (!code && (tdc->dflags & DFFetching) &&
+                  tdc->validPos <= filePos) {
+               /* too early: wait for DFFetching flag to vanish,
+                * or data to appear */
                afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
                                ICL_TYPE_STRING, __FILE__,
                                ICL_TYPE_INT32, __LINE__,
@@ -736,18 +758,25 @@ tagain:
                                ICL_TYPE_INT32, tdc->dflags);
                ReleaseReadLock(&tdc->lock);
                ReleaseReadLock(&avc->lock);
-               afs_osi_Sleep(&tdc->validPos);
+               code = afs_osi_SleepSig(&tdc->validPos);
                ObtainReadLock(&avc->lock);
                ObtainReadLock(&tdc->lock);
            }
-           /* fetching flag gone, data is here, or we never tried (BBusy for instance) */
+           if (code) {
+               error = code;
+               break;
+           }
+           /* fetching flag gone, data is here, or we never tried
+            * (BBusy for instance) */
            if (tdc->dflags & DFFetching) {
-               /* still fetching, some new data is here: compute length and offset */
+               /* still fetching, some new data is here:
+                * compute length and offset */
                offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk);
                len = tdc->validPos - filePos;
            }
            else {
-               /* no longer fetching, verify data version (avoid new GetDCache call) */
+               /* no longer fetching, verify data version (avoid new
+                * GetDCache call) */
                if (hsame(avc->m.DataVersion, tdc->f.versionNo)) {
                    offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk);
                    len = tdc->f.chunkBytes - offset;
index f56c303..3ee5551 100644 (file)
@@ -99,6 +99,7 @@ AFSAOBJS = \
        rx_clock.o      \
        rx_event.o      \
        rx_globals.o    \
+       rx_kmutex.o     \
        rx_knet.o       \
        rx_kcommon.o    \
        rx_misc.o       \
@@ -313,6 +314,8 @@ Kvldbint.xdr.o: $(AFSINT)/Kvldbint.xdr.c
        $(CRULE1) -DAFS_UUID_XG
 afs_main.o: $(AFS)/afs_main.c
        $(CRULE1)
+rx_kmutex.o: $(RX)/rx_kmutex.c
+       $(CRULE1)
 rx_knet.o: $(RX)/rx_knet.c
        $(CRULE1)
 rx_kcommon.o: $(RX)/rx_kcommon.c
index bf1043f..805dd24 100644 (file)
@@ -113,6 +113,7 @@ UAFSOBJ = \
        $(UOBJ)/rx_clock.o \
        $(UOBJ)/rx_event.o \
        $(UOBJ)/rx_globals.o \
+       $(UOBJ)/rx_kmutex.o \
        $(UOBJ)/rx_knet.o \
        $(UOBJ)/rx_kcommon.o \
        $(UOBJ)/rx_misc.o \
@@ -230,6 +231,7 @@ AFSWEBOBJ = \
        $(WEBOBJ)/rx_clock.o \
        $(WEBOBJ)/rx_event.o \
        $(WEBOBJ)/rx_globals.o \
+       $(WEBOBJ)/rx_kmutex.o \
        $(WEBOBJ)/rx_knet.o \
        $(WEBOBJ)/rx_kcommon.o \
        $(WEBOBJ)/rx_misc.o \
@@ -347,6 +349,7 @@ AFSWEBOBJKRB = \
        $(WEBOBJ)/rx_clock.o \
        $(WEBOBJ)/rx_event.o \
        $(WEBOBJ)/rx_globals.o \
+       $(WEBOBJ)/rx_kmutex.o \
        $(WEBOBJ)/rx_knet.o \
        $(WEBOBJ)/rx_kcommon.o \
        $(WEBOBJ)/rx_misc.o \
@@ -564,6 +567,8 @@ $(UOBJ)/Kvldbint.xdr.o: $(AFSINT)/Kvldbint.xdr.c
        $(CRULE1)
 $(UOBJ)/afs_main.o: $(AFS)/afs_main.c
        $(CRULE1)
+$(UOBJ)/rx_kmutex.o: $(RX)/rx_kmutex.c
+       $(CRULE1)
 $(UOBJ)/rx_knet.o: $(RX)/rx_knet.c
        $(CRULE1)
 $(UOBJ)/rx_kcommon.o: $(RX)/rx_kcommon.c
@@ -807,6 +812,8 @@ $(WEBOBJ)/Kvldbint.xdr.o: $(AFSINT)/Kvldbint.xdr.c
        $(CRULE2)
 $(WEBOBJ)/afs_main.o: $(AFS)/afs_main.c
        $(CRULE2)
+$(WEBOBJ)/rx_kmutex.o: $(RX)/rx_kmutex.c
+       $(CRULE2)
 $(WEBOBJ)/rx_knet.o: $(RX)/rx_knet.c
        $(CRULE2)
 $(WEBOBJ)/rx_kcommon.o: $(RX)/rx_kcommon.c
diff --git a/src/rx/AIX/rx_kmutex.c b/src/rx/AIX/rx_kmutex.c
new file mode 100644 (file)
index 0000000..8f344f3
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * AIX 4.x implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
diff --git a/src/rx/DARWIN/rx_kmutex.c b/src/rx/DARWIN/rx_kmutex.c
new file mode 100644 (file)
index 0000000..7aa430c
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * MACOS implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
index 530b3ce..98fecf6 100644 (file)
@@ -54,6 +54,7 @@
                                thread_block(0);                \
                                if (isGlockOwner) AFS_GLOCK();  \
                                MUTEX_ENTER(lck);       \
+                               }
 
 #define CV_SIGNAL(cv)           thread_wakeup_one((event_t)(cv))
 #define CV_BROADCAST(cv)        thread_wakeup((event_t)(cv))
diff --git a/src/rx/DUX/rx_kmutex.c b/src/rx/DUX/rx_kmutex.c
new file mode 100644 (file)
index 0000000..e269509
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * DUX implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
index 683360b..791b77c 100644 (file)
@@ -53,6 +53,7 @@
                                thread_block();         \
                                if (isGlockOwner) AFS_GLOCK();  \
                                MUTEX_ENTER(lck);       \
+                               }
 
 #define CV_SIGNAL(cv)          thread_wakeup_one((vm_offset_t)(cv))
 #define CV_BROADCAST(cv)       thread_wakeup((vm_offset_t)(cv))
diff --git a/src/rx/FBSD/rx_kmutex.c b/src/rx/FBSD/rx_kmutex.c
new file mode 100644 (file)
index 0000000..0d756f4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * FreeBSD implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
index 924d8c2..771d2fc 100644 (file)
@@ -45,6 +45,7 @@
                                thread_block();         \
                                if (isGlockOwner) AFS_GLOCK();  \
                                MUTEX_ENTER(lck);       \
+                               }
 
 #define CV_SIGNAL(cv)          thread_wakeup_one((vm_offset_t)(cv))
 #define CV_BROADCAST(cv)       thread_wakeup((vm_offset_t)(cv))
diff --git a/src/rx/HPUX/rx_kmutex.c b/src/rx/HPUX/rx_kmutex.c
new file mode 100644 (file)
index 0000000..2d5e40c
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * HPUX implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
diff --git a/src/rx/IRIX/rx_kmutex.c b/src/rx/IRIX/rx_kmutex.c
new file mode 100644 (file)
index 0000000..31b6296
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * IRIX implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
diff --git a/src/rx/LINUX/rx_kmutex.c b/src/rx/LINUX/rx_kmutex.c
new file mode 100644 (file)
index 0000000..3ee6926
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * Linux implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+#include "../rx/rx_kcommon.h"
+#include "../rx/rx_kmutex.h"
+#include "../rx/rx_kernel.h"
+
+#ifdef CONFIG_SMP
+
+void afs_mutex_init(afs_kmutex_t *l)
+{
+#if defined(AFS_LINUX24_ENV)
+    init_MUTEX(&l->sem);
+#else
+    l->sem = MUTEX;
+#endif
+    l->owner = 0;
+}
+
+void afs_mutex_enter(afs_kmutex_t *l)
+{
+    down(&l->sem);
+    if (l->owner)
+       osi_Panic("mutex_enter: 0x%x held by %d", l, l->owner);
+    l->owner = current->pid;
+}
+                                                             
+int afs_mutex_tryenter(afs_kmutex_t *l)
+{
+    if (down_trylock(&l->sem))
+       return 0;
+    l->owner = current->pid;
+    return 1;
+}
+
+void afs_mutex_exit(afs_kmutex_t *l)
+{
+    if (l->owner != current->pid)
+       osi_Panic("mutex_exit: 0x%x held by %d",
+                 l, l->owner);
+    l->owner = 0;
+    up(&l->sem);
+}
+
+/*
+ * CV_WAIT and CV_TIMEDWAIT rely on the fact that the Linux kernel has
+ * a global lock. Thus we can safely drop our locks before calling the
+ * kernel sleep services.
+ */
+int afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *l, int sigok)
+{
+    int isAFSGlocked = ISAFS_GLOCK();
+    sigset_t saved_set;
+
+    if (isAFSGlocked) AFS_GUNLOCK();
+    MUTEX_EXIT(l);
+
+    if (!sigok) {
+       spin_lock_irq(&current->sigmask_lock);
+       saved_set = current->blocked;
+       sigfillset(&current->blocked);
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
+    }
+
+#if defined(AFS_LINUX24_ENV)
+    interruptible_sleep_on((wait_queue_head_t *)cv);
+#else
+    interruptible_sleep_on((struct wait_queue**)cv);
+#endif
+
+    if (!sigok) {
+       spin_lock_irq(&current->sigmask_lock);
+       current->blocked = saved_set;
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
+    }
+
+    MUTEX_ENTER(l);
+    if (isAFSGlocked) AFS_GLOCK();
+
+    return (sigok && signal_pending(current)) ? EINTR : 0;
+}
+
+void afs_cv_timedwait(afs_kcondvar_t *cv, afs_kmutex_t *l, int waittime)
+{
+    int isAFSGlocked = ISAFS_GLOCK();
+    long t = waittime * HZ / 1000;
+
+    if (isAFSGlocked) AFS_GUNLOCK();
+    MUTEX_EXIT(l);
+    
+#if defined(AFS_LINUX24_ENV)
+    t = interruptible_sleep_on_timeout((wait_queue_head_t *)cv, t);
+#else
+    t = interruptible_sleep_on_timeout((struct wait_queue**)cv, t);
+#endif
+    
+    MUTEX_ENTER(l);
+    if (isAFSGlocked) AFS_GLOCK();
+}
+
+#endif
index 8b49213..d8f5499 100644 (file)
@@ -50,128 +50,28 @@ static inline int MUTEX_ISMINE(afs_kmutex_t *l)
     return l->owner == current->pid;
 }
 
-
-static inline void afs_mutex_init(afs_kmutex_t *l)
-{
-#if defined(AFS_LINUX24_ENV)
-    init_MUTEX(&l->sem);
-#else
-    l->sem = MUTEX;
-#endif
-    l->owner = 0;
-}
-#define MUTEX_INIT(a,b,c,d) afs_mutex_init(a)
-
+#define MUTEX_INIT(a,b,c,d)    afs_mutex_init(a)
 #define MUTEX_DESTROY(a)
-
-static inline void MUTEX_ENTER(afs_kmutex_t *l)
-{
-    down(&l->sem);
-    if (l->owner)
-       osi_Panic("mutex_enter: 0x%x held by %d", l, l->owner);
-    l->owner = current->pid;
-}
-                                                             
-/* And how to do a good tryenter? */
-static inline int MUTEX_TRYENTER(afs_kmutex_t *l)
-{
-    if (!l->owner) {
-       MUTEX_ENTER(l);
-       return 1;
-    }
-    else
-       return 0;
-}
-
-static inline void MUTEX_EXIT(afs_kmutex_t *l)
-{
-    if (l->owner != current->pid)
-       osi_Panic("mutex_exit: 0x%x held by %d",
-                 l, l->owner);
-    l->owner = 0;
-    up(&l->sem);
-}
+#define MUTEX_ENTER            afs_mutex_enter
+#define MUTEX_TRYENTER         afs_mutex_tryenter
+#define MUTEX_EXIT             afs_mutex_exit
 
 #if defined(AFS_LINUX24_ENV)
-#define CV_INIT(cv,b,c,d) init_waitqueue_head((wait_queue_head_t *)(cv))
+#define CV_INIT(cv,b,c,d)      init_waitqueue_head((wait_queue_head_t *)(cv))
 #else
-#define CV_INIT(cv,b,c,d) init_waitqueue((struct wait_queue**)(cv))
+#define CV_INIT(cv,b,c,d)      init_waitqueue((struct wait_queue**)(cv))
 #endif
 #define CV_DESTROY(cv)
-
-/* CV_WAIT and CV_TIMEDWAIT rely on the fact that the Linux kernel has
- * a global lock. Thus we can safely drop our locks before calling the
- * kernel sleep services.
- */
-static inline int CV_WAIT(afs_kcondvar_t *cv, afs_kmutex_t *l)
-{
-    int isAFSGlocked = ISAFS_GLOCK(); 
-    sigset_t saved_set;
-
-    if (isAFSGlocked) AFS_GUNLOCK();
-    MUTEX_EXIT(l);
-
-    spin_lock_irq(&current->sigmask_lock);
-    saved_set = current->blocked;
-    sigfillset(&current->blocked);
-    recalc_sigpending(current);
-    spin_unlock_irq(&current->sigmask_lock);
-
-#if defined(AFS_LINUX24_ENV)
-    interruptible_sleep_on((wait_queue_head_t *)cv);
-#else
-    interruptible_sleep_on((struct wait_queue**)cv);
-#endif
-
-    spin_lock_irq(&current->sigmask_lock);
-    current->blocked = saved_set;
-    recalc_sigpending(current);
-    spin_unlock_irq(&current->sigmask_lock);
-
-    MUTEX_ENTER(l);
-    if (isAFSGlocked) AFS_GLOCK();
-
-    return 0;
-}
-
-static inline int CV_TIMEDWAIT(afs_kcondvar_t *cv, afs_kmutex_t *l, int waittime)
-{
-    int isAFSGlocked = ISAFS_GLOCK();
-    long t = waittime * HZ / 1000;
-    sigset_t saved_set;
-
-    if (isAFSGlocked) AFS_GUNLOCK();
-    MUTEX_EXIT(l);
-    
-    spin_lock_irq(&current->sigmask_lock);
-    saved_set = current->blocked;
-    sigfillset(&current->blocked);
-    recalc_sigpending(current);
-    spin_unlock_irq(&current->sigmask_lock);
-
-#if defined(AFS_LINUX24_ENV)
-    t = interruptible_sleep_on_timeout((wait_queue_head_t *)cv, t);
-#else
-    t = interruptible_sleep_on_timeout((struct wait_queue**)cv, t);
-#endif
-    
-    spin_lock_irq(&current->sigmask_lock);
-    current->blocked = saved_set;
-    recalc_sigpending(current);
-    spin_unlock_irq(&current->sigmask_lock);
-
-    MUTEX_ENTER(l);
-    if (isAFSGlocked) AFS_GLOCK();
-
-    return 0;
-}
+#define CV_WAIT_SIG(cv, m)     afs_cv_wait(cv, m, 1)
+#define CV_WAIT(cv, m)         afs_cv_wait(cv, m, 0)
+#define CV_TIMEDWAIT           afs_cv_timedwait
 
 #if defined(AFS_LINUX24_ENV)
-#define CV_SIGNAL(cv) wake_up((wait_queue_head_t *)cv)
-#define CV_BROADCAST(cv) wake_up((wait_queue_head_t *)cv)
+#define CV_SIGNAL(cv)          wake_up((wait_queue_head_t *)cv)
+#define CV_BROADCAST(cv)       wake_up((wait_queue_head_t *)cv)
 #else
-#define CV_SIGNAL(cv) wake_up((struct wait_queue**)cv)
-#define CV_BROADCAST(cv) wake_up((struct wait_queue**)cv)
+#define CV_SIGNAL(cv)          wake_up((struct wait_queue**)cv)
+#define CV_BROADCAST(cv)       wake_up((struct wait_queue**)cv)
 #endif
 
 #else
index d7fd900..dd59dcd 100644 (file)
@@ -186,6 +186,7 @@ kinstall: \
        ${KERNELDIR}/rx/rx_kcommon.c \
        ${KERNELDIR}/rx/rx_kcommon.h \
        ${KERNELDIR}/rx/rx_kernel.h \
+       ${KERNELDIR}/rx/rx_kmutex.c \
        ${KERNELDIR}/rx/rx_kmutex.h \
        ${KERNELDIR}/rx/rx_knet.c \
        ${KERNELDIR}/rx/rx_misc.c \
@@ -221,6 +222,7 @@ ukinstall: \
        ${UKERNELDIR}/rx/rx_kcommon.c \
        ${UKERNELDIR}/rx/rx_kcommon.h \
        ${UKERNELDIR}/rx/rx_kernel.h \
+       ${UKERNELDIR}/rx/rx_kmutex.c \
        ${UKERNELDIR}/rx/rx_kmutex.h \
        ${UKERNELDIR}/rx/rx_knet.c \
        ${UKERNELDIR}/rx/rx_misc.c \
@@ -284,6 +286,9 @@ ${KERNELDIR}/rx/rx_kcommon.h: rx_kcommon.h
 ${KERNELDIR}/rx/rx_kernel.h: rx_kernel.h
        ${INSTALL} $? $@
 
+${KERNELDIR}/rx/rx_kmutex.c: ${MKAFS_OSTYPE}/rx_kmutex.c
+       ${INSTALL} $? $@
+
 ${KERNELDIR}/rx/rx_kmutex.h: ${MKAFS_OSTYPE}/rx_kmutex.h
        ${INSTALL} $? $@
 
@@ -380,6 +385,9 @@ ${UKERNELDIR}/rx/rx_kcommon.h: UKERNEL/rx_kcommon.h
 ${UKERNELDIR}/rx/rx_kernel.h: rx_kernel.h
        ${INSTALL} $? $@
 
+${UKERNELDIR}/rx/rx_kmutex.c: UKERNEL/rx_kmutex.c
+       ${INSTALL} $? $@
+
 ${UKERNELDIR}/rx/rx_kmutex.h: UKERNEL/rx_kmutex.h
        ${INSTALL} $? $@
 
diff --git a/src/rx/NBSD/rx_kmutex.c b/src/rx/NBSD/rx_kmutex.c
new file mode 100644 (file)
index 0000000..c4b5782
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * NetBSD implementation.
+ */
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
index 530b3ce..98fecf6 100644 (file)
@@ -54,6 +54,7 @@
                                thread_block(0);                \
                                if (isGlockOwner) AFS_GLOCK();  \
                                MUTEX_ENTER(lck);       \
+                               }
 
 #define CV_SIGNAL(cv)           thread_wakeup_one((event_t)(cv))
 #define CV_BROADCAST(cv)        thread_wakeup((event_t)(cv))
diff --git a/src/rx/SOLARIS/rx_kmutex.c b/src/rx/SOLARIS/rx_kmutex.c
new file mode 100644 (file)
index 0000000..38e6798
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * Solaris implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+#if defined(AFS_SUN5_ENV) && defined(KERNEL) 
+
+#include "../rx/rx_kmutex.h"
+
+#include <errno.h>
+#include <sys/tiuser.h>
+#include <sys/t_lock.h>
+#include <sys/mutex.h>
+
+#ifdef RX_LOCKS_DB
+int afs_cv_wait(cv, m, sigok, fileid, line)
+    int fileid;
+    int line;
+#else
+int afs_cv_wait(cv, m, sigok)
+#endif
+    afs_kcondvar_t *cv;
+    afs_kmutex_t *m;
+    int sigok;
+{
+    int haveGlock = ISAFS_GLOCK();
+    int retval = 0;
+
+    if (haveGlock)
+       AFS_GUNLOCK();
+#ifdef RX_LOCKS_DB
+    rxdb_droplock(m, osi_ThreadUnique(), fileid, line);
+#endif
+    if (sigok) {
+       if (cv_wait_sig(cv, m) == 0)
+           retval = EINTR;
+    } else {
+       cv_wait(cv, m);
+    }
+#ifdef RX_LOCKS_DB
+    rxdb_grablock(m, osi_ThreadUnique(), fileid, line);
+#endif
+    if (haveGlock) {
+       MUTEX_EXIT(m);
+       AFS_GLOCK();
+       MUTEX_ENTER(m);
+    }
+    return retval;
+}
+
+#ifdef RX_LOCKS_DB
+int afs_cv_timedwait(cv, m, t, sigok, fileid, line)
+    int fileid;
+    int line;
+#else
+int afs_cv_timedwait(cv, m, t, sigok)
+#endif
+    afs_kcondvar_t *cv;
+    afs_kmutex_t *m;
+    clock_t t;
+    int sigok;
+{
+    int haveGlock = ISAFS_GLOCK();
+    int retval = 0;
+
+    if (haveGlock)
+       AFS_GUNLOCK();
+#ifdef RX_LOCKS_DB
+    rxdb_droplock(m, osi_ThreadUnique(), fileid, line);
+#endif
+    if (sigok) {
+       if (cv_timedwait_sig(cv, m, t) == 0)
+           retval = EINTR;
+    } else {
+       cv_timedwait(cv, m, t);
+    }
+#ifdef RX_LOCKS_DB
+    rxdb_grablock(m, osi_ThreadUnique(), fileid, line);
+#endif
+    if (haveGlock) {
+       MUTEX_EXIT(m);
+       AFS_GLOCK();
+       MUTEX_ENTER(m);
+    }
+    return retval;
+}
+
+#endif /* SUN5 && KERNEL */
index ca0f17c..eaf324a 100644 (file)
@@ -57,35 +57,11 @@ extern void osirx_AssertMine(afs_kmutex_t *lockaddr, char *msg);
        mutex_exit(a); \
     } while(0)
 
-#define CV_WAIT(_cv, _lck) \
-    do { \
-       int haveGlock = ISAFS_GLOCK(); \
-       if (haveGlock) \
-           AFS_GUNLOCK(); \
-       rxdb_droplock((_lck), osi_ThreadUnique(), rxdb_fileID, __LINE__); \
-       cv_wait(_cv, _lck); \
-       rxdb_grablock((_lck), osi_ThreadUnique(), rxdb_fileID, __LINE__); \
-       if (haveGlock) { \
-           MUTEX_EXIT(_lck); \
-           AFS_GLOCK(); \
-           MUTEX_ENTER(_lck); \
-       } \
-    } while (0)
-
-#define CV_TIMEDWAIT(_cv,_lck,_t) \
-    do { \
-       int haveGlock = ISAFS_GLOCK(); \
-       if (haveGlock) \
-           AFS_GUNLOCK(); \
-       rxdb_droplock((_lck), osi_ThreadUnique(), rxdb_fileID, __LINE__); \
-       cv_timedwait(_cv, _lck, t); \
-       rxdb_grablock((_lck), osi_ThreadUnique(), rxdb_fileID, __LINE__); \
-       if (haveGlock) { \
-           MUTEX_EXIT(_lck); \
-           AFS_GLOCK(); \
-           MUTEX_ENTER(_lck); \
-       } \
-     } while (0)
+#define CV_WAIT_SIG(cv, m)     afs_cv_wait(cv, m, 1, rxdb_fileID, __LINE__)
+#define CV_WAIT(cv, m)         afs_cv_wait(cv, m, 0, rxdb_fileID, __LINE__)
+
+#define CV_TIMEDWAIT(cv, m, t) \
+                       afs_cv_timedwait(cv, lck, t, 0, rxdb_fileID, __LINE__)
 
 #else /* RX_LOCKS_DB */
 
@@ -93,31 +69,10 @@ extern void osirx_AssertMine(afs_kmutex_t *lockaddr, char *msg);
 #define MUTEX_TRYENTER(a)      mutex_tryenter(a)
 #define MUTEX_EXIT(a)          mutex_exit(a)
 
-#define CV_WAIT(_cv, _lck) \
-    do { \
-       int haveGlock = ISAFS_GLOCK(); \
-       if (haveGlock) \
-           AFS_GUNLOCK(); \
-       cv_wait(_cv, _lck); \
-       if (haveGlock) { \
-           MUTEX_EXIT(_lck); \
-           AFS_GLOCK(); \
-           MUTEX_ENTER(_lck); \
-       } \
-    } while (0)
-
-#define CV_TIMEDWAIT(_cv,_lck,_t) \
-    do { \
-       int haveGlock = ISAFS_GLOCK(); \
-       if (haveGlock) \
-           AFS_GUNLOCK(); \
-       cv_timedwait(_cv, _lck, t); \
-       if (haveGlock) { \
-           MUTEX_EXIT(_lck); \
-           AFS_GLOCK(); \
-           MUTEX_ENTER(_lck); \
-       } \
-     } while (0)
+#define CV_WAIT_SIG(cv, m)     afs_cv_wait(cv, m, 1)
+#define CV_WAIT(cv, m)         afs_cv_wait(cv, m, 0)
+
+#define CV_TIMEDWAIT(cv, m, t) afs_cv_timedwait(cv, m, t, 0)
 
 #endif /* RX_LOCKS_DB */
 
diff --git a/src/rx/UKERNEL/rx_kmutex.c b/src/rx/UKERNEL/rx_kmutex.c
new file mode 100644 (file)
index 0000000..6127dce
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * rx_kmutex.c - mutex and condition variable macros for kernel environment.
+ *
+ * UKERNEL implementation.
+ */
+
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
+/*
+ * Currently everything is implemented in rx_kmutex.h
+ */
index 170e8e6..4247e6e 100644 (file)
@@ -10,7 +10,7 @@
 /*
  * rx_kmutex.h - mutex and condition variable macros for kernel environment.
  *
- * Solaris implementation.
+ * User-space implementation.
  */
 
 #ifndef _RX_KMUTEX_H_