OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/WINNT/client_osi/osisleep.h
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 */
 All Data Structures Files Functions Variables