Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / client_osi / osibasel.h
blob9ef6b90519240226a45fe556fc2e89d5a1ae9d02
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
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 */
36 unsigned short pad;
37 union {
38 void *privateDatap; /* data pointer for non-zero types */
39 osi_turnstile_t turn; /* turnstile */
40 } d;
41 unsigned short level; /* locking hierarchy level */
42 } osi_mutex_t;
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 */
66 union {
67 void *privateDatap; /* data pointer for non-zero types */
68 osi_turnstile_t turn; /* turnstile */
69 } d;
70 unsigned short level; /* locking hierarchy level */
71 } osi_rwlock_t;
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 {
80 osi_queue_t q;
81 char type;
82 union {
83 osi_rwlock_t *rw;
84 osi_mutex_t *mx;
86 } osi_lock_ref_t;
88 #define OSI_LOCK_MUTEX 1
89 #define OSI_LOCK_RW 2
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 *);
143 /* and init stuff */
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 */