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
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
12 #ifndef _OSIBASEL_H_ENV_
13 #define _OSIBASEL_H_ENV_ 1
15 /* flags for osi_mutex_t and osi_rwlock_t flags fields. Some bits
16 * are used only in one structure or another.
18 #define OSI_LOCKFLAG_EXCL 1 /* exclusive locked (rwlock only) */
20 /* a mutex (pure exclusive lock). This structure has two forms. In the
21 * base type (type == 0), the d field is interpreted as an atomic counter,
22 * and all the other fields are used. In the other types, type specifies
23 * which operations to use (via the global osi_lockOps), and d.privateDatap
24 * points to the real data used by the mutex.
26 * For the base type, flags tells us if the lock is held, and if anyone else
27 * is waiting for the lock. The field d.atomicCount is used to implement a spin
28 * lock using an atomic increment operation.
30 typedef struct osi_mutex {
31 char type; /* for all types; type 0 uses atomic count */
32 char flags; /* flags for base type */
33 unsigned short atomicIndex; /* index of lock for low-level sync */
34 DWORD tid; /* tid of thread that owns the lock */
35 unsigned short waiters; /* waiters */
38 void *privateDatap; /* data pointer for non-zero types */
39 osi_turnstile_t turn; /* turnstile */
41 unsigned short level; /* locking hierarchy level */
44 /* a read/write lock. This structure has two forms. In the
45 * base type (type == 0), the d field is interpreted as an atomic counter,
46 * and all the other fields are used. In the other types, type specifies
47 * which operations to use (via the global osi_lockOps), and d.privateDatap
48 * points to the real data used by the mutex.
50 * For the base type, flags tells us if the lock is held, and if anyone else
51 * is waiting for the lock. The field d.atomicCount is used to implement a spin
52 * lock using an atomic increment operation.
54 * This type of lock has N readers or one writer.
56 typedef struct osi_rwlock {
57 char type; /* for all types; type 0 uses atomic count */
58 char flags; /* flags for base type */
59 unsigned short atomicIndex; /* index into hash table for low-level sync */
60 DWORD tid; /* writer's tid */
61 unsigned short waiters; /* waiters */
62 unsigned short readers; /* readers */
64 void *privateDatap; /* data pointer for non-zero types */
65 osi_turnstile_t turn; /* turnstile */
67 unsigned short level; /* locking hierarchy level */
72 * a lock reference is a queue object that maintains a reference to a
73 * mutex or read/write lock object. Its intended purpose is for
74 * maintaining lists of lock objects on a per thread basis.
76 typedef struct osi_lock_ref {
85 #define OSI_LOCK_MUTEX 1
88 extern void lock_ObtainRead (struct osi_rwlock *);
90 extern void lock_ObtainWrite (struct osi_rwlock *);
92 extern void lock_ReleaseRead (struct osi_rwlock *);
94 extern void lock_ReleaseWrite (struct osi_rwlock *);
96 extern void lock_ObtainMutex (struct osi_mutex *);
98 extern void lock_ReleaseMutex (struct osi_mutex *);
100 extern int lock_TryRead (struct osi_rwlock *);
102 extern int lock_TryWrite (struct osi_rwlock *);
104 extern int lock_TryMutex (struct osi_mutex *);
106 extern void osi_SleepR (LONG_PTR, struct osi_rwlock *);
108 extern void osi_SleepW (LONG_PTR, struct osi_rwlock *);
110 extern void osi_SleepM (LONG_PTR, struct osi_mutex *);
112 extern void osi_Sleep (LONG_PTR);
114 extern void osi_Wakeup (LONG_PTR);
116 extern void lock_FinalizeRWLock(struct osi_rwlock *);
118 extern void lock_FinalizeMutex(struct osi_mutex *);
120 extern CRITICAL_SECTION osi_baseAtomicCS[];
122 /* and define the functions that create basic locks and mutexes */
124 extern void lock_InitializeRWLock(struct osi_rwlock *, char *, unsigned short level);
126 extern void lock_InitializeMutex(struct osi_mutex *, char *, unsigned short level);
128 extern void osi_Init (void);
130 extern void lock_ConvertWToR(struct osi_rwlock *);
132 extern void lock_ConvertRToW(struct osi_rwlock *);
134 /* and stat functions */
136 extern int lock_GetRWLockState(struct osi_rwlock *);
138 extern int lock_GetMutexState(struct osi_mutex *);
142 extern void osi_BaseInit(void);
144 /* and friendly macros */
146 #define lock_AssertNone(x) osi_assertx(lock_GetRWLockState(x) == 0, "(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
148 #define lock_AssertRead(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_READHELD, "!OSI_RWLOCK_READHELD")
150 #define lock_AssertWrite(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_WRITEHELD, "!OSI_RWLOCK_WRITEHELD")
152 #define lock_AssertAny(x) osi_assertx(lock_GetRWLockState(x) != 0, "!(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
154 #define lock_AssertMutex(x) osi_assertx(lock_GetMutexState(x) & OSI_MUTEX_HELD, "!OSI_MUTEX_HELD")
156 #endif /*_OSIBASEL_H_ENV_ */