summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c420
1 files changed, 8 insertions, 412 deletions
diff --git a/misc.c b/misc.c
index b5fce04..4e3b286 100644
--- a/misc.c
+++ b/misc.c
@@ -38,416 +38,12 @@
#include "implement.h"
-int
-pthread_once (
- pthread_once_t * once_control,
- void (*init_routine) (void)
-)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * If any thread in a process with a once_control parameter
- * makes a call to pthread_once(), the first call will summon
- * the init_routine(), but subsequent calls will not. The
- * once_control parameter determines whether the associated
- * initialization routine has been called. The init_routine()
- * is complete upon return of pthread_once().
- * This function guarantees that one and only one thread
- * executes the initialization routine, init_routine when
- * access is controlled by the pthread_once_t control
- * key.
- *
- * PARAMETERS
- * once_control
- * pointer to an instance of pthread_once_t
- *
- * init_routine
- * pointer to an initialization routine
- *
- *
- * DESCRIPTION
- * See above.
- *
- * RESULTS
- * 0 success,
- * EINVAL once_control or init_routine is NULL
- *
- * ------------------------------------------------------
- */
-{
- int result;
+#include "pthread_once.c"
+#include "pthread_self.c"
+#include "pthread_equal.c"
+#include "pthread_setconcurrency.c"
+#include "pthread_getconcurrency.c"
+#include "w32_CancelableWait.c"
+#include "ptw32_new.c"
+#include "ptw32_calloc.c"
- if (once_control == NULL || init_routine == NULL)
- {
-
- result = EINVAL;
- goto FAIL0;
-
- }
- else
- {
- result = 0;
- }
-
- if (!once_control->done)
- {
- if (InterlockedIncrement (&(once_control->started)) == 0)
- {
- /*
- * First thread to increment the started variable
- */
- (*init_routine) ();
- once_control->done = TRUE;
-
- }
- else
- {
- /*
- * Block until other thread finishes executing the onceRoutine
- */
- while (!(once_control->done))
- {
- /*
- * The following gives up CPU cycles without pausing
- * unnecessarily
- */
- Sleep (0);
- }
- }
- }
-
- /*
- * Fall through Intentionally
- */
-
- /*
- * ------------
- * Failure Code
- * ------------
- */
-FAIL0:
- return (result);
-
-} /* pthread_once */
-
-
-pthread_t
-pthread_self (void)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function returns a reference to the current running
- * thread.
- *
- * PARAMETERS
- * N/A
- *
- *
- * DESCRIPTION
- * This function returns a reference to the current running
- * thread.
- *
- * RESULTS
- * pthread_t reference to the current thread
- *
- * ------------------------------------------------------
- */
-{
- pthread_t self;
-
-#ifdef _UWIN
- if(!ptw32_selfThreadKey)
- return(NULL);
-#endif
-
- self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey);
-
- if (self == NULL)
- {
- /*
- * Need to create an implicit 'self' for the currently
- * executing thread.
- */
- self = ptw32_new();
-
- if (self != NULL)
- {
- /*
- * This is a non-POSIX thread which has chosen to call
- * a POSIX threads function for some reason. We assume that
- * it isn't joinable, but we do assume that it's
- * (deferred) cancelable.
- */
- self->implicit = 1;
- self->detachState = PTHREAD_CREATE_DETACHED;
- self->thread = GetCurrentThreadId ();
-
-#ifdef NEED_DUPLICATEHANDLE
- /*
- * DuplicateHandle does not exist on WinCE.
- *
- * NOTE:
- * GetCurrentThread only returns a pseudo-handle
- * which is only valid in the current thread context.
- * Therefore, you should not pass the handle to
- * other threads for whatever purpose.
- */
- self->threadH = GetCurrentThread();
-#else
- if( !DuplicateHandle(
- GetCurrentProcess(),
- GetCurrentThread(),
- GetCurrentProcess(),
- &self->threadH,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS ) )
- {
- free( self );
- return (NULL);
- }
-#endif
- }
-
- pthread_setspecific (ptw32_selfThreadKey, self);
- }
-
- return (self);
-
-} /* pthread_self */
-
-int
-pthread_equal (pthread_t t1, pthread_t t2)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function returns zero if t1 and t2 are equal, else
- * returns nonzero
- *
- * PARAMETERS
- * t1,
- * t2
- * references to an instances of thread_t
- *
- *
- * DESCRIPTION
- * This function returns nonzero if t1 and t2 are equal, else
- * returns zero.
- *
- * RESULTS
- * non-zero if t1 and t2 refer to the same thread,
- * 0 t1 and t2 do not refer to the same thread
- *
- * ------------------------------------------------------
- */
-{
- int result;
-
- /*
- * We also accept NULL == NULL - treating NULL as a thread
- * for this special case, because there is no error that we can return.
- */
- result = ( ( t1 == t2 ) && ( t1 == NULL || ( t1->thread == t2->thread ) ) );
-
- return (result);
-
-} /* pthread_equal */
-
-
-int
-pthread_setconcurrency(int level)
-{
- if (level < 0)
- {
- return EINVAL;
- }
- else
- {
- ptw32_concurrency = level;
- return 0;
- }
-}
-
-
-int
-pthread_getconcurrency(void)
-{
- return ptw32_concurrency;
-}
-
-
-static INLINE int
-ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)
- /*
- * -------------------------------------------------------------------
- * This provides an extra hook into the pthread_cancel
- * mechanism that will allow you to wait on a Windows handle and make it a
- * cancellation point. This function blocks until the given WIN32 handle is
- * signaled or pthread_cancel has been called. It is implemented using
- * WaitForMultipleObjects on 'waitHandle' and a manually reset WIN32
- * event used to implement pthread_cancel.
- *
- * Given this hook it would be possible to implement more of the cancellation
- * points.
- * -------------------------------------------------------------------
- */
-{
- int result;
- pthread_t self;
- HANDLE handles[2];
- DWORD nHandles = 1;
- DWORD status;
-
- handles[0] = waitHandle;
-
- if ((self = pthread_self()) != NULL)
- {
- /*
- * Get cancelEvent handle
- */
- if (self->cancelState == PTHREAD_CANCEL_ENABLE)
- {
-
- if ((handles[1] = self->cancelEvent) != NULL)
- {
- nHandles++;
- }
- }
- }
- else
- {
- handles[1] = NULL;
- }
-
- status = WaitForMultipleObjects (
- nHandles,
- handles,
- FALSE,
- timeout);
-
-
- if (status == WAIT_FAILED)
- {
- result = EINVAL;
- }
- else if (status == WAIT_TIMEOUT)
- {
- result = ETIMEDOUT;
- }
- else if (status == WAIT_ABANDONED_0)
- {
- result = EINVAL;
- }
- else
- {
- /*
- * Either got the handle or the cancel event
- * was signaled
- */
- switch (status - WAIT_OBJECT_0)
- {
-
- case 0:
- /*
- * Got the handle
- */
- result = 0;
- break;
-
- case 1:
- /*
- * Got cancel request
- */
- ResetEvent (handles[1]);
-
- if (self != NULL && !self->implicit)
- {
- /*
- * Thread started with pthread_create.
- * Make sure we haven't been async-canceled in the meantime.
- */
- (void) pthread_mutex_lock(&self->cancelLock);
- if (self->state < PThreadStateCanceling)
- {
- self->state = PThreadStateCanceling;
- self->cancelState = PTHREAD_CANCEL_DISABLE;
- (void) pthread_mutex_unlock(&self->cancelLock);
- ptw32_throw(PTW32_EPS_CANCEL);
-
- /* Never reached */
- }
- (void) pthread_mutex_unlock(&self->cancelLock);
- }
-
- /* Should never get to here. */
- result = EINVAL;
- break;
-
- default:
- result = EINVAL;
- break;
- }
- }
-
- return (result);
-
-} /* CancelableWait */
-
-int
-pthreadCancelableWait (HANDLE waitHandle)
-{
- return (ptw32_cancelable_wait(waitHandle, INFINITE));
-}
-
-int
-pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)
-{
- return (ptw32_cancelable_wait(waitHandle, timeout));
-}
-
-
-pthread_t
-ptw32_new (void)
-{
- pthread_t t;
-
- t = (pthread_t) calloc (1, sizeof (*t));
-
- if (t != NULL)
- {
- t->detachState = PTHREAD_CREATE_JOINABLE;
- t->cancelState = PTHREAD_CANCEL_ENABLE;
- t->cancelType = PTHREAD_CANCEL_DEFERRED;
- t->cancelLock = PTHREAD_MUTEX_INITIALIZER;
- t->cancelEvent = CreateEvent (
- 0,
- (int) TRUE, /* manualReset */
- (int) FALSE, /* setSignaled */
- NULL);
-
- if (t->cancelEvent == NULL)
- {
- free (t);
- t = NULL;
- }
- }
-
- return t;
-
-}
-
-
-#ifdef NEED_CALLOC
-void *
-ptw32_calloc(size_t n, size_t s) {
- unsigned int m = n*s;
- void *p;
-
- p = malloc(m);
- if (p == NULL) return NULL;
-
- memset(p, 0, m);
-
- return p;
-}
-#endif