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_OSISLEEP_H
13 #define OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H 1
20 #define OSI_SLEEPINFO_SIGNALLED 1 /* this sleep structure has been signalled */
21 #define OSI_SLEEPINFO_INHASH 2 /* this guy is in the hash table */
22 #define OSI_SLEEPINFO_DELETED 4 /* remove this guy when refcount hits 0 */
25 #define OSI_SLEEPINFO_W4READ 1 /* waiting for a read lock */
26 #define OSI_SLEEPINFO_W4WRITE 2 /* waiting for a write lock */
27 typedef struct osi_sleepInfo
{
29 LONG_PTR value
; /* sleep value when in a sleep queue, patch addr for turnstiles */
30 DWORD
*tidp
; /* tid history */
31 DWORD tid
; /* thread ID of sleeper */
32 EVENT_HANDLE sema
; /* semaphore for this entry */
33 long states
; /* states bits */
34 long idx
; /* sleep hash table we're in, if in hash */
35 unsigned long waitFor
; /* what are we waiting for; used for bulk wakeups */
36 unsigned long refCount
; /* reference count from FDs */
39 /* first guy is the most recently added process */
40 typedef struct osi_turnstile
{
41 osi_sleepInfo_t
*firstp
;
42 osi_sleepInfo_t
*lastp
;
45 typedef struct osi_sleepFD
{
46 osi_fd_t fd
; /* FD header */
47 osi_sleepInfo_t
*sip
; /* ptr to the dude */
48 int idx
; /* hash index */
51 /* struct for single-shot initialization support */
52 typedef struct osi_once
{
53 long atomic
; /* used for atomicity */
54 int done
; /* tells if initialization is done */
57 /* size of mutex hash table; should be a prime number; used for mutex and lock hashing */
58 #define OSI_MUTEXHASHSIZE 251 /* prime number */
60 #define osi_MUTEXHASH(x) ((unsigned short) (((LONG_PTR) x) % (intptr_t) OSI_MUTEXHASHSIZE))
62 /* size of sleep value hash table. Must be power of 2 */
63 #define OSI_SLEEPHASHSIZE 256
66 #define osi_SLEEPHASH(x) (((x)>>2)&(OSI_SLEEPHASHSIZE-1))
68 /* export this so that RPC function can call osi_NextSleepCookie while
69 * holding this lock, so that locks don't get released while we're copying
72 extern Crit_Sec osi_sleepCookieCS
;
74 /* spin lock version of atomic sleep, used internally only */
75 extern void osi_SleepSpin(LONG_PTR value
, Crit_Sec
*counterp
);
77 /* spin lock version of wakeup, used internally only */
78 extern void osi_WakeupSpin(LONG_PTR value
);
80 /* exported function to sleep on a value */
81 extern void osi_Sleep (LONG_PTR
);
83 extern void osi_FreeSleepInfo(osi_sleepInfo_t
*);
85 /* function to atomically initialize and return a "once only"
86 * structure. Returns true if you're the first caller, otherwise
89 extern int osi_Once(osi_once_t
*);
91 /* function like the above, but doesn't set the once-only flag.
92 * Can be used as optimization to tell if osi_Once has been
93 * called. If it returns true, by the time you really call
94 * osi_Once, someone else may have called it, but if it
95 * return false, you're guaranteed it will stay false, and that
96 * osi_Once would return false, too.
98 extern int osi_TestOnce(osi_once_t
*);
100 /* called once for each call to osi_Once that returns true; permits other
101 * calls to osi_Once to proceed (and return false).
103 extern void osi_EndOnce(osi_once_t
*);
106 /* exported function to wakeup those sleeping on a value */
107 extern void osi_Wakeup (LONG_PTR
);
109 extern void osi_Init (void);
111 /* create a ptr to a cookie */
112 osi_sleepFD_t
*osi_CreateSleepCookie(void);
114 /* release a ptr to a sleep cookie */
115 void osi_FreeSleepCookie(osi_sleepFD_t
*);
117 /* advance a sleep cookie to the next ptr */
118 int osi_NextSleepCookie(osi_sleepFD_t
*);
120 /* functions for the sleep FD implementation */
121 extern long osi_SleepFDCreate(osi_fdType_t
*, osi_fd_t
**);
122 extern long osi_SleepFDGetInfo(osi_fd_t
*, osi_remGetInfoParms_t
*);
123 extern long osi_SleepFDClose(osi_fd_t
*);
125 /* functions for getting hash sizes */
126 extern int osi_IsPrime(unsigned long);
127 extern unsigned long osi_PrimeLessThan(unsigned long);
130 unsigned long osi_GetBootTime(void);
132 #define osi_assert(x) \
134 if (!(x)) osi_panic(NULL, __FILE__, __LINE__); \
137 #define osi_assertx(x,s) \
139 if (!(x)) osi_panic((s), __FILE__, __LINE__); \
143 void osi_InitPanic(void *anotifFunc
);
144 void osi_panic(char *, char *, long);
146 time_t osi_Time(void);
148 extern void osi_TWait(osi_turnstile_t
*turnp
, int waitFor
,
149 void *patchp
, DWORD
*tidp
,
152 extern void osi_TWaitExt(osi_turnstile_t
*turnp
, int waitFor
,
153 void *patchp
, DWORD
*tidp
,
154 Crit_Sec
*releasep
, int prepend
);
156 extern void osi_TSignal(osi_turnstile_t
*turnp
);
158 extern void osi_TBroadcast(osi_turnstile_t
*turnp
);
160 extern void osi_TSignalForMLs(osi_turnstile_t
*turnp
, int stillHaveReaders
, Crit_Sec
*csp
);
162 #define osi_TInit(t) ((t)->firstp = (t)->lastp = 0)
164 #define osi_TEmpty(t) ((t)->firstp == NULL)
166 #endif /* OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H */