/* * 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 _OSISLEEP_H_ENV_ #define _OSISLEEP_H_ENV_ 1 /*#include "osi.h"*/ #include "osifd.h" #include "osiqueue.h" #ifdef DJGPP #include "osithrd95.h" #endif /* DJGPP */ /* 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 value; /* sleep value when in a sleep queue, patch addr for turnstiles */ unsigned long tid; /* thread ID of sleeper */ EVENT_HANDLE sema; /* semaphore for this entry */ unsigned short states; /* states bits */ unsigned short idx; /* sleep hash table we're in, if in hash */ unsigned short waitFor; /* what are we waiting for; used for bulk wakeups */ unsigned short 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 { #ifndef DJGPP long atomic; /* used for atomicity */ #else osi_mutex_t atomic; /* used for atomicity */ #endif /* !DJGPP */ 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) (((unsigned long) x) % (unsigned) OSI_MUTEXHASHSIZE)) /* size of sleep value hash table. Must be power of 2 */ #define OSI_SLEEPHASHSIZE 128 /* 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 value, Crit_Sec *counterp); /* spin lock version of wakeup, used internally only */ extern void osi_WakeupSpin(long value); #ifndef DJGPP /* exported function to sleep on a value */ extern void osi_Sleep (long); #endif 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 *); #ifndef DJGPP /* exported function to wakeup those sleeping on a value */ extern void osi_Wakeup (long); extern void osi_Init (void); #endif /* !DJGPP */ /* 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 **); #ifndef DJGPP extern long osi_SleepFDGetInfo(osi_fd_t *, osi_remGetInfoParms_t *); #endif 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); unsigned long osi_Time(void); extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, Crit_Sec *releasep); 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 /*_OSISLEEP_H_ENV_ */