* 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:
Christopher Faylor 2001-11-28 00:06:35 +00:00
parent a6d66c1399
commit 4d029f3940
9 changed files with 183 additions and 60 deletions

View File

@ -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> 2001-11-26 Christopher Faylor <cgf@redhat.com>
* Makefile.in (libcygwin.a): Use ar commands to build libcygwin.a since * Makefile.in (libcygwin.a): Use ar commands to build libcygwin.a since

View File

@ -858,6 +858,8 @@ ttyname
_ttyname = ttyname _ttyname = ttyname
tzset tzset
_tzset = tzset _tzset = tzset
ualarm
_ualarm = ualarm
umask umask
_umask = umask _umask = umask
uname uname
@ -866,6 +868,8 @@ ungetc
_ungetc = ungetc _ungetc = ungetc
unlink unlink
_unlink = unlink _unlink = unlink
usleep
_usleep = usleep
utime utime
_utime = utime _utime = utime
utimes utimes
@ -963,8 +967,6 @@ wcscmp
_wcscmp = wcscmp _wcscmp = wcscmp
wcslen wcslen
_wcslen = wcslen _wcslen = wcslen
usleep
_usleep = usleep
wprintf wprintf
_wprintf = wprintf _wprintf = wprintf
memccpy memccpy

View File

