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 OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H
13 #define OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H 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.
57 #define OSI_RWLOCK_THREADS 32
59 typedef struct osi_rwlock
{
60 char type
; /* for all types; type 0 uses atomic count */
61 char flags
; /* flags for base type */
62 unsigned short atomicIndex
; /* index into hash table for low-level sync */
63 DWORD tid
[OSI_RWLOCK_THREADS
]; /* writer's tid */
64 unsigned short waiters
; /* waiters */
65 unsigned short readers
; /* readers */
67 void *privateDatap
; /* data pointer for non-zero types */
68 osi_turnstile_t turn
; /* turnstile */
70 unsigned short level
; /* locking hierarchy level */
75 * a lock reference is a queue object that maintains a reference to a
76 * mutex or read/write lock object. Its intended purpose is for
77 * maintaining lists of lock objects on a per thread basis.
79 typedef struct osi_lock_ref
{
88 #define OSI_LOCK_MUTEX 1
91 extern void lock_ObtainRead (struct osi_rwlock
*);
93 extern void lock_ObtainWrite (struct osi_rwlock
*);
95 extern void lock_ReleaseRead (struct osi_rwlock
*);
97 extern void lock_ReleaseWrite (struct osi_rwlock
*);
99 extern void lock_ObtainMutex (struct osi_mutex
*);
101 extern void lock_ReleaseMutex (struct osi_mutex
*);
103 extern int lock_TryRead (struct osi_rwlock
*);
105 extern int lock_TryWrite (struct osi_rwlock
*);
107 extern int lock_TryMutex (struct osi_mutex
*);
109 extern void osi_SleepR (LONG_PTR
, struct osi_rwlock
*);
111 extern void osi_SleepW (LONG_PTR
, struct osi_rwlock
*);
113 extern void osi_SleepM (LONG_PTR
, struct osi_mutex
*);
115 extern void osi_Sleep (LONG_PTR
);
117 extern void osi_Wakeup (LONG_PTR
);
119 extern void lock_FinalizeRWLock(struct osi_rwlock
*);
121 extern void lock_FinalizeMutex(struct osi_mutex
*);
123 extern CRITICAL_SECTION osi_baseAtomicCS
[];
125 /* and define the functions that create basic locks and mutexes */
127 extern void lock_InitializeRWLock(struct osi_rwlock
*, char *, unsigned short level
);
129 extern void lock_InitializeMutex(struct osi_mutex
*, char *, unsigned short level
);
131 extern void osi_Init (void);
133 extern void lock_ConvertWToR(struct osi_rwlock
*);
135 extern void lock_ConvertRToW(struct osi_rwlock
*);
137 /* and stat functions */
139 extern int lock_GetRWLockState(struct osi_rwlock
*);
141 extern int lock_GetMutexState(struct osi_mutex
*);
145 extern void osi_BaseInit(void);
147 extern void osi_SetLockOrderValidation(int);
149 /* and friendly macros */
151 #define lock_AssertNone(x) osi_assertx(lock_GetRWLockState(x) == 0, "(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
153 #define lock_AssertRead(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_READHELD, "!OSI_RWLOCK_READHELD")
155 #define lock_AssertWrite(x) osi_assertx((lock_GetRWLockState(x) & OSI_RWLOCK_WRITEHELD) && ((x)->tid[0] == thrd_Current()), "!OSI_RWLOCK_WRITEHELD")
157 #define lock_AssertAny(x) osi_assertx(lock_GetRWLockState(x) != 0, "!(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
159 #define lock_AssertMutex(x) osi_assertx((lock_GetMutexState(x) & OSI_MUTEX_HELD) && ((x)->tid == thrd_Current()), "!OSI_MUTEX_HELD")
161 #endif /* OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H */