* cygwin.din (ualarm): New export.
* dcrt0.cc (_dll_crt0): Add experimental tls storage declaration. (dll_crt0): Ditto. * debug.cc (thread_stub): Ditto. * thread.cc: Minor cleanup. (__pthread_create): Add experimental tls storage declaration. * miscfuncs.cc: Define tls index. * winsup.h: Declare experimental tls storage. * window.cc (alarm): Use old timer return from setitimer. (ualarm): New function.
This commit is contained in:
		| @@ -1,3 +1,17 @@ | ||||
| 2001-11-27  Christopher Faylor  <cgf@redhat.com> | ||||
|  | ||||
| 	* cygwin.din (ualarm): New export. | ||||
| 	* dcrt0.cc (_dll_crt0): Add experimental tls storage declaration. | ||||
| 	(dll_crt0): Ditto. | ||||
| 	* debug.cc (thread_stub): Ditto. | ||||
| 	* thread.cc: Minor cleanup. | ||||
| 	(__pthread_create): Add experimental tls storage declaration. | ||||
| 	* miscfuncs.cc: Define tls index. | ||||
| 	* winsup.h: Declare experimental tls storage. | ||||
|  | ||||
| 	* window.cc (alarm): Use old timer return from setitimer. | ||||
| 	(ualarm): New function. | ||||
|  | ||||
| 2001-11-26  Christopher Faylor  <cgf@redhat.com> | ||||
|  | ||||
| 	* Makefile.in (libcygwin.a): Use ar commands to build libcygwin.a since | ||||
|   | ||||
| @@ -858,6 +858,8 @@ ttyname | ||||
| _ttyname = ttyname | ||||
| tzset | ||||
| _tzset = tzset | ||||
| ualarm | ||||
| _ualarm = ualarm | ||||
| umask | ||||
| _umask = umask | ||||
| uname | ||||
| @@ -866,6 +868,8 @@ ungetc | ||||
| _ungetc = ungetc | ||||
| unlink | ||||
| _unlink = unlink | ||||
| usleep | ||||
| _usleep = usleep | ||||
| utime | ||||
| _utime = utime | ||||
| utimes | ||||
| @@ -963,8 +967,6 @@ wcscmp | ||||
| _wcscmp = wcscmp | ||||
| wcslen | ||||
| _wcslen = wcslen | ||||
| usleep | ||||
| _usleep = usleep | ||||
| wprintf | ||||
| _wprintf = wprintf | ||||
| memccpy | ||||
|   | ||||
| @@ -803,6 +803,7 @@ initial_env () | ||||
| extern "C" void __stdcall | ||||
| _dll_crt0 () | ||||
| { | ||||
|   DECLARE_TLS_STORAGE; | ||||
|   initial_env (); | ||||
|   char zeros[sizeof (fork_info->zero)] = {0}; | ||||
| #ifdef DEBUGGING | ||||
| @@ -853,6 +854,7 @@ _dll_crt0 () | ||||
| void | ||||
| dll_crt0 (per_process *uptr) | ||||
| { | ||||
|   DECLARE_TLS_STORAGE; | ||||
|   /* Set the local copy of the pointer into the user space. */ | ||||
|   if (uptr && uptr != user_data) | ||||
|     { | ||||
|   | ||||
| @@ -82,6 +82,7 @@ thread_start NO_COPY start_buf[NTHREADS] = {{0, NULL,NULL}}; | ||||
| static DWORD WINAPI | ||||
| thread_stub (VOID *arg) | ||||
| { | ||||
|   DECLARE_TLS_STORAGE; | ||||
|   LPTHREAD_START_ROUTINE threadfunc = ((thread_start *) arg)->func; | ||||
|   VOID *threadarg = ((thread_start *) arg)->arg; | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ details. */ | ||||
| #include "cygerrno.h" | ||||
| #include <sys/errno.h> | ||||
|  | ||||
| /********************** String Helper Functions ************************/ | ||||
| long tls_ix; | ||||
|  | ||||
| const char case_folded_lower[] NO_COPY = { | ||||
|    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15, | ||||
|   | ||||
| @@ -289,7 +289,7 @@ MTinterface::Init (int forked) | ||||
|       thread_self_dwTlsIndex = TlsAlloc (); | ||||
|       if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES) | ||||
| 	system_printf | ||||
| 	  ("local storage for thread couldn't be set\nThis means that we are not thread safe!\n"); | ||||
| 	  ("local storage for thread couldn't be set\nThis means that we are not thread safe!"); | ||||
|     } | ||||
|  | ||||
|   concurrency = 0; | ||||
| @@ -323,21 +323,21 @@ void | ||||
| MTinterface::fixup_after_fork (void) | ||||
| { | ||||
|   pthread_mutex *mutex = mutexs; | ||||
|   debug_printf("mutexs is %x\n",mutexs); | ||||
|   debug_printf ("mutexs is %x",mutexs); | ||||
|   while (mutex) | ||||
|     { | ||||
|       mutex->fixup_after_fork (); | ||||
|       mutex = mutex->next; | ||||
|     } | ||||
|   pthread_cond *cond = conds; | ||||
|   debug_printf("conds is %x\n",conds); | ||||
|   debug_printf ("conds is %x",conds); | ||||
|   while (cond) | ||||
|     { | ||||
|       cond->fixup_after_fork (); | ||||
|       cond = cond->next; | ||||
|     } | ||||
|   semaphore *sem = semaphores; | ||||
|   debug_printf("semaphores is %x\n",semaphores); | ||||
|   debug_printf ("semaphores is %x",semaphores); | ||||
|   while (sem) | ||||
|     { | ||||
|       sem->fixup_after_fork (); | ||||
| @@ -375,7 +375,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr, | ||||
|   function = func; | ||||
|   arg = threadarg; | ||||
|  | ||||
|   win32_obj_id =::CreateThread (&sec_none_nih, attr.stacksize, | ||||
|   win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize, | ||||
| 				(LPTHREAD_START_ROUTINE) thread_init_wrapper, | ||||
| 				this, CREATE_SUSPENDED, &thread_id); | ||||
|  | ||||
| @@ -420,14 +420,14 @@ pthread_cond::pthread_cond (pthread_condattr *attr):verifyable_object (PTHREAD_C | ||||
|   this->mutex = NULL; | ||||
|   this->waiting = 0; | ||||
|  | ||||
|   this->win32_obj_id =::CreateEvent (&sec_none_nih, false,	/*auto signal reset - which I think is pthreads like ? */ | ||||
|   this->win32_obj_id = ::CreateEvent (&sec_none_nih, false,	/*auto signal reset - which I think is pthreads like ? */ | ||||
| 				     false,	/*start non signaled */ | ||||
| 				     NULL /*no name */); | ||||
|   /*TODO: make a shared mem mutex if out attributes request shared mem cond */ | ||||
|   cond_access=NULL; | ||||
|   cond_access = NULL; | ||||
|   if ((temperr = pthread_mutex_init (&this->cond_access, NULL))) | ||||
|     { | ||||
|       system_printf ("couldn't init mutex, this %0p errno=%d\n", this, temperr); | ||||
|       system_printf ("couldn't init mutex, this %p errno %d", this, temperr); | ||||
|       /*we need the mutex for correct behaviour */ | ||||
|       magic = 0; | ||||
|     } | ||||
| @@ -461,33 +461,33 @@ pthread_cond::BroadCast () | ||||
| { | ||||
|   /* TODO: implement the same race fix as Signal has */ | ||||
|   if (pthread_mutex_lock (&cond_access)) | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %0p\n", this); | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %p", this); | ||||
|   int count = waiting; | ||||
|   if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) | ||||
|     { | ||||
|       if (pthread_mutex_unlock (&cond_access)) | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %0p\n", this); | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %p", this); | ||||
|       /*This isn't and API error - users are allowed to call this when no threads | ||||
| 	 are waiting | ||||
| 	 system_printf ("Broadcast called with invalid mutex\n"); | ||||
| 	 system_printf ("Broadcast called with invalid mutex"); | ||||
|       */ | ||||
|       return; | ||||
|     } | ||||
|   while (count--) | ||||
|     PulseEvent (win32_obj_id); | ||||
|   if (pthread_mutex_unlock (&cond_access)) | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %0p\n", this); | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %p", this); | ||||
| } | ||||
|  | ||||
| void | ||||
| pthread_cond::Signal () | ||||
| { | ||||
|   if (pthread_mutex_lock (&cond_access)) | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %0p\n", this); | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %p", this); | ||||
|   if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) | ||||
|     { | ||||
|       if (pthread_mutex_unlock (&cond_access)) | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %0p\n", | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %p", | ||||
| 		       this); | ||||
|       return; | ||||
|     } | ||||
| @@ -496,7 +496,7 @@ pthread_cond::Signal () | ||||
|     /* nothing to signal */ | ||||
|     { | ||||
|       if (pthread_mutex_unlock (&cond_access)) | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %0p\n", this); | ||||
| 	system_printf ("Failed to unlock condition variable access mutex, this %p", this); | ||||
|       return; | ||||
|     } | ||||
|   PulseEvent (win32_obj_id); | ||||
| @@ -518,7 +518,7 @@ pthread_cond::Signal () | ||||
|     } | ||||
|   InterlockedDecrement (&waiting); | ||||
|   if (pthread_mutex_unlock (&cond_access)) | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %0p\n", this); | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %p", this); | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -563,16 +563,16 @@ pthread_cond::TimedWait (DWORD dwMilliseconds) | ||||
| void | ||||
| pthread_cond::fixup_after_fork () | ||||
| { | ||||
|   debug_printf("cond %x in fixup_after_fork\n", this); | ||||
|   debug_printf ("cond %x in fixup_after_fork", this); | ||||
|   if (shared != PTHREAD_PROCESS_PRIVATE) | ||||
|     api_fatal("doesn't understand PROCESS_SHARED condition variables\n"); | ||||
|     api_fatal ("doesn't understand PROCESS_SHARED condition variables"); | ||||
|   /* FIXME: duplicate code here and in the constructor. */ | ||||
|   this->win32_obj_id =::CreateEvent (&sec_none_nih, false, false, NULL); | ||||
|   this->win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL); | ||||
|   if (!win32_obj_id) | ||||
|     api_fatal("failed to create new win32 mutex\n"); | ||||
|     api_fatal ("failed to create new win32 mutex"); | ||||
| #if DETECT_BAD_APPS | ||||
|   if (waiting) | ||||
|     api_fatal("Forked() while a condition variable has waiting threads.\nReport to cygwin@cygwin.com\n"); | ||||
|     api_fatal ("Forked () while a condition variable has waiting threads.\nReport to cygwin@cygwin.com"); | ||||
| #else | ||||
|   waiting = 0; | ||||
|   mutex = NULL; | ||||
| @@ -641,7 +641,7 @@ pthread_key::get () | ||||
| pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREAD_MUTEX_MAGIC) | ||||
| { | ||||
|   /*attr checked in the C call */ | ||||
|   if (attr && attr->pshared==PTHREAD_PROCESS_SHARED) | ||||
|   if (attr && attr->pshared == PTHREAD_PROCESS_SHARED) | ||||
|     { | ||||
|       // fail | ||||
|       magic = 0; | ||||
| @@ -651,7 +651,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA | ||||
|     InitializeCriticalSection (&criticalsection); | ||||
|   else | ||||
|     { | ||||
|       this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); | ||||
|       this->win32_obj_id = ::CreateMutex (&sec_none_nih, false, NULL); | ||||
|       if (!win32_obj_id) | ||||
| 	magic = 0; | ||||
|     } | ||||
| @@ -721,21 +721,21 @@ pthread_mutex::UnLock () | ||||
| void | ||||
| pthread_mutex::fixup_after_fork () | ||||
| { | ||||
|   debug_printf("mutex %x in fixup_after_fork\n", this); | ||||
|   debug_printf ("mutex %x in fixup_after_fork", this); | ||||
|   if (pshared != PTHREAD_PROCESS_PRIVATE) | ||||
|     api_fatal("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's\n"); | ||||
|     api_fatal ("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's"); | ||||
|   /* FIXME: duplicate code here and in the constructor. */ | ||||
|   if (wincap.has_try_enter_critical_section ()) | ||||
|     InitializeCriticalSection(&criticalsection); | ||||
|     InitializeCriticalSection (&criticalsection); | ||||
|   else | ||||
|     { | ||||
|       win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); | ||||
|       win32_obj_id = ::CreateMutex (&sec_none_nih, false, NULL); | ||||
|       if (!win32_obj_id) | ||||
| 	api_fatal("pthread_mutex::fixup_after_fork() failed to create new win32 mutex\n"); | ||||
| 	api_fatal ("pthread_mutex::fixup_after_fork () failed to create new win32 mutex"); | ||||
|     } | ||||
| #if DETECT_BAD_APPS | ||||
|   if (condwaits) | ||||
|     api_fatal("Forked() while a mutex has condition variables waiting on it.\nReport to cygwin@cygwin.com\n"); | ||||
|     api_fatal ("Forked () while a mutex has condition variables waiting on it.\nReport to cygwin@cygwin.com"); | ||||
| #else | ||||
|   condwaits = 0; | ||||
| #endif | ||||
| @@ -752,7 +752,7 @@ pthread_mutexattr::~pthread_mutexattr () | ||||
|  | ||||
| semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MAGIC) | ||||
| { | ||||
|   this->win32_obj_id =::CreateSemaphore (&sec_none_nih, value, LONG_MAX, | ||||
|   this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, value, LONG_MAX, | ||||
| 					 NULL); | ||||
|   if (!this->win32_obj_id) | ||||
|     magic = 0; | ||||
| @@ -809,13 +809,13 @@ semaphore::Wait () | ||||
| void | ||||
| semaphore::fixup_after_fork () | ||||
| { | ||||
|   debug_printf("sem %x in fixup_after_fork\n", this); | ||||
|   debug_printf ("sem %x in fixup_after_fork", this); | ||||
|   if (shared != PTHREAD_PROCESS_PRIVATE) | ||||
|     api_fatal("doesn't understand PROCESS_SHARED semaphores variables\n"); | ||||
|     api_fatal ("doesn't understand PROCESS_SHARED semaphores variables"); | ||||
|   /* FIXME: duplicate code here and in the constructor. */ | ||||
|   this->win32_obj_id =::CreateSemaphore (&sec_none_nih, currentvalue, LONG_MAX, NULL); | ||||
|   this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue, LONG_MAX, NULL); | ||||
|   if (!win32_obj_id) | ||||
|     api_fatal("failed to create new win32 semaphore\n"); | ||||
|     api_fatal ("failed to create new win32 semaphore"); | ||||
| } | ||||
|  | ||||
| verifyable_object::verifyable_object (long verifyer): | ||||
| @@ -891,7 +891,7 @@ thread_init_wrapper (void *_arg) | ||||
|   if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent)) | ||||
|     system_printf ("local storage for thread couldn't be set"); | ||||
|  | ||||
|   /*the OS doesn't check this for <=64 Tls entries (pre win2k) */ | ||||
|   /*the OS doesn't check this for <= 64 Tls entries (pre win2k) */ | ||||
|   TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread); | ||||
|  | ||||
| #ifdef _CYG_THREAD_FAILSAFE | ||||
| @@ -919,6 +919,7 @@ int | ||||
| __pthread_create (pthread_t *thread, const pthread_attr_t *attr, | ||||
| 		  void *(*start_routine) (void *), void *arg) | ||||
| { | ||||
|   DECLARE_TLS_STORAGE; | ||||
|   if (attr && verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT) | ||||
|     return EINVAL; | ||||
|  | ||||
| @@ -1293,7 +1294,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi | ||||
|   if (prepcb) | ||||
|   { | ||||
|     prepcb->cb = prepare; | ||||
|     prepcb->next=(callback *)InterlockedExchangePointer ((LONG *) &MT_INTERFACE->pthread_prepare, (long int) prepcb); | ||||
|     prepcb->next = (callback *)InterlockedExchangePointer ((LONG *) &MT_INTERFACE->pthread_prepare, (long int) prepcb); | ||||
|   } | ||||
|   if (parentcb) | ||||
|   { | ||||
| @@ -1302,7 +1303,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi | ||||
|     while (*t) | ||||
|       t = &(*t)->next; | ||||
|     /*t = pointer to last next in the list */ | ||||
|     parentcb->next=(callback *)InterlockedExchangePointer ((LONG *) t, (long int) parentcb); | ||||
|     parentcb->next = (callback *)InterlockedExchangePointer ((LONG *) t, (long int) parentcb); | ||||
|   } | ||||
|   if (childcb) | ||||
|   { | ||||
| @@ -1311,7 +1312,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi | ||||
|     while (*t) | ||||
|       t = &(*t)->next; | ||||
|     /*t = pointer to last next in the list */ | ||||
|     childcb->next=(callback *)InterlockedExchangePointer ((LONG *) t, (long int) childcb); | ||||
|     childcb->next = (callback *)InterlockedExchangePointer ((LONG *) t, (long int) childcb); | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| @@ -1759,13 +1760,13 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
|  | ||||
|   /*if the cond variable is blocked, then the above timer test maybe wrong. *shrug**/ | ||||
|   if (pthread_mutex_lock (&(*cond)->cond_access)) | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %0p\n", *cond); | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %p", *cond); | ||||
|  | ||||
|   if ((*cond)->waiting) | ||||
|     if ((*cond)->mutex && ((*cond)->mutex != (*themutex))) | ||||
|       { | ||||
| 	if (pthread_mutex_unlock (&(*cond)->cond_access)) | ||||
| 	  system_printf ("Failed to unlock condition variable access mutex, this %0p\n", *cond); | ||||
| 	  system_printf ("Failed to unlock condition variable access mutex, this %p", *cond); | ||||
| 	return EINVAL; | ||||
|       } | ||||
|   InterlockedIncrement (&((*cond)->waiting)); | ||||
| @@ -1773,7 +1774,7 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
|   (*cond)->mutex = (*themutex); | ||||
|   InterlockedIncrement (&((*themutex)->condwaits)); | ||||
|   if (pthread_mutex_unlock (&(*cond)->cond_access)) | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %0p\n", *cond); | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %p", *cond); | ||||
|   rv = (*cond)->TimedWait (waitlength); | ||||
|   /* this may allow a race on the mutex acquisition and waits.. | ||||
|    * But doing this within the cond access mutex creates a different race | ||||
| @@ -1785,10 +1786,10 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
|   if (last == true) | ||||
|     (*cond)->mutex = NULL; | ||||
|   if (pthread_mutex_lock (&(*cond)->cond_access)) | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %0p\n", *cond); | ||||
|     system_printf ("Failed to lock condition variable access mutex, this %p", *cond); | ||||
|   InterlockedDecrement (&((*themutex)->condwaits)); | ||||
|   if (pthread_mutex_unlock (&(*cond)->cond_access)) | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %0p\n", *cond); | ||||
|     system_printf ("Failed to unlock condition variable access mutex, this %p", *cond); | ||||
|  | ||||
|   return rv; | ||||
| } | ||||
| @@ -1797,11 +1798,11 @@ extern "C" int | ||||
| pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
| 			const struct timespec *abstime) | ||||
| { | ||||
|   if (check_valid_pointer(abstime)) | ||||
|   if (check_valid_pointer (abstime)) | ||||
|     return EINVAL; | ||||
|   struct timeb currSysTime; | ||||
|   long waitlength; | ||||
|   ftime(&currSysTime); | ||||
|   ftime (&currSysTime); | ||||
|   waitlength = (abstime->tv_sec - currSysTime.time) *1000; | ||||
|   if (waitlength < 0) | ||||
|     return ETIMEDOUT; | ||||
| @@ -1945,7 +1946,7 @@ int | ||||
| __pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, | ||||
| 				int *prioceiling) | ||||
| { | ||||
|   pthread_mutex_t *themutex=(pthread_mutex_t *) mutex; | ||||
|   pthread_mutex_t *themutex = (pthread_mutex_t *) mutex; | ||||
|   if (*mutex == PTHREAD_MUTEX_INITIALIZER) | ||||
|     __pthread_mutex_init ((pthread_mutex_t *) mutex, NULL); | ||||
|   if (verifyable_object_isvalid (themutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) | ||||
|   | ||||
							
								
								
									
										84
									
								
								winsup/cygwin/winbase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								winsup/cygwin/winbase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| #include_next "winbase.h" | ||||
|  | ||||
| #ifndef _WINBASE2_H | ||||
| #define _WINBASE2_H | ||||
|  | ||||
| extern __inline__ long ilockincr (long *m) | ||||
| { | ||||
|   register int __res; | ||||
|   __asm__ __volatile__ ("\n\ | ||||
| 	movl	$1,%0\n\ | ||||
| 	lock	xadd %0,(%1)\n\ | ||||
| 	inc	%0\n\ | ||||
| 	": "=a" (__res), "=r" (m): "1" (m)); | ||||
|   return __res; | ||||
| } | ||||
| extern __inline__ long ilockdecr (long *m) | ||||
| { | ||||
|   register int __res; | ||||
|   __asm__ __volatile__ ("\n\ | ||||
| 	movl	$0xffffffff,%0\n\ | ||||
| 	lock	xadd %0,(%1)\n\ | ||||
| 	dec	%0\n\ | ||||
| 	": "=a" (__res), "=r" (m): "1" (m)); | ||||
|   return __res; | ||||
| } | ||||
| extern __inline__ long ilockexch (long *t, long v) | ||||
| { | ||||
|   register int __res; | ||||
|   __asm__ __volatile__ ("\n\ | ||||
| 	movl	(%2),%0\n\ | ||||
| 1:	lock	cmpxchgl %3,(%1)\n\ | ||||
| 	jne 1b\n\ | ||||
|  	": "=a" (__res), "=c" (t): "1" (t), "d" (v)); | ||||
|   return __res; | ||||
| } | ||||
|  | ||||
| #undef InterlockedIncrement | ||||
| #define InterlockedIncrement ilockincr | ||||
| #undef InterlockedDecrement | ||||
| #define InterlockedDecrement ilockdecr | ||||
| #undef InterlockedExchange | ||||
| #define InterlockedExchange ilockexch | ||||
|  | ||||
| extern long tls_ix; | ||||
|  | ||||
| extern __inline__ DWORD | ||||
| my_tlsalloc () | ||||
| { | ||||
|   return (DWORD) ilockincr (&tls_ix); | ||||
| } | ||||
|  | ||||
| extern __inline__ BOOL | ||||
| my_tlssetvalue (DWORD ix, void *val) | ||||
| { | ||||
|   char **stackbase; | ||||
|   __asm__ volatile ("movl %%fs:4,%0": "=g" (stackbase)); | ||||
|   stackbase[-ix] = (char *) val; | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| extern __inline__ void * | ||||
| my_tlsgetvalue (DWORD ix) | ||||
| { | ||||
|   char **stackbase; | ||||
|   __asm__ volatile ("movl %%fs:4,%0": "=g" (stackbase)); | ||||
|   return stackbase[-ix]; | ||||
| } | ||||
|  | ||||
| extern __inline__ BOOL | ||||
| my_tlsfree (DWORD ix) | ||||
| { | ||||
|   /* nothing for now */ | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| #undef TlsAlloc | ||||
| #define TlsAlloc my_tlsalloc | ||||
| #undef TlsGetValue | ||||
| #define TlsGetValue my_tlsgetvalue | ||||
| #undef TlsSetValue | ||||
| #define TlsSetValue my_tlssetvalue | ||||
| #undef TlsFree | ||||
| #define TlsFree my_tlsfree | ||||
| #endif /*_WINBASE2_H*/ | ||||
| @@ -150,8 +150,7 @@ window_terminate () | ||||
|     SendMessage (ourhwnd, WM_DESTROY, 0, 0); | ||||
| } | ||||
|  | ||||
| extern "C" | ||||
| int | ||||
| extern "C" int | ||||
| setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) | ||||
| { | ||||
|   UINT elapse; | ||||
| @@ -195,8 +194,7 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| extern "C" | ||||
| int | ||||
| extern "C" int | ||||
| getitimer (int which, struct itimerval *value) | ||||
| { | ||||
|   UINT elapse, val; | ||||
| @@ -221,27 +219,41 @@ getitimer (int which, struct itimerval *value) | ||||
|   elapse = GetTickCount () - start_time; | ||||
|   val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; | ||||
|   val -= elapse; | ||||
|   value->it_value.tv_sec = val/1000; | ||||
|   value->it_value.tv_usec = val%1000; | ||||
|   value->it_value.tv_sec = val / 1000; | ||||
|   value->it_value.tv_usec = val % 1000; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| extern "C" | ||||
| unsigned int | ||||
| extern "C" unsigned int | ||||
| alarm (unsigned int seconds) | ||||
| { | ||||
|   int ret; | ||||
|   struct itimerval newt, oldt; | ||||
|  | ||||
|   getitimer (ITIMER_REAL, &oldt); | ||||
|  | ||||
|   newt.it_value.tv_sec = seconds; | ||||
|   newt.it_value.tv_usec = 0; | ||||
|   newt.it_interval.tv_sec = 0; | ||||
|   newt.it_interval.tv_usec = 0; | ||||
|   setitimer (ITIMER_REAL, &newt, NULL); | ||||
|   setitimer (ITIMER_REAL, &newt, &oldt); | ||||
|   ret = oldt.it_value.tv_sec; | ||||
|   if (ret == 0 && oldt.it_value.tv_usec) | ||||
|     ret = 1; | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| extern "C" useconds_t | ||||
| ualarm (useconds_t value, useconds_t interval) | ||||
| { | ||||
|   struct itimerval timer, otimer; | ||||
|  | ||||
|   timer.it_value.tv_sec = 0; | ||||
|   timer.it_value.tv_usec = value; | ||||
|   timer.it_interval.tv_sec = 0; | ||||
|   timer.it_interval.tv_usec = interval; | ||||
|  | ||||
|   if (setitimer (ITIMER_REAL, &timer, &otimer) < 0) | ||||
|     return (u_int)-1; | ||||
|  | ||||
|   return (otimer.it_value.tv_sec * 1000000) + otimer.it_value.tv_usec; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -272,4 +272,11 @@ extern HMODULE cygwin_hmodule; | ||||
| #define winsock_active (wsadata.wVersion < 512) | ||||
| extern struct WSAData wsadata; | ||||
|  | ||||
| #ifdef EXPCGF | ||||
| #define DECLARE_TLS_STORAGE char **tls[4096] __attribute__ ((unused)) | ||||
| #else | ||||
| #define DECLARE_TLS_STORAGE do {} while (0) | ||||
| #define _WINBASE2_H | ||||
| #endif | ||||
|  | ||||
| #endif /* defined __cplusplus */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user