/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* Copyright (C) 1994 Cazamar Systems, Inc. */ #ifndef OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H #define OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H 1 /*#include "osi.h"*/ #include "osifd.h" #include "osiqueue.h" /* states bits */ #define OSI_SLEEPINFO_SIGNALLED 1 /* this sleep structure has been signalled */ #define OSI_SLEEPINFO_INHASH 2 /* this guy is in the hash table */ #define OSI_SLEEPINFO_DELETED 4 /* remove this guy when refcount hits 0 */ /* waitinfo bits */ #define OSI_SLEEPINFO_W4READ 1 /* waiting for a read lock */ #define OSI_SLEEPINFO_W4WRITE 2 /* waiting for a write lock */ typedef struct osi_sleepInfo { osi_queue_t q; LONG_PTR value; /* sleep value when in a sleep queue, patch addr for turnstiles */ DWORD *tidp; /* tid history */ DWORD tid; /* thread ID of sleeper */ EVENT_HANDLE sema; /* semaphore for this entry */ long states; /* states bits */ long idx; /* sleep hash table we're in, if in hash */ unsigned long waitFor; /* what are we waiting for; used for bulk wakeups */ unsigned long refCount; /* reference count from FDs */ } osi_sleepInfo_t; /* first guy is the most recently added process */ typedef struct osi_turnstile { osi_sleepInfo_t *firstp; osi_sleepInfo_t *lastp; } osi_turnstile_t; typedef struct osi_sleepFD{ osi_fd_t fd; /* FD header */ osi_sleepInfo_t *sip; /* ptr to the dude */ int idx; /* hash index */ } osi_sleepFD_t; /* struct for single-shot initialization support */ typedef struct osi_once { long atomic; /* used for atomicity */ int done; /* tells if initialization is done */ } osi_once_t; /* size of mutex hash table; should be a prime number; used for mutex and lock hashing */ #define OSI_MUTEXHASHSIZE 251 /* prime number */ #define osi_MUTEXHASH(x) ((unsigned short) (((LONG_PTR) x) % (intptr_t) OSI_MUTEXHASHSIZE)) /* size of sleep value hash table. Must be power of 2 */ #define OSI_SLEEPHASHSIZE 256 /* hash function */ #define osi_SLEEPHASH(x) (((x)>>2)&(OSI_SLEEPHASHSIZE-1)) /* export this so that RPC function can call osi_NextSleepCookie while * holding this lock, so that locks don't get released while we're copying * out this info. */ extern Crit_Sec osi_sleepCookieCS; /* spin lock version of atomic sleep, used internally only */ extern void osi_SleepSpin(LONG_PTR value, Crit_Sec *counterp); /* spin lock version of wakeup, used internally only */ extern void osi_WakeupSpin(LONG_PTR value); /* exported function to sleep on a value */ extern void osi_Sleep (LONG_PTR); extern void osi_FreeSleepInfo(osi_sleepInfo_t *); /* function to atomically initialize and return a "once only" * structure. Returns true if you're the first caller, otherwise * returns 0. */ extern int osi_Once(osi_once_t *); /* function like the above, but doesn't set the once-only flag. * Can be used as optimization to tell if osi_Once has been * called. If it returns true, by the time you really call * osi_Once, someone else may have called it, but if it * return false, you're guaranteed it will stay false, and that * osi_Once would return false, too. */ extern int osi_TestOnce(osi_once_t *); /* called once for each call to osi_Once that returns true; permits other * calls to osi_Once to proceed (and return false). */ extern void osi_EndOnce(osi_once_t *); /* exported function to wakeup those sleeping on a value */ extern void osi_Wakeup (LONG_PTR); extern void osi_Init (void); /* create a ptr to a cookie */ osi_sleepFD_t *osi_CreateSleepCookie(void); /* release a ptr to a sleep cookie */ void osi_FreeSleepCookie(osi_sleepFD_t *); /* advance a sleep cookie to the next ptr */ int osi_NextSleepCookie(osi_sleepFD_t *); /* functions for the sleep FD implementation */ extern long osi_SleepFDCreate(osi_fdType_t *, osi_fd_t **); extern long osi_SleepFDGetInfo(osi_fd_t *, osi_remGetInfoParms_t *); extern long osi_SleepFDClose(osi_fd_t *); /* functions for getting hash sizes */ extern int osi_IsPrime(unsigned long); extern unsigned long osi_PrimeLessThan(unsigned long); /* time functions */ unsigned long osi_GetBootTime(void); #define osi_assert(x) \ do { \ if (!(x)) osi_panic(NULL, __FILE__, __LINE__); \ } while(0) #define osi_assertx(x,s) \ do { \ if (!(x)) osi_panic((s), __FILE__, __LINE__); \ } while(0) /* panic */ void osi_InitPanic(void *anotifFunc); void osi_panic(char *, char *, long); time_t osi_Time(void); extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, Crit_Sec *releasep); extern void osi_TWaitExt(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, Crit_Sec *releasep, int prepend); extern void osi_TSignal(osi_turnstile_t *turnp); extern void osi_TBroadcast(osi_turnstile_t *turnp); extern void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, Crit_Sec *csp); #define osi_TInit(t) ((t)->firstp = (t)->lastp = 0) #define osi_TEmpty(t) ((t)->firstp == NULL) #endif /* OPENAFS_WINNT_CLIENT_OSI_OSISLEEP_H */