From 7fdb900bc169f0105bf5fb2cd282f6448f3f11f7 Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 4 Nov 1999 17:18:43 +0000 Subject: 1999-11-05 Ross Johnson * 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 --- CONTRIBUTORS | 1 + ChangeLog | 7 ++ README.WinCE | 15 +++++ WinCE-PORT | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ condvar.c | 16 ++++- config.h | 22 +++++-- config.h.in | 19 +++++- errno.c | 4 +- implement.h | 19 +++++- misc.c | 20 +++++- mutex.c | 5 +- need_errno.h | 132 +++++++++++++++++++++++++++++++++++++ private.c | 111 +++++++++++++++++++++++++++++-- pthread.def | 4 +- pthread.h | 37 +++++++++-- sched.h | 4 +- semaphore.c | 126 ++++++++++++++++++++++++++++++++++-- semaphore.h | 13 +++- signal.c | 3 +- tsd.c | 5 ++ 20 files changed, 736 insertions(+), 35 deletions(-) create mode 100644 README.WinCE create mode 100644 WinCE-PORT create mode 100644 need_errno.h 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 diff --git a/ChangeLog b/ChangeLog index 5e20044..dbed53e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +1999-11-05 Ross Johnson + + * 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 + 1999-10-30 Ross Johnson * 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 , 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 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 ). + + +-- eof diff --git a/condvar.c b/condvar.c index 4b41a23..69ce69f 100644 --- a/condvar.c +++ b/condvar.c @@ -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)); diff --git a/config.h b/config.h index 920b9c4..41f703f 100644 --- a/config.h +++ b/config.h @@ -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 header file. */ #undef HAVE_SIGNAL_H -/* Define if you have the 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 header file. */ #undef HAVE_SIGNAL_H -/* Define if you have the 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/errno.c b/errno.c index c457dd7..77c747a 100644 --- a/errno.c +++ b/errno.c @@ -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 to use local file during development */ +#include "semaphore.h" #include @@ -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 */ -#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 */ diff --git a/misc.c b/misc.c index 208541a..84dc6eb 100644 --- a/misc.c +++ b/misc.c @@ -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 diff --git a/mutex.c b/mutex.c index 16e911c..bef116e 100644 --- a/mutex.c +++ b/mutex.c @@ -22,8 +22,9 @@ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA */ - -#include + +/* errno.h or a replacement file is included by pthread.h */ +//#include #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 + +#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 */ diff --git a/private.c b/private.c index cd01fe5..2e0f53f 100644 --- a/private.c +++ b/private.c @@ -30,7 +30,9 @@ #endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ +#ifndef NEED_FTIME #include +#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 + diff --git a/pthread.h b/pthread.h index 87f769e..54d00ba 100644 --- a/pthread.h +++ b/pthread.h @@ -215,7 +215,12 @@ #endif /* HAVE_CONFIG_H */ #include + +#ifndef NEED_FTIME #include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ #if HAVE_SIGNAL_H #include @@ -242,15 +247,24 @@ struct timespec { #define SIG_SETMASK 2 #endif /* SIG_SETMASK */ - #include + +/* + * note: ETIMEDOUT is correctly defined in winsock.h on winCE + */ +#ifdef HAVE_WINSOCK_H +#include +#endif + +#ifdef NEED_ERRNO +#include "need_errno.h" +#else #include +#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 @@ -703,6 +724,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 */ @@ -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 diff --git a/sched.h b/sched.h index 2f498d3..197ac7b 100644 --- a/sched.h +++ b/sched.h @@ -43,8 +43,8 @@ #endif #include -#include -#include +//#include +//#include #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 -#include -#include +//#include +//#include #include #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 +#ifdef NEED_ERRNO +#include "need_errno.h" +#else #include +#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, diff --git a/signal.c b/signal.c index 504b235..db0feec 100644 --- a/signal.c +++ b/signal.c @@ -23,7 +23,8 @@ * MA 02111-1307, USA */ -#include +/* errno.h or a replacement file is included by pthread.h */ +//#include #include "pthread.h" #include "implement.h" diff --git a/tsd.c b/tsd.c index 0766744..f8656ce 100644 --- a/tsd.c +++ b/tsd.c @@ -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 *)) -- cgit v1.2.3