* 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:
parent
a6d66c1399
commit
4d029f3940
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user