winthread.c File Reference

#include "thread.h"
#include <io.h>

Data Structures

struct  WinThread
struct  ThreadArg
struct  Lock
struct  Cond
struct  Search

Defines

#define SPINLOCK(lPtr)   while(InterlockedExchange((lPtr), 1)) Sleep(0)
#define SPINUNLOCK(lPtr)   InterlockedExchange((lPtr), 0)
#define GETWINTHREAD()   TlsGetValue(tlskey)

Functions

BOOL APIENTRY DllMain (HANDLE hModule, DWORD why, LPVOID lpReserved)
void NsInitThreads (void)
int NsGetStack (void **addrPtr, size_t *sizePtr)
void ** NsGetTls (void)
char * NsThreadLibName (void)
void * NsLockAlloc (void)
void NsLockFree (void *lock)
void NsLockSet (void *lock)
int NsLockTry (Lock *lock)
void NsLockUnset (void *lock)
void Ns_CondInit (Ns_Cond *cond)
void Ns_CondDestroy (Ns_Cond *cond)
void Ns_CondSignal (Ns_Cond *cond)
void Ns_CondBroadcast (Ns_Cond *cond)
void Ns_CondWait (Ns_Cond *cond, Ns_Mutex *mutex)
int Ns_CondTimedWait (Ns_Cond *cond, Ns_Mutex *mutex, Ns_Time *timePtr)
void NsCreateThread (void *arg, long stacksize, Ns_Thread *resultPtr)
void Ns_ThreadExit (void *arg)
void Ns_ThreadJoin (Ns_Thread *thread, void **argPtr)
void Ns_ThreadYield (void)
int Ns_ThreadId (void)
void Ns_ThreadSelf (Ns_Thread *threadPtr)
DIR * opendir (char *pathname)
int closedir (DIR *dp)
dirent * readdir (DIR *dp)

Define Documentation

 
#define GETWINTHREAD (  )     TlsGetValue(tlskey)

#define SPINLOCK ( lPtr   )     while(InterlockedExchange((lPtr), 1)) Sleep(0)

#define SPINUNLOCK ( lPtr   )     InterlockedExchange((lPtr), 0)


Function Documentation

int closedir ( DIR *  dp  ) 

----------------------------------------------------------------------

closedir --

Closes and active directory search.

Results: 0.

Side effects: None.

----------------------------------------------------------------------

BOOL APIENTRY DllMain ( HANDLE  hModule,
DWORD  why,
LPVOID  lpReserved 
)

----------------------------------------------------------------------

DllMain --

Thread library DLL main, managing each thread's WinThread structure and the master critical section lock.

Results: TRUE.

Side effects: On error will abort process.

----------------------------------------------------------------------

FALLTHROUGH

Note this code does not execute for the final thread on exit because the TLS callbacks may invoke code from an unloaded DLL, e.g., Tcl.

void Ns_CondBroadcast ( Ns_Cond *  cond  ) 

----------------------------------------------------------------------

Ns_CondBroadcast --

Broadcast a condition, resuming all waiting threads, if any.

Results: None.

Side effects: First thread, if any, is awoken.

----------------------------------------------------------------------

Set each thread to wake up the next thread on the waiting list. This results in a rolling wakeup which should reduce lock contention as the threads are awoken.

Wake up the first thread to start the rolling wakeup.

NB: See Wakeup() comment in Ns_CondSignal().

void Ns_CondDestroy ( Ns_Cond *  cond  ) 

----------------------------------------------------------------------

Ns_CondDestroy --

Destroy a previously initialized condition variable. Note this function is almost never called as condition variables normally exist until the process exits.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void Ns_CondInit ( Ns_Cond *  cond  ) 

----------------------------------------------------------------------

Ns_CondInit --

Initialize a condition variable. Note that this function is rarely called directly as condition variables are now self initialized when first accessed.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void Ns_CondSignal ( Ns_Cond *  cond  ) 

----------------------------------------------------------------------

Ns_CondSignal --

Signal a condition variable, releasing a single thread if one is waiting.

Results: None.

Side effects: A single waiting thread may be resumed.

----------------------------------------------------------------------

NB: Unlike with NsLockUnset, the Wakeup() must be done before the spin unlock as the other thread may have been in a timed wait which just timed out.

int Ns_CondTimedWait ( Ns_Cond *  cond,
Ns_Mutex *  mutex,
Ns_Time *  timePtr 
)

----------------------------------------------------------------------

Ns_CondTimedWait --

Wait for a condition to be signaled up to a given absolute time out. This code is very tricky to avoid the race condition between locking and unlocking the coordinating mutex and catching a wakeup signal. Be sure you understand how condition variables work before screwing around with this code.

Results: NS_OK on signal being received within the timeout period, otherwise NS_TIMEOUT.

Side effects: None.

----------------------------------------------------------------------

Convert to relative wait time and verify.

Lock the condition and add this thread to the end of the wait list.

