OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/WINNT/client_osi/osibasel.h
00001 /*
00002  * Copyright 2000, International Business Machines Corporation and others.
00003  * All Rights Reserved.
00004  *
00005  * This software has been released under the terms of the IBM Public
00006  * License.  For details, see the LICENSE file in the top-level source
00007  * directory or online at http://www.openafs.org/dl/license10.html
00008  */
00009 
00010 /* Copyright (C) 1994 Cazamar Systems, Inc. */
00011 
00012 #ifndef OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H
00013 #define OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H 1
00014 
00015 /* flags for osi_mutex_t and osi_rwlock_t flags fields.  Some bits
00016  * are used only in one structure or another.
00017  */
00018 #define OSI_LOCKFLAG_EXCL               1       /* exclusive locked (rwlock only) */
00019 
00020 /* a mutex (pure exclusive lock).  This structure has two forms.  In the
00021  * base type (type == 0), the d field is interpreted as an atomic counter,
00022  * and all the other fields are used.  In the other types, type specifies
00023  * which operations to use (via the global osi_lockOps), and d.privateDatap
00024  * points to the real data used by the mutex.
00025  *
00026  * For the base type, flags tells us if the lock is held, and if anyone else
00027  * is waiting for the lock.  The field d.atomicCount is used to implement a spin
00028  * lock using an atomic increment operation.
00029  */
00030 typedef struct osi_mutex {
00031     short type;                 /* for all types; type 0 uses atomic count */
00032     unsigned short atomicIndex; /* index of lock for low-level sync */
00033     int flags;                  /* flags for base type */
00034     DWORD tid;                  /* tid of thread that owns the lock */
00035     int waiters;                /* waiters */
00036     unsigned short level;       /* locking hierarchy level */
00037     short pad1;
00038     int pad2;
00039     union {
00040         void *privateDatap;     /* data pointer for non-zero types */
00041         osi_turnstile_t turn;   /* turnstile */
00042     } d;
00043 } osi_mutex_t;
00044 
00045 /* a read/write lock.  This structure has two forms.  In the
00046  * base type (type == 0), the d field is interpreted as an atomic counter,
00047  * and all the other fields are used.  In the other types, type specifies
00048  * which operations to use (via the global osi_lockOps), and d.privateDatap
00049  * points to the real data used by the mutex.
00050  *
00051  * For the base type, flags tells us if the lock is held, and if anyone else
00052  * is waiting for the lock.  The field d.atomicCount is used to implement a spin
00053  * lock using an atomic increment operation.
00054  *
00055  * This type of lock has N readers or one writer.
00056  */
00057 
00058 #define OSI_RWLOCK_THREADS 64
00059 
00060 typedef struct osi_rwlock {
00061     short type;                 /* for all types; type 0 uses atomic count */
00062     unsigned short atomicIndex; /* index into hash table for low-level sync */
00063     int flags;                  /* flags */
00064     int waiters;                /* waiters */
00065     int readers;                /* readers */
00066     DWORD tid[OSI_RWLOCK_THREADS];      /* writer's tid */
00067     short pad2;
00068     unsigned short level;       /* locking hierarchy level */
00069     union {
00070         void *privateDatap;     /* data pointer for non-zero types */
00071         osi_turnstile_t turn;   /* turnstile */
00072     } d;
00073 } osi_rwlock_t;
00074 
00075 
00076 /*
00077  * a lock reference is a queue object that maintains a reference to a
00078  * mutex or read/write lock object.  Its intended purpose is for
00079  * maintaining lists of lock objects on a per thread basis.
00080  */
00081 typedef struct osi_lock_ref {
00082     osi_queue_t q;
00083     char type;
00084     union {
00085         osi_rwlock_t *rw;
00086         osi_mutex_t  *mx;
00087     };
00088 } osi_lock_ref_t;
00089 
00090 #define OSI_LOCK_MUTEX  1
00091 #define OSI_LOCK_RW     2
00092 
00093 extern void lock_ObtainRead (struct osi_rwlock *);
00094 
00095 extern void lock_ObtainWrite (struct osi_rwlock *);
00096 
00097 extern void lock_ReleaseRead (struct osi_rwlock *);
00098 
00099 extern void lock_ReleaseWrite (struct osi_rwlock *);
00100 
00101 extern void lock_ObtainMutex (struct osi_mutex *);
00102 
00103 extern void lock_ReleaseMutex (struct osi_mutex *);
00104 
00105 extern int lock_TryRead (struct osi_rwlock *);
00106 
00107 extern int lock_TryWrite (struct osi_rwlock *);
00108 
00109 extern int lock_TryMutex (struct osi_mutex *);
00110 
00111 extern void osi_SleepR (LONG_PTR, struct osi_rwlock *);
00112 
00113 extern void osi_SleepW (LONG_PTR, struct osi_rwlock *);
00114 
00115 extern void osi_SleepM (LONG_PTR, struct osi_mutex *);
00116 
00117 extern void osi_Sleep (LONG_PTR);
00118 
00119 extern void osi_Wakeup (LONG_PTR);
00120 
00121 extern void lock_FinalizeRWLock(struct osi_rwlock *);
00122 
00123 extern void lock_FinalizeMutex(struct osi_mutex *);
00124 
00125 extern CRITICAL_SECTION osi_baseAtomicCS[];
00126 
00127 /* and define the functions that create basic locks and mutexes */
00128 
00129 extern void lock_InitializeRWLock(struct osi_rwlock *, char *, unsigned short level);
00130 
00131 extern void lock_InitializeMutex(struct osi_mutex *, char *, unsigned short level);
00132 
00133 extern void osi_Init (void);
00134 
00135 extern void lock_ConvertWToR(struct osi_rwlock *);
00136 
00137 extern void lock_ConvertRToW(struct osi_rwlock *);
00138 
00139 /* and stat functions */
00140 
00141 extern int lock_GetRWLockState(struct osi_rwlock *);
00142 
00143 extern int lock_GetMutexState(struct osi_mutex *);
00144 
00145 /* and init stuff */
00146 
00147 extern void osi_BaseInit(void);
00148 
00149 extern void osi_SetLockOrderValidation(int);
00150 
00151 /* and friendly macros */
00152 
00153 #define lock_AssertNone(x) osi_assertx(lock_GetRWLockState(x) == 0, "(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
00154 
00155 #define lock_AssertRead(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_READHELD, "!OSI_RWLOCK_READHELD")
00156 
00157 #define lock_AssertWrite(x) osi_assertx((lock_GetRWLockState(x) & OSI_RWLOCK_WRITEHELD) && ((x)->tid[0] == thrd_Current()), "!OSI_RWLOCK_WRITEHELD")
00158 
00159 #define lock_AssertAny(x) osi_assertx(lock_GetRWLockState(x) != 0, "!(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
00160 
00161 #define lock_AssertMutex(x) osi_assertx((lock_GetMutexState(x) & OSI_MUTEX_HELD) && ((x)->tid == thrd_Current()), "!OSI_MUTEX_HELD")
00162 
00163 #endif /* OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H */
 All Data Structures Files Functions Variables