From 0749394433f301cccd22d280cee1dd760b72e876 Mon Sep 17 00:00:00 2001 From: rpj Date: Mon, 28 Dec 1998 23:01:00 +0000 Subject: With this update I'm able to build the library and build and run the tsd1.c test successfully using buildlib.bat and build.bat scripts. I not convinced that I understand the relationships between "__cplusplus" and "_WIN32" and the MS compiler, particularly in pthread.h where pthread_cleanup_push etc is defined. In particular, I have assumed that the __try/__finally blocks are only available if _WIN32 and __cplusplus are defined. I suspect this is wrong. Tue Dec 29 13:11:16 1998 Ross Johnson * implement.h: Move the following struct definitions to pthread.h: pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_, pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_, pthread_condattr_t_, pthread_once_t_. * pthread.h: Add "_" prefix to pthread_push_cleanup and pthread_pop_cleanup internal routines, and associated struct and typedefs. * buildlib.bat: Add compile command for semaphore.c * pthread.def: Comment out pthread_atfork routine name. Now unimplemented. * tsd.c (pthread_setspecific): Rename tkAssocCreate to _pthread_tkAssocCreate. (pthread_key_delete): Rename tkAssocDestroy to _pthread_tkAssocDestroy. * sync.c (pthread_join): Rename threadDestroy to _pthread_threadDestroy * sched.c (is_attr): attr is now **attr (was *attr), so add extra NULL pointer test. (pthread_attr_setschedparam): Increase redirection for attr which is now a **. (pthread_attr_getschedparam): Ditto. (pthread_setschedparam): Change thread validation and rename "thread" Win32 thread Handle element name to match John Bossom's version. (pthread_getschedparam): Ditto. * private.c (_pthread_threadDestroy): Rename call to callUserDestroyRoutines() as _pthread_callUserDestroyRoutines() * misc.c: Add #include "implement.h". * dll.c: Remove defined(KLUDGE) wrapped code. * fork.c: Remove redefinition of ENOMEM. Remove pthread_atfork() and fork() with #if 0/#endif. * create.c (pthread_create): Rename threadStart and threadDestroy calls to _pthread_threadStart and _pthread_threadDestroy. * implement.h: Rename "detachedstate" to "detachstate". * attr.c: Rename "detachedstate" to "detachstate". Mon Dec 28 09:54:39 1998 Ross Johnson * pthread.h (pthread_attr_t_): Change to *pthread_attr_t. * attr.c (pthread_attr_setstacksize): Merge with John Bossom's version. (pthread_attr_getstacksize): Merge with John Bossom's version. (pthread_attr_setstackaddr): Merge with John Bossom's version. (pthread_attr_getstackaddr): Merge with John Bossom's version. (pthread_attr_init): Merge with John Bossom's version. (pthread_attr_destroy): Merge with John Bossom's version. (pthread_attr_getdetachstate): Merge with John Bossom's version. (pthread_attr_setdetachstate): Merge with John Bossom's version. (is_attr): attr is now **attr (was *attr), so add extra NULL pointer test. * implement.h (pthread_attr_t_): Add and rename elements in JEB's version to correspond to original, so that it can be used with original attr routines. * pthread.h: Add #endif at end which was truncated in merging. --- semaphore.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 semaphore.c (limited to 'semaphore.c') diff --git a/semaphore.c b/semaphore.c new file mode 100644 index 0000000..04e99f5 --- /dev/null +++ b/semaphore.c @@ -0,0 +1,257 @@ +/* + * ------------------------------------------------------------- + * + * $Header: /cvs/pthreads-win32/pthreads/semaphore.c,v 1.1.2.1 1998/12/28 23:01:14 rpj Exp $ + * + * Module: semaphore.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * They are supposed to follow the older UNIX convention for + * reporting errors. That is, on failure they are supposed + * to return a value of -1 and store the appropriate error + * number into 'errno'. + * HOWEVER,errno cannot be modified in a multithreaded + * program on WIN32; therefore, the value is returned as + * the function value. + * It is recommended that you compare for zero (0) for success + * instead of -1 for failure when checking the status of + * these functions. + * + * Contents: + * Public Methods Author + * -------------- ------ + * sem_init John E. Bossom Mar 1998 + * sem_destroy John E. Bossom Mar 1998 + * sem_trywait John E. Bossom Mar 1998 + * sem_wait John E. Bossom Mar 1998 + * sem_post John E. Bossom Mar 1998 + * + * Private Methods + * --------------- + * + * ------------------------------------------------------------- + */ +#include +#include +#include +#include +#include + +#include "semaphore.h" + + + +int +sem_init (sem_t * sem, int pshared, unsigned int value) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function initializes an unnamed semaphore. the + * initial value of the semaphore is 'value' + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * pshared + * if zero, this semaphore may only be shared between + * threads in the same process. + * if nonzero, the semaphore can be shared between + * processes + * + * value + * initial value of the semaphore counter + * + * DESCRIPTION + * This function initializes an unnamed semaphore. The + * initial value of the semaphore is set to 'value'. + * + * RESULTS + * 0 successfully created semaphore, + * EINVAL 'sem' is not a valid semaphore, + * ENOSPC a required resource has been exhausted, + * ENOSYS semaphores are not supported, + * EPERM the process lacks appropriate privilege + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (pshared != 0) + { + /* + * Creating a semaphore that can be shared between + * processes + */ + result = EPERM; + + } + else + { + /* + * NOTE: Taking advantage of the fact that + * sem_t is a simple structure with one entry; + * We don't have to allocate it... + */ + *sem = CreateSemaphore ( + 0, + value, + 0x7FFFFFF, + NULL); + + if (*sem == 0) + { + result = ENOSPC; + } + } + + return (result); + +} /* sem_init */ + + +int +sem_destroy (sem_t * sem) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function destroys an unnamed semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function destroys an unnamed semaphore. + * + * RESULTS + * 0 successfully destroyed semaphore, + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EBUSY threads (or processes) are currently + * blocked on 'sem' + * + * ------------------------------------------------------ + */ +{ + return ((sem == NULL) + ? EINVAL + : (CloseHandle (*sem) + ? 0 + : EINVAL)); + +} /* sem_destroy */ + + +int +sem_trywait (sem_t * sem) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function tries to wait on a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function tries to wait on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * this function returns immediately with the error EAGAIN + * + * RESULTS + * 0 successfully destroyed semaphore, + * EAGAIN the semaphore was already locked, + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + return ((sem == NULL) + ? EINVAL + : ((WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT) + ? EAGAIN + : 0)); + +} /* sem_trywait */ + + +int +sem_wait (sem_t * sem) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function waits on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value or until interrupted by + * a signal. + * + * RESULTS + * 0 successfully destroyed semaphore, + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + + return ((sem == NULL) + ? EINVAL + : pthreadCancelableWait (*sem) + ); + +} /* sem_wait */ + + +int +sem_post (sem_t * sem) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function posts a wakeup to a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function posts a wakeup to a semaphore. If there + * are waiting threads (or processes), on is awakened; + * otherwise, the semaphore value is incremented by one. + * + * RESULTS + * 0 successfully destroyed semaphore, + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * + * ------------------------------------------------------ + */ +{ + return ((sem == NULL) + ? EINVAL + : (ReleaseSemaphore (*sem, 1, 0) + ? 0 + : EINVAL)); + +} /* sem_post */ -- cgit v1.2.3