aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-03-17 01:14:58 +0000
committerChristopher Faylor <me@cgf.cx>2001-03-17 01:14:58 +0000
commit5ccbf4b6998788d90b317b2c27f93efc2eca1516 (patch)
tree464959f9a7111b7931514d9129c292f5cb5a231d
parent8308bf58f71b692b85944f5ec8a58168779a142c (diff)
downloadnewlib-5ccbf4b6998788d90b317b2c27f93efc2eca1516.zip
newlib-5ccbf4b6998788d90b317b2c27f93efc2eca1516.tar.gz
newlib-5ccbf4b6998788d90b317b2c27f93efc2eca1516.tar.bz2
* cygwin.din: Export the new functions.
* pthread.cc (pthread_cond_*): Add wrapper functions that call __pthread_cond* functions. * thread.cc (__pthread_cond_*): Implement the pthread_cond* functions. * thread.h: Add new class entries and prototypes for __pthread_cond* functions. * include/pthread.h: user land header prototypes for pthread_cond* functions and related defines.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/cygwin.din10
-rw-r--r--winsup/cygwin/include/pthread.h33
-rw-r--r--winsup/cygwin/pthread.cc61
-rw-r--r--winsup/cygwin/thread.cc268
-rw-r--r--winsup/cygwin/thread.h28
6 files changed, 410 insertions, 1 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b34736d..a42758e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+aturday Mar 17 01:19 2001 Robert Collins rbtcollins@hotmail.com
+
+ * cygwin.din: Export the new functions.
+ * pthread.cc (pthread_cond_*): Add wrapper functions that call
+ __pthread_cond* functions.
+ * thread.cc (__pthread_cond_*): Implement the pthread_cond* functions.
+ * thread.h: Add new class entries and prototypes for __pthread_cond*
+ functions.
+ * include/pthread.h: user land header prototypes for pthread_cond*
+ functions and related defines.
+
Wed Mar 14 16:30:00 2001 Corinna Vinschen <corinna@vinschen.de>
* environ.cc (parse_options): Use strtok_r instead of strtok.
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index fb6364c..a5ff772 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -1099,6 +1099,16 @@ cygwin32_internal = cygwin_internal
@PTH_ALLOW@pthread_mutex_trylock
@PTH_ALLOW@pthread_mutex_unlock
@PTH_ALLOW@pthread_mutex_destroy
+@PTH_ALLOW@pthread_cond_init
+@PTH_ALLOW@pthread_cond_destroy
+@PTH_ALLOW@pthread_cond_broadcast
+@PTH_ALLOW@pthread_cond_signal
+@PTH_ALLOW@pthread_cond_wait
+@PTH_ALLOW@pthread_cond_timedwait
+@PTH_ALLOW@pthread_condattr_init
+@PTH_ALLOW@pthread_condattr_destroy
+@PTH_ALLOW@pthread_condattr_getpshared
+@PTH_ALLOW@pthread_condattr_setpshared
@PTH_ALLOW@sem_init
@PTH_ALLOW@sem_destroy
@PTH_ALLOW@sem_wait
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 90bf5c2..1a96e72 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -23,6 +23,16 @@ extern "C"
#define TFD(n) void*(*n)(void*)
+/* Defines. (These are correctly defined here as per
+ http://www.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html */
+
+/* FIXME: this should allocate a new cond variable, and return the value that
+ would normally be written to the passed parameter of pthread_cond_init(lvalue, NULL); */
+// #define PTHREAD_COND_INITIALIZER 0
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
typedef int pthread_t;
typedef int pthread_mutex_t;
typedef int sem_t;
@@ -43,6 +53,15 @@ typedef struct pthread_mutexattr
}
pthread_mutexattr_t;
+typedef struct pthread_condattr
+ {
+ int shared;
+ int valid;
+ }
+pthread_condattr_t;
+
+typedef int pthread_cond_t;
+
/* ThreadCreation */
int pthread_create (pthread_t * thread, const pthread_attr_t * attr, TFD (function), void *arg);
int pthread_attr_init (pthread_attr_t * attr);
@@ -50,6 +69,20 @@ int pthread_attr_destroy (pthread_attr_t * attr);
int pthread_attr_setstacksize (pthread_attr_t * attr, size_t size);
int pthread_attr_getstacksize (pthread_attr_t * attr, size_t * size);
+/* Condition variables */
+int pthread_cond_broadcast(pthread_cond_t *);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
+int pthread_cond_signal(pthread_cond_t *);
+int pthread_cond_timedwait(pthread_cond_t *,
+ pthread_mutex_t *, const struct timespec *);
+int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int pthread_condattr_destroy(pthread_condattr_t *);
+int pthread_condattr_getpshared(const pthread_condattr_t *, int *);
+int pthread_condattr_init(pthread_condattr_t *);
+int pthread_condattr_setpshared(pthread_condattr_t *, int);
+
+
/* Thread Control */
int pthread_detach (pthread_t thread);
int pthread_join (pthread_t thread, void **value_ptr);
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index 82200e4..1cbec26 100644
--- a/winsup/cygwin/pthread.cc
+++ b/winsup/cygwin/pthread.cc
@@ -171,6 +171,67 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)
return __pthread_mutex_destroy (mutex);
}
+/* Synchronisation */
+
+int
+pthread_cond_destroy(pthread_cond_t *cond)
+{
+ return __pthread_cond_destroy (cond);
+}
+
+int
+pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ return __pthread_cond_init (cond, attr);
+}
+
+int
+pthread_cond_signal(pthread_cond_t *cond)
+{
+ return __pthread_cond_signal (cond);
+}
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ return __pthread_cond_broadcast (cond);
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t *cond,
+ pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+ return __pthread_cond_timedwait (cond, mutex, abstime);
+}
+
+int
+pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ return __pthread_cond_wait (cond, mutex);
+}
+
+int
+pthread_condattr_init(pthread_condattr_t *condattr)
+{
+ return __pthread_condattr_init (condattr);
+}
+
+int
+pthread_condattr_destroy(pthread_condattr_t *condattr)
+{
+ return __pthread_condattr_destroy (condattr);
+}
+
+int
+pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
+{
+ return __pthread_condattr_getpshared (attr, pshared);
+}
+
+int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
+{
+ return __pthread_condattr_setpshared (attr, pshared);
+}
+
/* Semaphores */
int
sem_init (sem_t * sem, int pshared, unsigned int value)
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index d34906d..e2d751b 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -63,6 +63,13 @@ extern int threadsafe;
if (!item) return EINVAL; \
CHECKHANDLE (EINVAL, 0);
+#define GETCOND(n) \
+ SetResourceLock (LOCK_COND_LIST, READ_LOCK, n); \
+ CondItem *item=user_data->threadinterface->GetCond (cond); \
+ ReleaseResourceLock (LOCK_COND_LIST, READ_LOCK, n); \
+ if (!item) return EINVAL; \
+ CHECKHANDLE (EINVAL, 0);
+
#define CHECKITEM(rn, rm, fn) \
if (!item) { \
ReleaseResourceLock (rn, rm, fn); \
@@ -387,6 +394,13 @@ MTinterface::GetSemaphore (sem_t * sp)
return (SemaphoreItem *) Find (sp, &CmpPthreadObj, index, &semalist);
}
+CondItem *
+MTinterface::GetCond (pthread_cond_t * mp)
+{
+ AssertResourceOwner (LOCK_COND_LIST, READ_LOCK);
+ int index = 0;
+ return (CondItem *) Find (mp, &CmpPthreadObj, index, &condlist);
+}
void
MTitem::Destroy ()
@@ -455,6 +469,78 @@ SemaphoreItem::TryWait ()
return WaitForSingleObject (win32_obj_id, 0);
}
+/* Condition Items */
+CondItem *
+MTinterface::CreateCond (pthread_cond_t * cond, const pthread_condattr_t * attr)
+{
+ AssertResourceOwner (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK);
+
+ int i = FindNextUnused (&condlist);
+
+ CondItem *item = (CondItem *) GetItem (i, &condlist);
+ if (!item)
+ item = (CondItem *) SetItem (i, new CondItem (), &condlist);
+ if (!item)
+ system_printf ("cond creation failed");
+ item->used = true;
+ item->shared = attr->shared;
+ item->mutexitem=NULL;
+ item->waiting=0;
+
+ item->win32_obj_id = ::CreateEvent (&sec_none_nih,
+ false, /* auto signal reset - which I think is pthreads like ? */
+ false, /* start non signaled */
+ NULL /* no name */ );
+
+
+ CHECKHANDLE (NULL, 1);
+
+ *cond = (pthread_cond_t) item->win32_obj_id;
+
+ return item;
+}
+
+
+int
+CondItem::Signal ()
+{
+ return !PulseEvent(win32_obj_id);
+}
+
+int
+CondItem::Wait ()
+{
+ DWORD rv = SignalObjectAndWait (mutexitem->win32_obj_id, win32_obj_id, INFINITE, false);
+ switch (rv) {
+ case WAIT_FAILED: return 0; /* POSIX doesn't allow errors after we modify the mutex state */
+ case WAIT_OBJECT_0: return 0; /* we have been signaled */
+ default: return 0;
+ }
+}
+
+int
+CondItem::TimedWait (DWORD dwMilliseconds)
+{
+ DWORD rv = SignalObjectAndWait (mutexitem->win32_obj_id, win32_obj_id, dwMilliseconds, false);
+ switch (rv) {
+ case WAIT_FAILED: return 0; /* POSIX doesn't allow errors after we modify the mutex state */
+ case WAIT_ABANDONED: return ETIMEDOUT;
+ case WAIT_OBJECT_0: return 0; /* we have been signaled */
+ default: return 0;
+ }
+}
+
+int
+CondItem::BroadCast ()
+{
+ if (!mutexitem)
+ return 0;
+ PulseEvent(win32_obj_id);
+ while (InterlockedDecrement(&waiting)!=0)
+ PulseEvent(win32_obj_id);
+ mutexitem=NULL;
+ return 0;
+}
////////////////////////// Pthreads
@@ -678,6 +764,147 @@ __pthread_getspecific (pthread_key_t */*key*/)
NOT_IMP ("_p_key_getsp\n");
}
+/* Thread synchronisation */
+
+int
+__pthread_cond_destroy(pthread_cond_t *cond)
+{
+ SetResourceLock (LOCK_COND_LIST, READ_LOCK | WRITE_LOCK, "__pthread_cond_destroy");
+
+ CondItem *item = MT_INTERFACE->GetCond (cond);
+
+ CHECKITEM (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+ item->Destroy ();
+
+ MT_INTERFACE->ReleaseItem (item);
+
+ ReleaseResourceLock (LOCK_COND_LIST, READ_LOCK | WRITE_LOCK, "__pthread_cond_destroy")
+;
+ return 0;
+}
+
+int
+__pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ if (attr && (attr->valid != 0xf341))
+ return EINVAL;
+ SetResourceLock (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+ CondItem *item = MT_INTERFACE->CreateCond (cond, attr);
+
+ CHECKITEM (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+
+ ReleaseResourceLock (LOCK_COND_LIST, WRITE_LOCK | READ_LOCK, "__pthread_cond_init");
+ return 0;
+
+}
+
+int __pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ GETCOND("_pthread_cond_lock");
+
+ item->BroadCast();
+
+ return 0;
+}
+
+int __pthread_cond_signal(pthread_cond_t *cond)
+{
+ GETCOND("_pthread_cond_lock");
+
+ item->Signal();
+
+ return 0;
+}
+
+int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+ int rv;
+ if (!abstime)
+ return EINVAL;
+ SetResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+ MutexItem* mutexitem=user_data->threadinterface->GetMutex (mutex);
+ ReleaseResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+ if (!mutexitem) return EINVAL;
+ if (!mutexitem->HandleOke ())
+ {
+ return EINVAL;
+ }
+ GETCOND("_pthread_cond_lock");
+ if (item->mutexitem && (item->mutexitem != mutexitem))
+ return EINVAL;
+
+ item->mutexitem=mutexitem;
+ InterlockedIncrement(&item->waiting);
+ rv = item->TimedWait(abstime->tv_sec*1000);
+ mutexitem->Lock();
+ if (InterlockedDecrement(&item->waiting)==0)
+ item->mutexitem=NULL;
+
+ return rv;
+}
+
+int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ int rv;
+ SetResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+ MutexItem* mutexitem=user_data->threadinterface->GetMutex (mutex);
+ ReleaseResourceLock (LOCK_MUTEX_LIST, READ_LOCK, "_ptherad_mutex_lock");
+ if (!mutexitem) return EINVAL;
+ if (!mutexitem->HandleOke ())
+ {
+ return EINVAL;
+ }
+ GETCOND("_pthread_cond_lock");
+ if (item->mutexitem && (item->mutexitem != mutexitem))
+ return EINVAL;
+
+ item->mutexitem=mutexitem;
+ InterlockedIncrement(&item->waiting);
+ rv = item->Wait();
+ mutexitem->Lock();
+ if (InterlockedDecrement(&item->waiting)==0)
+ item->mutexitem=NULL;
+
+ return rv;
+}
+
+int
+__pthread_condattr_init (pthread_condattr_t * condattr)
+{
+ condattr->shared = 0;
+ condattr->valid = 0xf341; /* Roberts magic number */
+ return 0;
+}
+
+int
+__pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
+{
+ if (!attr || (attr->valid != 0xf341))
+ return EINVAL;
+ *pshared = attr->shared;
+ return 0;
+}
+
+int
+__pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
+{
+ if (!attr || (attr->valid != 0xf341) || (pshared <0) || (pshared > 1 ))
+ return EINVAL;
+ attr->shared = pshared;
+ return 0;
+}
+
+int
+__pthread_condattr_destroy (pthread_condattr_t * condattr)
+{
+ if (!condattr || (condattr->valid != 0xf341))
+ return EINVAL;
+ condattr->valid=0;
+ return 0;
+}
+
/* Thread signal */
int
__pthread_kill (pthread_t * thread, int sig)
@@ -693,7 +920,6 @@ __pthread_kill (pthread_t * thread, int sig)
// unlock myself
return rval;
-
}
int
@@ -956,6 +1182,46 @@ extern "C"
{
return -1;
}
+ int __pthread_cond_destroy(pthread_cond_t *)
+ {
+ return -1;
+ }
+ int __pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *)
+ {
+ return -1;
+ }
+ int __pthread_cond_signal(pthread_cond_t *)
+ {
+ return -1;
+ }
+ int __pthread_cond_broadcast(pthread_cond_t *)
+ {
+ return -1;
+ }
+ int __pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *)
+ {
+ return -1;
+ }
+ int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *)
+ {
+ return -1;
+ }
+ int __pthread_condattr_init (pthread_condattr_t *)
+ {
+ return -1;
+ }
+ int __pthread_condattr_destroy (pthread_condattr_t *)
+ {
+ return -1;
+ }
+ int __pthread_condattr_getpshared (pthread_condattr_t *, int *)
+ {
+ return -1;
+ }
+ int __pthread_condattr_setpshared (pthread_condattr_t *, int)
+ {
+ return -1;
+ }
int __sem_init (sem_t * sem, int pshared, unsigned int value)
{
return -1;
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 999bd5e..c2758c6 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -20,6 +20,7 @@ details. */
#define LOCK_THREAD_LIST 5
#define LOCK_MUTEX_LIST 6
#define LOCK_SEM_LIST 7
+#define LOCK_COND_LIST 8
#define WRITE_LOCK 1
#define READ_LOCK 2
@@ -190,6 +191,17 @@ public:
int TryWait ();
};
+class CondItem: public MTitem
+{
+public:
+ int shared;
+ LONG waiting;
+ MutexItem *mutexitem;
+ int Wait ();
+ int TimedWait (DWORD dwMilliseconds);
+ int BroadCast ();
+ int Signal ();
+};
typedef struct
{
@@ -226,6 +238,10 @@ public:
SemaphoreItem *CreateSemaphore (sem_t *, int, int);
SemaphoreItem *GetSemaphore (sem_t * t);
+ // Condition functions
+ CondItem *CreateCond (pthread_cond_t *, const pthread_condattr_t *);
+ CondItem *GetCond (pthread_cond_t *);
+
private:
// General Administration
MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *);
@@ -237,6 +253,7 @@ private:
MTList threadlist;
MTList mutexlist;
MTList semalist;
+ MTList condlist;
};
@@ -274,6 +291,17 @@ int __pthread_key_delete (pthread_key_t * key);
int __pthread_setspecific (pthread_key_t * key, const void *value);
void *__pthread_getspecific (pthread_key_t * key);
+/* Thead synchroniation */
+int __pthread_cond_destroy(pthread_cond_t *cond);
+int __pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
+int __pthread_cond_signal(pthread_cond_t *cond);
+int __pthread_cond_broadcast(pthread_cond_t *cond);
+int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
+int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int __pthread_condattr_init (pthread_condattr_t * condattr);
+int __pthread_condattr_destroy (pthread_condattr_t * condattr);
+int __pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared);
+int __pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared);
/* Thread signal */
int __pthread_kill (pthread_t * thread, int sig);