OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 /* Copyright (C) 1994 Cazamar Systems, Inc. */ 00011 00012 #ifndef OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H 00013 #define OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H 1 00014 00015 /*#include "osi.h"*/ 00016 #include "osifd.h" 00017 #include "osiqueue.h" 00018 00019 /* states bits */ 00020 #define OSI_SLEEPINFO_SIGNALLED 1 /* this sleep structure has been signalled */ 00021 #define OSI_SLEEPINFO_INHASH 2 /* this guy is in the hash table */ 00022 #define OSI_SLEEPINFO_DELETED 4 /* remove this guy when refcount hits 0 */ 00023 00024 /* waitinfo bits */ 00025 #define OSI_SLEEPINFO_W4READ 1 /* waiting for a read lock */ 00026 #define OSI_SLEEPINFO_W4WRITE 2 /* waiting for a write lock */ 00027 typedef struct osi_sleepInfo { 00028 osi_queue_t q; 00029 LONG_PTR value; /* sleep value when in a sleep queue, patch addr for turnstiles */ 00030 DWORD *tidp; /* tid history */ 00031 DWORD tid; /* thread ID of sleeper */ 00032 EVENT_HANDLE sema; /* semaphore for this entry */ 00033 unsigned short states; /* states bits */ 00034 unsigned short idx; /* sleep hash table we're in, if in hash */ 00035 unsigned short waitFor; /* what are we waiting for; used for bulk wakeups */ 00036 unsigned long refCount; /* reference count from FDs */ 00037 } osi_sleepInfo_t; 00038 00039 /* first guy is the most recently added process */ 00040 typedef struct osi_turnstile { 00041 osi_sleepInfo_t *firstp; 00042 osi_sleepInfo_t *lastp; 00043 } osi_turnstile_t; 00044 00045 typedef struct osi_sleepFD{ 00046 osi_fd_t fd; /* FD header */ 00047 osi_sleepInfo_t *sip; /* ptr to the dude */ 00048 int idx; /* hash index */ 00049 } osi_sleepFD_t; 00050 00051 /* struct for single-shot initialization support */ 00052 typedef struct osi_once { 00053 long atomic; /* used for atomicity */ 00054 int done; /* tells if initialization is done */ 00055 } osi_once_t; 00056 00057 /* size of mutex hash table; should be a prime number; used for mutex and lock hashing */ 00058 #define OSI_MUTEXHASHSIZE 251 /* prime number */ 00059 00060 #define osi_MUTEXHASH(x) ((unsigned short) (((LONG_PTR) x) % (intptr_t) OSI_MUTEXHASHSIZE)) 00061 00062 /* size of sleep value hash table. Must be power of 2 */ 00063 #define OSI_SLEEPHASHSIZE 128 00064 00065 /* hash function */ 00066 #define osi_SLEEPHASH(x) (((x)>>2)&(OSI_SLEEPHASHSIZE-1)) 00067 00068 /* export this so that RPC function can call osi_NextSleepCookie while 00069 * holding this lock, so that locks don't get released while we're copying 00070 * out this info. 00071 */ 00072 extern Crit_Sec osi_sleepCookieCS; 00073 00074 /* spin lock version of atomic sleep, used internally only */ 00075 extern void osi_SleepSpin(LONG_PTR value, Crit_Sec *counterp); 00076 00077 /* spin lock version of wakeup, used internally only */ 00078 extern void osi_WakeupSpin(LONG_PTR value); 00079 00080 /* exported function to sleep on a value */ 00081 extern void osi_Sleep (LONG_PTR); 00082 00083 extern void osi_FreeSleepInfo(osi_sleepInfo_t *); 00084 00085 /* function to atomically initialize and return a "once only" 00086 * structure. Returns true if you're the first caller, otherwise 00087 * returns 0. 00088 */ 00089 extern int osi_Once(osi_once_t *); 00090 00091 /* function like the above, but doesn't set the once-only flag. 00092 * Can be used as optimization to tell if osi_Once has been 00093 * called. If it returns true, by the time you really call 00094 * osi_Once, someone else may have called it, but if it 00095 * return false, you're guaranteed it will stay false, and that 00096 * osi_Once would return false, too. 00097 */ 00098 extern int osi_TestOnce(osi_once_t *); 00099 00100 /* called once for each call to osi_Once that returns true; permits other 00101 * calls to osi_Once to proceed (and return false). 00102 */ 00103 extern void osi_EndOnce(osi_once_t *); 00104 00105 00106 /* exported function to wakeup those sleeping on a value */ 00107 extern void osi_Wakeup (LONG_PTR); 00108 00109 extern void osi_Init (void); 00110 00111 /* create a ptr to a cookie */ 00112 osi_sleepFD_t *osi_CreateSleepCookie(void); 00113 00114 /* release a ptr to a sleep cookie */ 00115 void osi_FreeSleepCookie(osi_sleepFD_t *); 00116 00117 /* advance a sleep cookie to the next ptr */ 00118 int osi_NextSleepCookie(osi_sleepFD_t *); 00119 00120 /* functions for the sleep FD implementation */ 00121 extern long osi_SleepFDCreate(osi_fdType_t *, osi_fd_t **); 00122 extern long osi_SleepFDGetInfo(osi_fd_t *, osi_remGetInfoParms_t *); 00123 extern long osi_SleepFDClose(osi_fd_t *); 00124 00125 /* functions for getting hash sizes */ 00126 extern int osi_IsPrime(unsigned long); 00127 extern unsigned long osi_PrimeLessThan(unsigned long); 00128 00129 /* time functions */ 00130 unsigned long osi_GetBootTime(void); 00131 00132 #define osi_assert(x) \ 00133 do { \ 00134 if (!(x)) osi_panic(NULL, __FILE__, __LINE__); \ 00135 } while(0) 00136 00137 #define osi_assertx(x,s) \ 00138 do { \ 00139 if (!(x)) osi_panic((s), __FILE__, __LINE__); \ 00140 } while(0) 00141 00142 /* panic */ 00143 void osi_InitPanic(void *anotifFunc); 00144 void osi_panic(char *, char *, long); 00145 00146 time_t osi_Time(void); 00147 00148 extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, 00149 void *patchp, DWORD *tidp, 00150 Crit_Sec *releasep); 00151 00152 extern void osi_TWaitExt(osi_turnstile_t *turnp, int waitFor, 00153 void *patchp, DWORD *tidp, 00154 Crit_Sec *releasep, int prepend); 00155 00156 extern void osi_TSignal(osi_turnstile_t *turnp); 00157 00158 extern void osi_TBroadcast(osi_turnstile_t *turnp); 00159 00160 extern void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, Crit_Sec *csp); 00161 00162 #define osi_TInit(t) ((t)->firstp = (t)->lastp = 0) 00163 00164 #define osi_TEmpty(t) ((t)->firstp == NULL) 00165 00166 #endif /* OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H */