Release the outer mutex and wait for the signal to arrive or timeout.

Lock the condition and check if wakeup was signalled. Note that the signal may have arrived as the event was timing out so the return of WaitForSingleObject can't be relied on. If there was no wakeup, remove this thread from the list.

Wakeup the next thread in a rolling broadcast if necessary. Note, as with Ns_CondSignal, the wakeup must be sent while the spin lock is held.

Re-aquire the outer lock and return.

void Ns_CondWait ( Ns_Cond *  cond,
Ns_Mutex *  mutex 
)

----------------------------------------------------------------------

Ns_CondWait --

Wait indefinitely for a condition to be signaled.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void Ns_ThreadExit ( void *  arg  ) 

----------------------------------------------------------------------

Ns_ThreadExit --

Terminate a thread. Note the use of _endthreadex instead of ExitThread which, as mentioned above, is correct.

Results: None.

Side effects: Thread will clean itself up via the DllMain thread detach code.

----------------------------------------------------------------------

int Ns_ThreadId ( void   ) 

----------------------------------------------------------------------

Ns_ThreadId --

Return the numeric thread id.

Results: Integer thread id.

Side effects: None.

----------------------------------------------------------------------

void Ns_ThreadJoin ( Ns_Thread *  thread,
void **  argPtr 
)

----------------------------------------------------------------------

Ns_ThreadJoin --

Wait for exit of a non-detached thread.

Results: None.

Side effects: Requested thread is destroyed after join.

----------------------------------------------------------------------

void Ns_ThreadSelf ( Ns_Thread *  threadPtr  ) 

----------------------------------------------------------------------

Ns_ThreadSelf --

Return thread handle suitable for Ns_ThreadJoin.

Results: None.

Side effects: Value at threadPtr is updated with thread's handle.

----------------------------------------------------------------------

void Ns_ThreadYield ( void   ) 

----------------------------------------------------------------------

Ns_ThreadYield --

Yield the cpu to another thread.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void NsCreateThread ( void *  arg,
long  stacksize,
Ns_Thread *  resultPtr 
)

----------------------------------------------------------------------

NsCreateThread --

WinThread specific thread create function called by Ns_ThreadCreate. Note the use of _beginthreadex. CreateThread does not initialize the C runtime library fully and could lead to memory leaks on thread exit.

Results: None.

Side effects: Depends on thread startup routine.

----------------------------------------------------------------------

Round the stacksize to a pagesize and include the guardzone.

System scope always preferred, ignore any unsupported error.

int NsGetStack ( void **  addrPtr,
size_t *  sizePtr 
)

----------------------------------------------------------------------

NsGetStack --

Return stack info.

Results: Unsupport, always returns 0.

Side effects: None.

----------------------------------------------------------------------

void** NsGetTls ( void   ) 

----------------------------------------------------------------------

NsGetTls --

Return the TLS slots for this thread.

Results: Pointer to slots array.

Side effects: None.

----------------------------------------------------------------------

void NsInitThreads ( void   ) 

----------------------------------------------------------------------

NsInitThreads --

Core threads init.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void* NsLockAlloc ( void   ) 

----------------------------------------------------------------------

NsLockAlloc --

Allocate and initialize a mutex lock.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void NsLockFree ( void *  lock  ) 

----------------------------------------------------------------------

NsLockFree --

Free a mutex lock.

Results: None.

Side effects: None.

----------------------------------------------------------------------

void NsLockSet ( void *  lock  ) 

----------------------------------------------------------------------

NsLockSet --

Set a mutex lock.

Results: None.

Side effects: May wait wakeup event if lock already held.

----------------------------------------------------------------------

int NsLockTry ( Lock lock  ) 

----------------------------------------------------------------------

NsLockTry --

Try to set a mutex lock once.

Results: 1 if lock set, 0 otherwise.

Side effects: None.

----------------------------------------------------------------------

void NsLockUnset ( void *  lock  ) 

----------------------------------------------------------------------

NsLockUnset --

Unset a mutex lock.

Results: None.

Side effects: May signal wakeup event for a waiting thread.

----------------------------------------------------------------------

NB: It's safe to send the Wakeup() signal after spin unlock because the waiting thread is in an infiniate wait.

char* NsThreadLibName ( void   ) 

----------------------------------------------------------------------

NsThreadLibName --

Return the string name of the thread library.

Results: Pointer to static string.

Side effects: None.

----------------------------------------------------------------------

DIR* opendir ( char *  pathname  ) 

----------------------------------------------------------------------

opendir --

Start a directory search.

Results: Pointer to DIR.

Side effects: None.

----------------------------------------------------------------------

struct dirent* readdir ( DIR *  dp  ) 

----------------------------------------------------------------------

readdir --

Returns the next file in an active directory search.

Results: Pointer to thread-local struct dirent.

Side effects: None.

----------------------------------------------------------------------


Generated on Tue Sep 4 19:58:57 2007 by  doxygen 1.5.1