@ -803,6 +803,7 @@ initial_env ()
extern "C" void __stdcall extern "C" void __stdcall
_dll_crt0 () _dll_crt0 ()
{ {
DECLARE_TLS_STORAGE;
initial_env (); initial_env ();
char zeros[sizeof (fork_info->zero)] = {0}; char zeros[sizeof (fork_info->zero)] = {0};
#ifdef DEBUGGING #ifdef DEBUGGING
@ -853,6 +854,7 @@ _dll_crt0 ()
void void
dll_crt0 (per_process *uptr) dll_crt0 (per_process *uptr)
{ {
DECLARE_TLS_STORAGE;
/* Set the local copy of the pointer into the user space. */ /* Set the local copy of the pointer into the user space. */
if (uptr && uptr != user_data) if (uptr && uptr != user_data)
{ {

View File

@ -82,6 +82,7 @@ thread_start NO_COPY start_buf[NTHREADS] = {{0, NULL,NULL}};
static DWORD WINAPI static DWORD WINAPI
thread_stub (VOID *arg) thread_stub (VOID *arg)
{ {
DECLARE_TLS_STORAGE;
LPTHREAD_START_ROUTINE threadfunc = ((thread_start *) arg)->func; LPTHREAD_START_ROUTINE threadfunc = ((thread_start *) arg)->func;
VOID *threadarg = ((thread_start *) arg)->arg; VOID *threadarg = ((thread_start *) arg)->arg;

View File

@ -12,7 +12,7 @@ details. */
#include "cygerrno.h" #include "cygerrno.h"
#include <sys/errno.h> #include <sys/errno.h>
/********************** String Helper Functions ************************/ long tls_ix;
const char case_folded_lower[] NO_COPY = { const char case_folded_lower[] NO_COPY = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,

View File

@ -289,7 +289,7 @@ MTinterface::Init (int forked)
thread_self_dwTlsIndex = TlsAlloc (); thread_self_dwTlsIndex = TlsAlloc ();
if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES) if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES)
system_printf 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; concurrency = 0;
@ -323,21 +323,21 @@ void
MTinterface::fixup_after_fork (void) MTinterface::fixup_after_fork (void)
{ {
pthread_mutex *mutex = mutexs; pthread_mutex *mutex = mutexs;
debug_printf("mutexs is %x\n",mutexs); debug_printf ("mutexs is %x",mutexs);
while (mutex) while (mutex)
{ {
mutex->fixup_after_fork (); mutex->fixup_after_fork ();
mutex = mutex->next; mutex = mutex->next;
} }
pthread_cond *cond = conds; pthread_cond *cond = conds;
debug_printf("conds is %x\n",conds); debug_printf ("conds is %x",conds);
while (cond) while (cond)
{ {
cond->fixup_after_fork (); cond->fixup_after_fork ();
cond = cond->next; cond = cond->next;
} }
semaphore *sem = semaphores; semaphore *sem = semaphores;
debug_printf("semaphores is %x\n",semaphores); debug_printf ("semaphores is %x",semaphores);
while (sem) while (sem)
{ {
sem->fixup_after_fork (); sem->fixup_after_fork ();
@ -375,7 +375,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
function = func; function = func;
arg = threadarg; 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, (LPTHREAD_START_ROUTINE) thread_init_wrapper,
this, CREATE_SUSPENDED, &thread_id); this, CREATE_SUSPENDED, &thread_id);
@ -420,14 +420,14 @@ pthread_cond::pthread_cond (pthread_condattr *attr):verifyable_object (PTHREAD_C
this->mutex = NULL; this->mutex = NULL;
this->waiting = 0; 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 */ false, /*start non signaled */
NULL /*no name */); NULL /*no name */);
/*TODO: make a shared mem mutex if out attributes request shared mem cond */ /*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))) 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 */ /*we need the mutex for correct behaviour */
magic = 0; magic = 0;
} }
@ -461,33 +461,33 @@ pthread_cond::BroadCast ()
{ {
/* TODO: implement the same race fix as Signal has */ /* TODO: implement the same race fix as Signal has */
if (pthread_mutex_lock (&cond_access)) 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; int count = waiting;
if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
{ {
if (pthread_mutex_unlock (&cond_access)) 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 /*This isn't and API error - users are allowed to call this when no threads
are waiting are waiting
system_printf ("Broadcast called with invalid mutex\n"); system_printf ("Broadcast called with invalid mutex");
*/ */
return; return;
} }
while (count--) while (count--)
PulseEvent (win32_obj_id); PulseEvent (win32_obj_id);
if (pthread_mutex_unlock (&cond_access)) 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 void
pthread_cond::Signal () pthread_cond::Signal ()
{ {
if (pthread_mutex_lock (&cond_access)) 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 (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
{ {
if (pthread_mutex_unlock (&cond_access)) 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); this);
return; return;
} }
@ -496,7 +496,7 @@ pthread_cond::Signal ()
/* nothing to signal */ /* nothing to signal */
{ {
if (pthread_mutex_unlock (&cond_access)) 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; return;
} }
PulseEvent (win32_obj_id); PulseEvent (win32_obj_id);
@ -518,7 +518,7 @@ pthread_cond::Signal ()
} }
InterlockedDecrement (&waiting); InterlockedDecrement (&waiting);
if (pthread_mutex_unlock (&cond_access)) 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 int
@ -563,16 +563,16 @@ pthread_cond::TimedWait (DWORD dwMilliseconds)
void void
pthread_cond::fixup_after_fork () 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) 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. */ /* 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) 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 DETECT_BAD_APPS
if (waiting) 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 #else
waiting = 0; waiting = 0;
mutex = NULL; mutex = NULL;
@ -641,7 +641,7 @@ pthread_key::get ()
pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREAD_MUTEX_MAGIC) pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREAD_MUTEX_MAGIC)
{ {
/*attr checked in the C call */ /*attr checked in the C call */
if (attr && attr->pshared==PTHREAD_PROCESS_SHARED) if (attr && attr->pshared == PTHREAD_PROCESS_SHARED)
{ {
// fail // fail
magic = 0; magic = 0;
@ -651,7 +651,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA
InitializeCriticalSection (&criticalsection); InitializeCriticalSection (&criticalsection);
else 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) if (!win32_obj_id)
magic = 0; magic = 0;
} }
@ -721,21 +721,21 @@ pthread_mutex::UnLock ()
void void
pthread_mutex::fixup_after_fork () 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) 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. */ /* FIXME: duplicate code here and in the constructor. */
if (wincap.has_try_enter_critical_section ()) if (wincap.has_try_enter_critical_section ())
InitializeCriticalSection(&criticalsection); InitializeCriticalSection (&criticalsection);
else else
{ {
win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); win32_obj_id = ::CreateMutex (&sec_none_nih, false, NULL);
if (!win32_obj_id) 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 DETECT_BAD_APPS
if (condwaits) 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 #else
condwaits = 0; condwaits = 0;
#endif #endif
@ -752,7 +752,7 @@ pthread_mutexattr::~pthread_mutexattr ()
semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MAGIC) 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); NULL);
if (!this->win32_obj_id) if (!this->win32_obj_id)
magic = 0; magic = 0;
@ -809,13 +809,13 @@ semaphore::Wait ()
void void
semaphore::fixup_after_fork () 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) 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. */ /* 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) 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): verifyable_object::verifyable_object (long verifyer):
@ -891,7 +891,7 @@ thread_init_wrapper (void *_arg)
if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent)) if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
system_printf ("local storage for thread couldn't be set"); 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); TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
#ifdef _CYG_THREAD_FAILSAFE #ifdef _CYG_THREAD_FAILSAFE
@ -919,6 +919,7 @@ int
__pthread_create (pthread_t *thread, const pthread_attr_t *attr, __pthread_create (pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg) void *(*start_routine) (void *), void *arg)
{ {
DECLARE_TLS_STORAGE;
if (attr && verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT) if (attr && verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT)
return EINVAL; return EINVAL;
@ -1293,7 +1294,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi
if (prepcb) if (prepcb)
{ {
prepcb->cb = prepare; 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) if (parentcb)
{ {
@ -1302,7 +1303,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi
while (*t) while (*t)
t = &(*t)->next; t = &(*t)->next;
/*t = pointer to last next in the list */ /*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) if (childcb)
{ {
@ -1311,7 +1312,7 @@ __pthread_atfork (void (*prepare)(void), void (*parent)(void), void (*child)(voi
while (*t) while (*t)
t = &(*t)->next; t = &(*t)->next;
/*t = pointer to last next in the list */ /*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; 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 the cond variable is blocked, then the above timer test maybe wrong. *shrug**/
if (pthread_mutex_lock (&(*cond)->cond_access)) 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)->waiting)
if ((*cond)->mutex && ((*cond)->mutex != (*themutex))) if ((*cond)->mutex && ((*cond)->mutex != (*themutex)))
{ {
if (pthread_mutex_unlock (&(*cond)->cond_access)) 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; return EINVAL;
} }
InterlockedIncrement (&((*cond)->waiting)); InterlockedIncrement (&((*cond)->waiting));
@ -1773,7 +1774,7 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
(*cond)->mutex = (*themutex); (*cond)->mutex = (*themutex);
InterlockedIncrement (&((*themutex)->condwaits)); InterlockedIncrement (&((*themutex)->condwaits));
if (pthread_mutex_unlock (&(*cond)->cond_access)) 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); rv = (*cond)->TimedWait (waitlength);
/* this may allow a race on the mutex acquisition and waits.. /* this may allow a race on the mutex acquisition and waits..
* But doing this within the cond access mutex creates a different race * 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) if (last == true)
(*cond)->mutex = NULL; (*cond)->mutex = NULL;
if (pthread_mutex_lock (&(*cond)->cond_access)) 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)); InterlockedDecrement (&((*themutex)->condwaits));
if (pthread_mutex_unlock (&(*cond)->cond_access)) 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; return rv;
} }
@ -1797,11 +1798,11 @@ extern "C" int
pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) const struct timespec *abstime)
{ {
if (check_valid_pointer(abstime)) if (check_valid_pointer (abstime))
return EINVAL; return EINVAL;
struct timeb currSysTime; struct timeb currSysTime;
long waitlength; long waitlength;
ftime(&currSysTime); ftime (&currSysTime);
waitlength = (abstime->tv_sec - currSysTime.time) *1000; waitlength = (abstime->tv_sec - currSysTime.time) *1000;
if (waitlength < 0) if (waitlength < 0)
return ETIMEDOUT; return ETIMEDOUT;
@ -1945,7 +1946,7 @@ int
__pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, __pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
int *prioceiling) int *prioceiling)
{ {
pthread_mutex_t *themutex=(pthread_mutex_t *) mutex; pthread_mutex_t *themutex = (pthread_mutex_t *) mutex;
if (*mutex == PTHREAD_MUTEX_INITIALIZER) if (*mutex == PTHREAD_MUTEX_INITIALIZER)
__pthread_mutex_init ((pthread_mutex_t *) mutex, NULL); __pthread_mutex_init ((pthread_mutex_t *) mutex, NULL);
if (verifyable_object_isvalid (themutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) if (verifyable_object_isvalid (themutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)

84
winsup/cygwin/winbase.h Normal file
View 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*/

