2 * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
4 * (C) COPYRIGHT IBM CORPORATION 1987, 1988
5 * LICENSED MATERIALS - PROPERTY OF IBM
9 /* Copyright (C) 1994 Cazamar Systems, Inc. */
11 #ifndef _OSISLEEP_H_ENV_
12 #define _OSISLEEP_H_ENV_ 1
18 #include "osithrd95.h"
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 */
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 {
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 */
40 /* first guy is the most recently added process */
41 typedef struct osi_turnstile {
42 osi_sleepInfo_t *firstp;
43 osi_sleepInfo_t *lastp;
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 */
52 /* struct for single-shot initialization support */
53 typedef struct osi_once {
55 long atomic; /* used for atomicity */
57 osi_mutex_t atomic; /* used for atomicity */
59 int done; /* tells if initialization is done */
62 /* size of mutex hash table; should be a prime number; used for mutex and lock hashing */
63 #define OSI_MUTEXHASHSIZE 251 /* prime number */
65 #define osi_MUTEXHASH(x) ((unsigned short) (((unsigned long) x) % (unsigned) OSI_MUTEXHASHSIZE))
67 /* size of sleep value hash table. Must be power of 2 */
68 #define OSI_SLEEPHASHSIZE 128
71 #define osi_SLEEPHASH(x) (((x)>>2)&(OSI_SLEEPHASHSIZE-1))
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
77 extern Crit_Sec osi_sleepCookieCS;
79 /* spin lock version of atomic sleep, used internally only */
80 extern void osi_SleepSpin(long value, Crit_Sec *counterp);
82 /* spin lock version of wakeup, used internally only */
83 extern void osi_WakeupSpin(long value);
85 /* exported function to sleep on a value */
86 extern void osi_Sleep (long);
88 extern void osi_FreeSleepInfo(osi_sleepInfo_t *);
90 /* function to atomically initialize and return a "once only"
91 * structure. Returns true if you're the first caller, otherwise
94 extern int osi_Once(osi_once_t *);
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.
103 extern int osi_TestOnce(osi_once_t *);
105 /* called once for each call to osi_Once that returns true; permits other
106 * calls to osi_Once to proceed (and return false).
108 extern void osi_EndOnce(osi_once_t *);
112 /* exported function to wakeup those sleeping on a value */
113 extern void osi_Wakeup (long);
115 extern void osi_Init (void);
118 /* create a ptr to a cookie */
119 osi_sleepFD_t *osi_CreateSleepCookie(void);
121 /* release a ptr to a sleep cookie */
122 void osi_FreeSleepCookie(osi_sleepFD_t *);
124 /* advance a sleep cookie to the next ptr */
125 int osi_NextSleepCookie(osi_sleepFD_t *);
127 /* functions for the sleep FD implementation */
128 extern long osi_SleepFDCreate(osi_fdType_t *, osi_fd_t **);
130 extern long osi_SleepFDGetInfo(osi_fd_t *, osi_remGetInfoParms_t *);
132 extern long osi_SleepFDClose(osi_fd_t *);
134 /* functions for getting hash sizes */
135 extern int osi_IsPrime(unsigned long);
136 extern unsigned long osi_PrimeLessThan(unsigned long);
139 unsigned long osi_GetBootTime(void);
141 #define osi_assert(x) \
143 if (!(x)) osi_panic(NULL, __FILE__, __LINE__); \
146 #define osi_assertx(x,s) \
148 if (!(x)) osi_panic((s), __FILE__, __LINE__); \
152 void osi_InitPanic(void *anotifFunc);
153 void osi_panic(char *, char *, long);
155 unsigned long osi_Time(void);
157 extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp,
160 extern void osi_TSignal(osi_turnstile_t *turnp);
162 extern void osi_TBroadcast(osi_turnstile_t *turnp);
164 extern void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, Crit_Sec *csp);
166 #define osi_TInit(t) ((t)->firstp = (t)->lastp = 0)
168 #define osi_TEmpty(t) ((t)->firstp == NULL)
170 #endif /*_OSISLEEP_H_ENV_ */