aaf0c8f96bf5e01e1c5648ad1d2a255530acb5e3
[openafs.git] / src / WINNT / client_osi / osisleep.h
1 /* 
2  * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
3  *
4  * (C) COPYRIGHT IBM CORPORATION 1987, 1988
5  * LICENSED MATERIALS - PROPERTY OF IBM
6  *
7  */
8
9 /* Copyright (C) 1994 Cazamar Systems, Inc. */
10
11 #ifndef _OSISLEEP_H_ENV_
12 #define _OSISLEEP_H_ENV_ 1
13
14 /*#include "osi.h"*/
15 #include "osifd.h"
16 #include "osiqueue.h"
17 #ifdef DJGPP
18 #include "osithrd95.h"
19 #endif /* DJGPP */
20
21 /* states bits */
22 #define OSI_SLEEPINFO_SIGNALLED 1       /* this sleep structure has been signalled */
23 #define OSI_SLEEPINFO_INHASH    2       /* this guy is in the hash table */
24 #define OSI_SLEEPINFO_DELETED   4       /* remove this guy when refcount hits 0 */
25
26 /* waitinfo bits */
27 #define OSI_SLEEPINFO_W4READ    1       /* waiting for a read lock */
28 #define OSI_SLEEPINFO_W4WRITE   2       /* waiting for a write lock */
29 typedef struct osi_sleepInfo {
30         osi_queue_t q;
31         long value;             /* sleep value when in a sleep queue, patch addr for turnstiles */
32         unsigned long tid;      /* thread ID of sleeper */
33         EVENT_HANDLE sema;              /* semaphore for this entry */
34         unsigned short states;  /* states bits */
35         unsigned short idx;     /* sleep hash table we're in, if in hash */
36         unsigned short waitFor; /* what are we waiting for; used for bulk wakeups */
37         unsigned short refCount;/* reference count from FDs */
38 } osi_sleepInfo_t;
39
40 /* first guy is the most recently added process */
41 typedef struct osi_turnstile {
42         osi_sleepInfo_t *firstp;
43         osi_sleepInfo_t *lastp;
44 } osi_turnstile_t;
45
46 typedef struct osi_sleepFD{
47         osi_fd_t fd;            /* FD header */
48         osi_sleepInfo_t *sip;   /* ptr to the dude */
49         int idx;                /* hash index */
50 } osi_sleepFD_t;
51
52 /* struct for single-shot initialization support */
53 typedef struct osi_once {
54 #ifndef DJGPP
55         long atomic;    /* used for atomicity */
56 #else
57         osi_mutex_t atomic;     /* used for atomicity */
58 #endif /* !DJGPP */
59         int done;       /* tells if initialization is done */
60 } osi_once_t;
61
62 /* size of mutex hash table; should be a prime number; used for mutex and lock hashing */
63 #define OSI_MUTEXHASHSIZE       251     /* prime number */
64
65 #define osi_MUTEXHASH(x) ((unsigned short) (((unsigned long) x) % (unsigned) OSI_MUTEXHASHSIZE))
66
67 /* size of sleep value hash table.  Must be power of 2 */
68 #define OSI_SLEEPHASHSIZE       128
69
70 /* hash function */
71 #define osi_SLEEPHASH(x)        (((x)>>2)&(OSI_SLEEPHASHSIZE-1))
72
73 /* export this so that RPC function can call osi_NextSleepCookie while
74  * holding this lock, so that locks don't get released while we're copying
75  * out this info.
76  */
77 extern Crit_Sec osi_sleepCookieCS;
78
79 /* spin lock version of atomic sleep, used internally only */
80 extern void osi_SleepSpin(long value, Crit_Sec *counterp);
81
82 /* spin lock version of wakeup, used internally only */
83 extern void osi_WakeupSpin(long value);
84
85 /* exported function to sleep on a value */
86 extern void osi_Sleep (long);
87
88 extern void osi_FreeSleepInfo(osi_sleepInfo_t *);
89
90 /* function to atomically initialize and return a "once only"
91  * structure.  Returns true if you're the first caller, otherwise
92  * returns 0.
93  */
94 extern int osi_Once(osi_once_t *);
95
96 /* function like the above, but doesn't set the once-only flag.
97  * Can be used as optimization to tell if osi_Once has been
98  * called.  If it returns true, by the time you really call
99  * osi_Once, someone else may have called it, but if it
100  * return false, you're guaranteed it will stay false, and that
101  * osi_Once would return false, too.
102  */
103 extern int osi_TestOnce(osi_once_t *);
104
105 /* called once for each call to osi_Once that returns true; permits other
106  * calls to osi_Once to proceed (and return false).
107  */
108 extern void osi_EndOnce(osi_once_t *);
109
110
111 #ifndef DJGPP
112 /* exported function to wakeup those sleeping on a value */
113 extern void osi_Wakeup (long);
114
115 extern void osi_Init (void);
116 #endif /* !DJGPP */
117
118 /* create a ptr to a cookie */
119 osi_sleepFD_t *osi_CreateSleepCookie(void);
120
121 /* release a ptr to a sleep cookie */
122 void osi_FreeSleepCookie(osi_sleepFD_t *);
123
124 /* advance a sleep cookie to the next ptr */
125 int osi_NextSleepCookie(osi_sleepFD_t *);
126
127 /* functions for the sleep FD implementation */
128 extern long osi_SleepFDCreate(osi_fdType_t *, osi_fd_t **);
129 #ifndef DJGPP
130 extern long osi_SleepFDGetInfo(osi_fd_t *, osi_remGetInfoParms_t *);
131 #endif
132 extern long osi_SleepFDClose(osi_fd_t *);
133
134 /* functions for getting hash sizes */
135 extern int osi_IsPrime(unsigned long);
136 extern unsigned long osi_PrimeLessThan(unsigned long);
137
138 /* time functions */
139 unsigned long osi_GetBootTime(void);
140
141 #define osi_assert(x)   \
142     do { \
143         if (!(x)) osi_panic(NULL, __FILE__, __LINE__); \
144     } while(0)
145
146 #define osi_assertx(x,s)        \
147     do { \
148         if (!(x)) osi_panic((s), __FILE__, __LINE__); \
149     } while(0)
150
151 /* panic */
152 void osi_InitPanic(void *anotifFunc);
153 void osi_panic(char *, char *, long);
154
155 unsigned long osi_Time(void);
156
157 extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp,
158         Crit_Sec *releasep);
159
160 extern void osi_TSignal(osi_turnstile_t *turnp);
161
162 extern void osi_TBroadcast(osi_turnstile_t *turnp);
163
164 extern void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, Crit_Sec *csp);
165
166 #define osi_TInit(t)    ((t)->firstp = (t)->lastp = 0)
167
168 #define osi_TEmpty(t)   ((t)->firstp == NULL)
169
170 #endif /*_OSISLEEP_H_ENV_ */