View File

@ -150,8 +150,7 @@ window_terminate ()
SendMessage (ourhwnd, WM_DESTROY, 0, 0); SendMessage (ourhwnd, WM_DESTROY, 0, 0);
} }
extern "C" extern "C" int
int
setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
{ {
UINT elapse; UINT elapse;
@ -195,8 +194,7 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
return 0; return 0;
} }
extern "C" extern "C" int
int
getitimer (int which, struct itimerval *value) getitimer (int which, struct itimerval *value)
{ {
UINT elapse, val; UINT elapse, val;
@ -221,27 +219,41 @@ getitimer (int which, struct itimerval *value)
elapse = GetTickCount () - start_time; elapse = GetTickCount () - start_time;
val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000;
val -= elapse; val -= elapse;
value->it_value.tv_sec = val/1000; value->it_value.tv_sec = val / 1000;
value->it_value.tv_usec = val%1000; value->it_value.tv_usec = val % 1000;
return 0; return 0;
} }
extern "C" extern "C" unsigned int
unsigned int
alarm (unsigned int seconds) alarm (unsigned int seconds)
{ {
int ret; int ret;
struct itimerval newt, oldt; struct itimerval newt, oldt;
getitimer (ITIMER_REAL, &oldt);
newt.it_value.tv_sec = seconds; newt.it_value.tv_sec = seconds;
newt.it_value.tv_usec = 0; newt.it_value.tv_usec = 0;
newt.it_interval.tv_sec = 0; newt.it_interval.tv_sec = 0;
newt.it_interval.tv_usec = 0; newt.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &newt, NULL); setitimer (ITIMER_REAL, &newt, &oldt);
ret = oldt.it_value.tv_sec; ret = oldt.it_value.tv_sec;
if (ret == 0 && oldt.it_value.tv_usec) if (ret == 0 && oldt.it_value.tv_usec)
ret = 1; ret = 1;
return ret; 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;
}

View File

@ -272,4 +272,11 @@ extern HMODULE cygwin_hmodule;
#define winsock_active (wsadata.wVersion < 512) #define winsock_active (wsadata.wVersion < 512)
extern struct WSAData wsadata; 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 */ #endif /* defined __cplusplus */