diff options
| -rw-r--r-- | CONTRIBUTORS | 1 | ||||
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | README.WinCE | 15 | ||||
| -rw-r--r-- | WinCE-PORT | 208 | ||||
| -rw-r--r-- | condvar.c | 16 | ||||
| -rw-r--r-- | config.h | 22 | ||||
| -rw-r--r-- | config.h.in | 19 | ||||
| -rw-r--r-- | errno.c | 4 | ||||
| -rw-r--r-- | implement.h | 19 | ||||
| -rw-r--r-- | misc.c | 20 | ||||
| -rw-r--r-- | mutex.c | 5 | ||||
| -rw-r--r-- | need_errno.h | 132 | ||||
| -rw-r--r-- | private.c | 111 | ||||
| -rw-r--r-- | pthread.def | 4 | ||||
| -rw-r--r-- | pthread.h | 37 | ||||
| -rw-r--r-- | sched.h | 4 | ||||
| -rw-r--r-- | semaphore.c | 126 | ||||
| -rw-r--r-- | semaphore.h | 13 | ||||
| -rw-r--r-- | signal.c | 3 | ||||
| -rw-r--r-- | tsd.c | 5 | 
20 files changed, 736 insertions, 35 deletions
| diff --git a/CONTRIBUTORS b/CONTRIBUTORS index be8aaec..c9818bd 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -15,5 +15,6 @@ Mumit Khan		khan@xraylith.wisc.edu  Aurelio Medina		aureliom@crt.com  Milan Gardian		mg@tatramed.sk  Graham Dumpleton	Graham.Dumpleton@ra.pad.otc.telstra.com.au +Tristan Savatier	tristan@mpegtv.com  Erik Hensema		erik.hensema@group2000.nl  Rich Peters		rpeters@micro-magic.com @@ -1,3 +1,10 @@ +1999-11-05  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> + +	* general: Patched for portability to WinCE. The details are +	described in the file WinCE-PORT. Follow the instructions +	in README.WinCE to make the appropriate changes in config.h. +	- Tristan Savatier <tristan@mpegtv.com> +  1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>  	* create.c (pthread_create): Explicitly initialise thread state to diff --git a/README.WinCE b/README.WinCE new file mode 100644 index 0000000..2d4212e --- /dev/null +++ b/README.WinCE @@ -0,0 +1,15 @@ +WinCE port +---------- +(See the file WinCE-PORT for a detailed explanation.) + +In config.h: + +you need to define the following which are undefined by default: + +#define NEED_DUPLICATEHANDLE +#define NEED_CREATETHREAD +#define NEED_ERRNO +#define NEED_CALLOC +#define NEED_FTIME +#define NEED_SEM + diff --git a/WinCE-PORT b/WinCE-PORT new file mode 100644 index 0000000..9de284d --- /dev/null +++ b/WinCE-PORT @@ -0,0 +1,208 @@ +Some interesting news: + +I have been able to port pthread-win32 to Windows-CE, +which uses a subset of the WIN32 API. + +Since we intend to keep using pthread-win32 for our +Commercial WinCE developments, I would be very interested +if WinCE support could be added to the main source tree +of pthread-win32.  Also, I would like to be credited +for this port :-) + +Now, here is the story... + +The port was performed and tested on a Casio "Cassiopeia" +PalmSize PC, which runs a MIP processor.  The OS in the +Casio is WinCE version 2.11, but I used VC++ 6.0 with +the WinCE SDK for version 2.01. + +I used pthread-win32 to port a heavily multithreaded +commercial application (real-time MPEG video player) +from Linux to WinCE.  I consider the changes that +I have done to be quite well tested. + +Overall the modifications that we had to do are minor. + +The WinCE port were based on pthread-win32-snap-1999-05-30, +but I am certain that they can be integrated very easiely +to more recent versions of the source. + +I have attached the modified source code: +pthread-win32-snap-1999-05-30-WinCE. + +All the changes do not affect the code compiled on non-WinCE +environment, provided that the macros used for WinCE compilation +are not used, of course! + +Overall description of the WinCE port: +------------------------------------- + +Most of the changes had to be made in areas where +pthread-win32 was relying on some standard-C librairies +(e.g. _ftime, calloc, errno), which are not available +on WinCE. We have changed the code to use native Win32 +API instead (or in some cases we made wrappers). + +The Win32 Semaphores are not available, +so we had to re-implement Semaphores using mutexes +and events. + +Limitations / known problems of the WinCE port: +---------------------------------------------- + +Not all the semaphore routines have been ported +(semaphores are defined by Posix but are not part +pf pthread).  I have just done enough to make +pthread routines (that rely internally on semaphores) +work, like signal conditions. + +I noticed that the Win32 threads work slightly +differently on WinCE.  This may have some impact +on some tricky parts of pthread-win32, but I have +not really investigated.  For example, on WinCE, +the process is killed if the main thread falls off +the bottom (or calls pthread_exit), regardless +of the existence of any other detached thread. +Microsoft manual indicates that this behavior is +deffirent from that of Windows Threads for other +Win32 platforms. + + +Detailed descriptions of the changes and rationals: + +------------------------------------ +- use a new macro NEED_ERRNO. + +If defined, the code in errno.c that defines a reentrant errno +is compiled, regardless of _MT and _REENTRANT. + +Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or +any other standard C library, i.e. even if _MT or _REENTRANT +is defined, errno is not provided by any library.  NEED_ERRNO +must be set to compile for WinCE. + +------------------------------------ +- In implement.h, change #include <semaphore.h> to #include "semaphore.h". + +Rational: semaphore.h is provided in pthread-win32 and should not +be searched in the systems standard include.  would not compile. +This change does not seem to create problems on "classic" win32 +(e.g. win95). + +------------------------------------ +- use a new macro NEED_CALLOC. + +If defined, some code in misc.c will provide a replacement +for calloc, which is not available on Win32. + + +------------------------------------ +- use a new macro NEED_CREATETHREAD. + +If defined, implement.h defines the macro _beginthreadex +and _endthreadex. + +Rational: On WinCE, the wrappers _beginthreadex and _endthreadex +do not exist. The native Win32 routines must be used. + +------------------------------------ +- in misc.c: + +#ifdef NEED_DUPLICATEHANDLE +	  /* DuplicateHandle does not exist on WinCE */ +	  self->threadH = GetCurrentThread(); +#else +	  if( !DuplicateHandle( +			       GetCurrentProcess(), +			       GetCurrentThread(), +			       GetCurrentProcess(), +			       &self->threadH, +			       0, +			       FALSE, +			       DUPLICATE_SAME_ACCESS ) ) +	    { +	      free( self ); +	      return (NULL); +	    } +#endif + +Rational: On WinCE, DuplicateHandle does not exist.  I could not understand +why DuplicateHandle must be used.  It seems to me that getting the current +thread handle with GetCurrentThread() is sufficient, and it seems to work +perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ? + +------------------------------------ +- In private.c, added some code at the beginning of _pthread_processInitialize +to detect the case of multiple calls to _pthread_processInitialize. + +Rational: In order to debug pthread-win32, it is easier to compile +it as a regular library (it is not possible to debug DLL's on winCE). +In that case, the application must call _pthread_processInitialize() +explicitely, to initialize pthread-win32.  It is safer in this circumstance +to handle the case where _pthread_processInitialize() is called on +an already initialized library: + +int +_pthread_processInitialize (void) +{ +	if (_pthread_processInitialized) { +		/*  +		 * ignore if already initialized. this is useful for  +		 * programs that uses a non-dll pthread +		 * library. such programs must call _pthread_processInitialize() explicitely, +		 * since this initialization routine is automatically called only when +		 * the dll is loaded. +		 */ +		return TRUE; +	} +    _pthread_processInitialized = TRUE; +  	[...] +} + +------------------------------------ +- in private.c, if macro NEED_FTIME is defined, add routines to +convert timespec_to_filetime and filetime_to_timespec, and modified +code that was using _ftime() to use Win32 API instead. + +Rational: _ftime is not available on WinCE.  It is necessary to use +the native Win32 time API instead. + +Note: the routine timespec_to_filetime is provided as a convenience and a mean +to test that filetime_to_timespec works, but it is not used by the library. + +------------------------------------ +- in semaphore.c, if macro NEED_SEM is defined, add code for the routines +_increase_semaphore and _decrease_semaphore, and modify significantly +the implementation of the semaphores so that it does not use CreateSemaphore. + +Rational: CreateSemaphore is not available on WinCE.  I had to re-implement +semaphores using mutexes and Events. + +Note: Only the semaphore routines that are used by pthread are implemented +(i.e. signal conditions rely on a subset of the semaphores routines, and +this subset works). Some other semaphore routines (e.g. sem_trywait) are +not yet supported on my WinCE port (and since I don't need them, I am not +planning to do anything about them). + +------------------------------------ +- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES + +/* TLS_OUT_OF_INDEXES not defined on WinCE */ +#ifndef TLS_OUT_OF_INDEXES +#define TLS_OUT_OF_INDEXES 0xffffffff +#endif + +Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file +on WinCE. + +------------------------------------ +- added file need_errno.h + +Rational: On WinCE, there is no errno.h file. need_errno.h is just a +copy of windows version of errno.h, with minor modifications due to the fact +that some of the error codes are defined by the WinCE socket library. +In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is +included (instead of <errno.h>). + + +-- eof @@ -946,9 +946,21 @@ pthread_cond_broadcast (pthread_cond_t * cond)        /*         * Wake up all waiters         */ + +#ifdef NEED_SEM + +      result = (_pthread_increase_semaphore( &cv->sema, cv->waiters ) +		? 0 +		: EINVAL); + +#else /* NEED_SEM */ +        result = (ReleaseSemaphore( cv->sema, cv->waiters, NULL ) -	        ? 0 -	        : EINVAL ); +		? 0 +		: EINVAL); + +#endif /* NEED_SEM */ +      }    (void) pthread_mutex_unlock(&(cv->waitersLock)); @@ -3,11 +3,23 @@  /* Do we know about the C type sigset_t? */  #undef HAVE_SIGSET_T -/* Do we have the `_stdcall' keyword? */ -#undef STDCALL -  /* Define if you have the <signal.h> header file.  */  #undef HAVE_SIGNAL_H -/* Define if you have the <windows.h> header file.  */ -#undef HAVE_WINDOWS_H +/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ +#undef NEED_DUPLICATEHANDLE + +/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ +#undef NEED_CREATETHREAD + +/* Define if you don't have Win32 errno. (eg. WinCE) */ +#undef NEED_ERRNO + +/* Define if you don't have Win32 calloc. (eg. WinCE)  */ +#undef NEED_CALLOC + +/* Define if you don't have Win32 ftime. (eg. WinCE)  */ +#undef NEED_FTIME + +/* Define if you don't have Win32 semaphores. (eg. WinCE)  */ +#undef NEED_SEM diff --git a/config.h.in b/config.h.in index 6671c7f..41f703f 100644 --- a/config.h.in +++ b/config.h.in @@ -6,5 +6,20 @@  /* Define if you have the <signal.h> header file.  */  #undef HAVE_SIGNAL_H -/* Define if you have the <windows.h> header file.  */ -#undef HAVE_WINDOWS_H +/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ +#undef NEED_DUPLICATEHANDLE + +/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ +#undef NEED_CREATETHREAD + +/* Define if you don't have Win32 errno. (eg. WinCE) */ +#undef NEED_ERRNO + +/* Define if you don't have Win32 calloc. (eg. WinCE)  */ +#undef NEED_CALLOC + +/* Define if you don't have Win32 ftime. (eg. WinCE)  */ +#undef NEED_FTIME + +/* Define if you don't have Win32 semaphores. (eg. WinCE)  */ +#undef NEED_SEM @@ -24,7 +24,7 @@   * MA 02111-1307, USA   */ -#if ! defined( _REENTRANT ) && ! defined( _MT ) +#if (! defined(HAVE_ERRNO)) || (! defined( _REENTRANT ) && ! defined( _MT ))  #include "pthread.h"  #include "implement.h" @@ -79,4 +79,4 @@ int * _errno( void )  } /* _errno */ -#endif /* !_REENTRANT && !_MT */ +#endif /* (! HAVE_ERRNO) || (!_REENTRANT && !_MT) */ diff --git a/implement.h b/implement.h index 70836dc..bc76dec 100644 --- a/implement.h +++ b/implement.h @@ -27,7 +27,8 @@  #ifndef _IMPLEMENT_H  #define _IMPLEMENT_H -#define PT_STDCALL __stdcall +/* changed include from <semaphore.h> to use local file during development */ +#include "semaphore.h"  #include <semaphore.h> @@ -315,6 +316,12 @@ extern CRITICAL_SECTION _pthread_mutex_test_init_lock;  extern CRITICAL_SECTION _pthread_cond_test_init_lock;  extern CRITICAL_SECTION _pthread_rwlock_test_init_lock; +/* Declared in misc.c */ +#ifdef NEED_CALLOC +#define calloc(n, s) _pthread_calloc(n, s) +void *_pthread_calloc(size_t n, size_t s); +#endif +  #ifdef __cplusplus  extern "C" { @@ -353,6 +360,12 @@ void _pthread_tkAssocDestroy (ThreadKeyAssoc * assoc);  int _pthread_sem_timedwait (sem_t * sem,  			    const struct timespec * abstime); +#ifdef NEED_SEM +void _pthread_decrease_semaphore(sem_t * sem); +BOOL _pthread_increase_semaphore(sem_t * sem, +                                 unsigned int n); +#endif /* NEED_SEM */ +  #ifdef __cplusplus  }  #endif /* __cplusplus */ @@ -365,7 +378,7 @@ int _pthread_sem_timedwait (sem_t * sem,   *   * Patch by Anders Norlander <anorland@hem2.passagen.se>   */ -#if defined(__CYGWIN32__) || defined(__CYGWIN__) +#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)  /*    * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE @@ -387,7 +400,7 @@ int _pthread_sem_timedwait (sem_t * sem,  #define _endthreadex ExitThread -#endif /* __CYGWIN32__ || __CYGWIN__ */ +#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD*/  #endif /* _IMPLEMENT_H */ @@ -163,6 +163,10 @@ pthread_self (void)  	  self->thread = GetCurrentThreadId (); +#ifdef NEED_DUPLICATEHANDLE +	  /* DuplicateHandle does not exist on WinCE */ +	  self->threadH = GetCurrentThread(); +#else  	  if( !DuplicateHandle(  			       GetCurrentProcess(),  			       GetCurrentThread(), @@ -175,6 +179,7 @@ pthread_self (void)  	      free( self );  	      return (NULL);  	    } +#endif  	}        pthread_setspecific (_pthread_selfThreadKey, self); @@ -361,4 +366,17 @@ pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)    return (CancelableWait(waitHandle, timeout));  } - +#ifdef NEED_CALLOC +void  +*_pthread_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 @@ -22,8 +22,9 @@   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,   * MA 02111-1307, USA   */ - -#include <errno.h> +
 +/* errno.h or a replacement file is included by pthread.h */ +//#include <errno.h>  #include "pthread.h"  #include "implement.h" diff --git a/need_errno.h b/need_errno.h new file mode 100644 index 0000000..d10f951 --- /dev/null +++ b/need_errno.h @@ -0,0 +1,132 @@ +/*** +*errno.h - system wide error numbers (set by system calls) +* +*       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +*Purpose: +*       This file defines the system-wide error numbers (set by +*       system calls).  Conforms to the XENIX standard.  Extended +*       for compatibility with Uniforum standard. +*       [System V] +* +*       [Public] +* +****/ + +#if     _MSC_VER > 1000 +#pragma once +#endif + +#ifndef _INC_ERRNO +#define _INC_ERRNO + +#if     !defined(_WIN32) && !defined(_MAC) +#error ERROR: Only Mac or Win32 targets supported! +#endif + +#include <winsock.h> + +#ifdef  __cplusplus +extern "C" { +#endif + + + +/* Define _CRTIMP */ + +#ifndef _CRTIMP +#ifdef  _DLL +#define _CRTIMP __declspec(dllimport) +#else   /* ndef _DLL */ +#define _CRTIMP +#endif  /* _DLL */ +#endif  /* _CRTIMP */ + + +/* Define __cdecl for non-Microsoft compilers */ + +#if     ( !defined(_MSC_VER) && !defined(__cdecl) ) +#define __cdecl +#endif + +/* Define _CRTAPI1 (for compatibility with the NT SDK) */ + +#ifndef _CRTAPI1 +#if	_MSC_VER >= 800 && _M_IX86 >= 300 +#define _CRTAPI1 __cdecl +#else +#define _CRTAPI1 +#endif +#endif + + +/* declare reference to errno */ + +#if     (defined(_MT) || defined(_DLL)) && !defined(_MAC) +_CRTIMP extern int * __cdecl _errno(void); +#define errno   (*_errno()) +#else   /* ndef _MT && ndef _DLL */ +_CRTIMP extern int errno; +#endif  /* _MT || _DLL */ + +/* Error Codes */ + +#define EPERM           1 +#define ENOENT          2 +#define ESRCH           3 +#define EINTR           4 +#define EIO             5 +#define ENXIO           6 +#define E2BIG           7 +#define ENOEXEC         8 +#define EBADF           9 +#define ECHILD          10 +#define EAGAIN          11 +#define ENOMEM          12 +#define EACCES          13 +#define EFAULT          14 +#define EBUSY           16 +#define EEXIST          17 +#define EXDEV           18 +#define ENODEV          19 +#define ENOTDIR         20 +#define EISDIR          21 +#define EINVAL          22 +#define ENFILE          23 +#define EMFILE          24 +#define ENOTTY          25 +#define EFBIG           27 +#define ENOSPC          28 +#define ESPIPE          29 +#define EROFS           30 +#define EMLINK          31 +#define EPIPE           32 +#define EDOM            33 +#define ERANGE          34 +#define EDEADLK         36 + +/* defined differently in winsock.h on WinCE */ +#ifndef ENAMETOOLONG +#define ENAMETOOLONG    38 +#endif + +#define ENOLCK          39 +#define ENOSYS          40 + +/* defined differently in winsock.h on WinCE */ +#ifndef ENOTEMPTY +#define ENOTEMPTY       41 +#endif + +#define EILSEQ          42 + +/* + * Support EDEADLOCK for compatibiity with older MS-C versions. + */ +#define EDEADLOCK       EDEADLK + +#ifdef  __cplusplus +} +#endif + +#endif  /* _INC_ERRNO */ @@ -30,7 +30,9 @@  #endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ +#ifndef NEED_FTIME  #include <sys/timeb.h> +#endif  #include "pthread.h"  #include "semaphore.h"  #include "implement.h" @@ -60,6 +62,17 @@ _pthread_processInitialize (void)        * ------------------------------------------------------        */  { +	if (_pthread_processInitialized) { +		/*  +		 * ignore if already initialized. this is useful for  +		 * programs that uses a non-dll pthread +		 * library. such programs must call _pthread_processInitialize() explicitely, +		 * since this initialization routine is automatically called only when +		 * the dll is loaded. +		 */ +		return TRUE; +	} +    _pthread_processInitialized = TRUE;    /* @@ -586,6 +599,46 @@ _pthread_callUserDestroyRoutines (pthread_t thread)  }				/* _pthread_callUserDestroyRoutines */ + +#ifdef NEED_FTIME + +/* + * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds + */ +#define TIMESPEC_TO_FILETIME_OFFSET \ +          ( ((LONGLONG) 27111902 << 32) + (LONGLONG) 3577643008 ) + +static void +timespec_to_filetime(const struct timespec *ts, FILETIME *ft) +     /* +      * ------------------------------------------------------------------- +      * converts struct timespec +      * where the time is expressed in seconds and nanoseconds from Jan 1, 1970. +      * into FILETIME (as set by GetSystemTimeAsFileTime), where the time is +      * expressed in 100 nanoseconds from Jan 1, 1601, +      * ------------------------------------------------------------------- +      */ +{ +	*(LONGLONG *)ft = ts->tv_sec * 10000000 + (ts->tv_nsec + 50) / 100 + TIMESPEC_TO_FILETIME_OFFSET; +} + +static void +filetime_to_timespec(const FILETIME *ft, struct timespec *ts) +     /* +      * ------------------------------------------------------------------- +      * converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is +      * expressed in 100 nanoseconds from Jan 1, 1601, +      * into struct timespec +      * where the time is expressed in seconds and nanoseconds from Jan 1, 1970. +      * ------------------------------------------------------------------- +      */ +{ +	ts->tv_sec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000); +	ts->tv_nsec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET - ((LONGLONG)ts->tv_sec * (LONGLONG)10000000)) * 100); +} + +#endif /* NEED_FTIME */ +  int  _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)       /* @@ -628,15 +681,21 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)  {    int result = 0; +#ifdef NEED_FTIME + +  struct timespec currSysTime; + +#else /* NEED_FTIME */  #if defined(__MINGW32__)    struct timeb currSysTime; -#else +#else /* __MINGW32__ */    struct _timeb currSysTime; -#endif +#endif /* __MINGW32__ */ +#endif /* NEED_FTIME */    const DWORD NANOSEC_PER_MILLISEC = 1000000;    const DWORD MILLISEC_PER_SEC = 1000; @@ -659,18 +718,56 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)  	   */  	  /* get current system time */ + +#ifdef NEED_FTIME + +	  { +	    FILETIME ft; +	    SYSTEMTIME st; + +	    GetSystemTime(&st); +            SystemTimeToFileTime(&st, &ft); +	    /* +             * GetSystemTimeAsFileTime(&ft); would be faster, +             * but it does not exist on WinCE +             */ + +	    filetime_to_timespec(&ft, &currSysTime); +	  } + +	  /* +           * subtract current system time from abstime +           */ +	  milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; +	  milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; + +#else /* NEED_FTIME */  	  _ftime(&currSysTime); -	  /* subtract current system time from abstime */ +	  /* +           * subtract current system time from abstime +           */  	  milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; -	  milliseconds += (abstime->tv_nsec / NANOSEC_PER_MILLISEC) - +	  milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) -  	    currSysTime.millitm; +#endif /* NEED_FTIME */ + +  	  if (((int) milliseconds) < 0)  	    milliseconds = 0;  	} +#ifdef NEED_SEM + +      result = (pthreadCancelableTimedWait (sem->event, milliseconds)); + +#else /* NEED_SEM */ +        result = (pthreadCancelableTimedWait (*sem, milliseconds)); + +#endif +      }    if (result != 0) @@ -681,6 +778,12 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)      } +#ifdef NEED_SEM + +  _pthread_decrease_semaphore(sem); + +#endif /* NEED_SEM */ +    return 0;  }				/* _pthread_sem_timedwait */ diff --git a/pthread.def b/pthread.def index 6920d5a..9a4efac 100644 --- a/pthread.def +++ b/pthread.def @@ -1,11 +1,12 @@  ; pthread.def -; Last updated: $Date: 1999/09/15 00:56:22 $ +; Last updated: $Date: 1999/11/04 17:18:43 $  ; Currently unimplemented functions are commented out.  LIBRARY pthread  EXPORTS +_pthread_processInitialize  ;pthread_atfork  pthread_attr_destroy  pthread_attr_getdetachstate @@ -108,3 +109,4 @@ pthreadCancelableTimedWait  ;  pthread_push_cleanup  pthread_pop_cleanup + @@ -215,7 +215,12 @@  #endif /* HAVE_CONFIG_H */  #include <windows.h> + +#ifndef NEED_FTIME  #include <time.h> +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */  #if HAVE_SIGNAL_H  #include <signal.h> @@ -242,15 +247,24 @@ struct timespec {  #define SIG_SETMASK 2  #endif /* SIG_SETMASK */ -  #include <process.h> + +/* + * note: ETIMEDOUT is correctly defined in winsock.h on winCE + */ +#ifdef HAVE_WINSOCK_H +#include <winsock.h> +#endif + +#ifdef NEED_ERRNO +#include "need_errno.h" +#else  #include <errno.h> +#endif -#ifdef _WIN32  #ifndef ETIMEDOUT -#define ETIMEDOUT 19981220     /* Let's hope this is unique */ +#define ETIMEDOUT 19981220     /* FIXME: Need the proper value here. */  #endif -#endif /* _WIN32 */  #ifdef _MSC_VER  /* @@ -264,6 +278,13 @@ struct timespec {  #define FALSE	0  #endif /* !TRUE */ +#ifdef __MINGW32__ +#define PT_STDCALL +#else +#define PT_STDCALL __stdcall +#endif + +  /*    * This should perhaps be in autoconf or    * possibly fixed in Mingw32 to @@ -704,6 +725,12 @@ struct _pthread_cleanup_t   */  /* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +int pthread_win32_initialize_np(void); + +/*   * PThread Attribute Functions   */  int pthread_attr_init (pthread_attr_t * attr); @@ -902,7 +929,7 @@ int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);  /*   * Thread-Safe C Runtime Library Mappings.   */ -#if ! defined( _REENTRANT ) && ! defined( _MT ) +#if (! defined(NEED_ERRNO)) || (! defined( _REENTRANT ) && ! defined( _MT ))  int * _errno( void );  #endif @@ -43,8 +43,8 @@  #endif  #include <windows.h> -#include <process.h> -#include <errno.h> +//#include <process.h> +//#include <errno.h>  #ifdef _MSC_VER  /* diff --git a/semaphore.c b/semaphore.c index 0fcfc94..a8c346e 100644 --- a/semaphore.c +++ b/semaphore.c @@ -43,14 +43,13 @@   */  #include <windows.h> -#include <process.h> -#include <sys/timeb.h> +//#include <process.h> +//#include <sys/timeb.h>  #include <string.h>  #include "pthread.h"  #include "semaphore.h" -  int  sem_init (sem_t * sem, int pshared, unsigned int value)       /* @@ -90,6 +89,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value)  {    int result = 0; +    if (pshared != 0)      {        /* @@ -101,6 +101,22 @@ sem_init (sem_t * sem, int pshared, unsigned int value)      }    else      { + +#ifdef NEED_SEM + +      sem->value = value; +      pthread_mutex_init(&sem->mutex, NULL); +      sem->event = CreateEvent (NULL, +				FALSE,	/* manual reset */ +				FALSE,	/* initial state */ +				NULL); +      if (value != 0) +        { +	  SetEvent(sem->event); +        } + +#else /* NEED_SEM */ +        /*         * NOTE: Taking advantage of the fact that         *               sem_t is a simple structure with one entry; @@ -116,6 +132,9 @@ sem_init (sem_t * sem, int pshared, unsigned int value)  	{  	  result = ENOSPC;  	} + +#endif /* NEED_SEM */ +      }    if (result != 0) @@ -161,11 +180,27 @@ sem_destroy (sem_t * sem)      {        result = EINVAL;      } + +#ifdef NEED_SEM + +  else +    { +      pthread_mutex_destroy(&sem->mutex); +      if (!CloseHandle(sem->event)) +        { +          result = EINVAL; +        } +    } + +#else /* NEED_SEM */ +    else if (! CloseHandle (*sem))      {        result = EINVAL;      } +#endif /* NEED_SEM */ +    if (result != 0)      {        errno = result; @@ -213,11 +248,22 @@ sem_trywait (sem_t * sem)      {        result = EINVAL;      } + +#ifdef NEED_SEM + +  /* not yet implemented! */ +  result = EINVAL; +  return -1; + +#else /* NEED_SEM */ +    else if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)      {        result = EAGAIN;      } +#endif /* NEED_SEM */ +    if (result != 0)      {        errno = result; @@ -229,6 +275,53 @@ sem_trywait (sem_t * sem)  }				/* sem_trywait */ +#ifdef NEED_SEM + +void  +_pthread_decrease_semaphore(sem_t * sem) +{ +  pthread_mutex_lock(&sem->mutex); + +  if (sem->value != 0) +    { +      sem->value--; +      if (sem->value != 0) +        { +          SetEvent(sem->event); +        } +    } +  else +    { +      /* this case should not happen! */ +    } + +  pthread_mutex_unlock(&sem->mutex); +} + +BOOL  +_pthread_increase_semaphore(sem_t * sem, unsigned int n) +{ +  BOOL result; + +  pthread_mutex_lock(&sem->mutex); + +  if (sem->value + n > sem->value) +    { +       sem->value += n; +       SetEvent(sem->event); +       result = TRUE; +    } +  else +    { +       result = FALSE; +    } + +  pthread_mutex_unlock(&sem->mutex); +  return result; +} + +#endif /* NEED_SEM */ +  int  sem_wait (sem_t * sem)       /* @@ -268,7 +361,17 @@ sem_wait (sem_t * sem)      }    else      { + +#ifdef NEED_SEM + +	result = pthreadCancelableWait (sem->event); + +#else /* NEED_SEM */ +  	result = pthreadCancelableWait (*sem); + +#endif /* NEED_SEM */ +      }    if (result != 0) @@ -277,6 +380,12 @@ sem_wait (sem_t * sem)        return -1;      } +#ifdef NEED_SEM + +  _decrease_semaphore(sem); + +#endif /* NEED_SEM */ +    return 0;  }				/* sem_wait */ @@ -314,12 +423,21 @@ sem_post (sem_t * sem)      {  	result = EINVAL;      } + +#ifdef NEED_SEM + +  else if (! _increase_semaphore (sem, 1)) + +#else /* NEED_SEM */ +    else if (! ReleaseSemaphore (*sem, 1, 0)) + +#endif /* NEED_SEM */ +      {  	result = EINVAL;      } -    if (result != 0)      {        errno = result; diff --git a/semaphore.h b/semaphore.h index fb475a0..8af8be8 100644 --- a/semaphore.h +++ b/semaphore.h @@ -28,8 +28,11 @@  #if !defined( SEMAPHORE_H )  #define SEMAPHORE_H -#include <process.h> +#ifdef NEED_ERRNO +#include "need_errno.h" +#else  #include <errno.h> +#endif  #define _POSIX_SEMAPHORES @@ -42,7 +45,15 @@ extern "C"  typedef unsigned int mode_t;  #endif +#ifdef NEED_SEM +typedef struct { +	unsigned int	value; +	pthread_mutex_t mutex; +	HANDLE	event; +} sem_t; +#else /* NEED_SEM */  typedef HANDLE sem_t; +#endif /* NEED_SEM */  int sem_init (sem_t * sem,  	      int pshared, @@ -23,7 +23,8 @@   * MA 02111-1307, USA   */ -#include <errno.h> +/* errno.h or a replacement file is included by pthread.h */
 +//#include <errno.h>  #include "pthread.h"  #include "implement.h" @@ -25,6 +25,11 @@  #include "pthread.h"  #include "implement.h" +
 +/* TLS_OUT_OF_INDEXES not defined on WinCE */
 +#ifndef TLS_OUT_OF_INDEXES
 +#define TLS_OUT_OF_INDEXES 0xffffffff
 +#endif
  int  pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) | 
