OpenAFS
OpenAFS distributed network file system
|
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 */