aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygserver
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2017-06-20 13:09:07 +0200
committerCorinna Vinschen <corinna@vinschen.de>2017-06-20 13:09:07 +0200
commitc5ca43f35913a7d0b2ec786e27c629d1c5ed0715 (patch)
tree0f65fc4d567b488cc264d08d1a07837ead2b1a33 /winsup/cygserver
parent185cd97d24150db8964754ae0cbb69102dd6cfdb (diff)
downloadnewlib-c5ca43f35913a7d0b2ec786e27c629d1c5ed0715.zip
newlib-c5ca43f35913a7d0b2ec786e27c629d1c5ed0715.tar.gz
newlib-c5ca43f35913a7d0b2ec786e27c629d1c5ed0715.tar.bz2
Revert "cygserver: Revamp thread sleep handling"
This reverts commit b80b2c011936f7f075b76b6e59f9e8a5ec49caa1.
Diffstat (limited to 'winsup/cygserver')
-rw-r--r--winsup/cygserver/bsd_mutex.cc144
-rw-r--r--winsup/cygserver/bsd_mutex.h14
-rw-r--r--winsup/cygserver/sysv_msg.cc3
-rw-r--r--winsup/cygserver/sysv_sem.cc3
-rw-r--r--winsup/cygserver/sysv_shm.cc6
5 files changed, 99 insertions, 71 deletions
diff --git a/winsup/cygserver/bsd_mutex.cc b/winsup/cygserver/bsd_mutex.cc
index 8bf0888..52531bc 100644
--- a/winsup/cygserver/bsd_mutex.cc
+++ b/winsup/cygserver/bsd_mutex.cc
@@ -13,11 +13,9 @@ details. */
#include <sys/smallprint.h>
#include <limits.h>
#include <stdlib.h>
-#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
-#include "bsd_helper.h"
#include "process.h"
#include "cygserver_ipc.h"
@@ -174,91 +172,141 @@ class msleep_sync_array
};
CRITICAL_SECTION cs;
- PHANDLE wakeup_evt;
+ long cnt;
+ long max_cnt;
+ struct msleep_record {
+ void *ident;
+ HANDLE wakeup_evt;
+ LONG threads;
+ } *a;
+
+ int find_ident (void *ident, msleep_action action)
+ {
+ int i;
+ for (i = 0; i < cnt; ++i)
+ if (a[i].ident == ident)
+ return i;
+ if (i >= max_cnt)
+ panic ("ident %x not found and run out of slots.", ident);
+ if (i >= cnt && action == MSLEEP_LEAVE)
+ panic ("ident %x not found (%d).", ident, action);
+ return i;
+ }
+
+ HANDLE first_entry (int i, void *ident)
+ {
+ debug ("New ident %x, index %d", ident, i);
+ a[i].ident = ident;
+ a[i].wakeup_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (!a[i].wakeup_evt)
+ panic ("CreateEvent failed: %u", GetLastError ());
+ debug ("i = %d, CreateEvent: %x", i, a[i].wakeup_evt);
+ a[i].threads = 1;
+ ++cnt;
+ return a[i].wakeup_evt;
+ }
+
+ HANDLE next_entry (int i)
+ {
+ if (a[i].ident && WaitForSingleObject (a[i].wakeup_evt, 0) != WAIT_OBJECT_0)
+ {
+ ++a[i].threads;
+ return a[i].wakeup_evt;
+ }
+ return NULL;
+ }
public:
- msleep_sync_array (int count)
+ msleep_sync_array (int count) : cnt (0), max_cnt (count)
{
InitializeCriticalSection (&cs);
- wakeup_evt = (PHANDLE) calloc (count, sizeof (HANDLE));
- if (!wakeup_evt)
+ if (!(a = new msleep_record[count]))
panic ("Allocating msleep records failed: %d", errno);
}
- ~msleep_sync_array () { free (wakeup_evt); }
+ ~msleep_sync_array () { delete a; }
- HANDLE enter (int idx)
+ HANDLE enter (void *ident)
{
- if (!wakeup_evt[idx])
+ HANDLE evt = NULL;
+ while (!evt)
{
- EnterCriticalSection (&cs);
- if (!wakeup_evt[idx])
+ EnterCriticalSection (&cs);
+ int i = find_ident (ident, MSLEEP_ENTER);
+ if (i >= cnt)
+ evt = first_entry (i, ident);
+ else if (!(evt = next_entry (i)))
{
- wakeup_evt[idx] = CreateSemaphore (NULL, 0, 1024, NULL);
- if (!wakeup_evt[idx])
- panic ("CreateSemaphore failed: %u", GetLastError ());
+ /* wakeup has been called, so sleep to wait until all
+ formerly waiting threads have left and retry. */
+ LeaveCriticalSection (&cs);
+ Sleep (1L);
}
- LeaveCriticalSection (&cs);
}
- return wakeup_evt[idx];
+ LeaveCriticalSection (&cs);
+ return evt;
}
- void leave (int idx)
+ void leave (void *ident)
{
- /* Placeholder */
+ EnterCriticalSection (&cs);
+ int i = find_ident (ident, MSLEEP_LEAVE);
+ if (--a[i].threads == 0)
+ {
+ debug ("i = %d, CloseEvent: %x", i, a[i].wakeup_evt);
+ CloseHandle (a[i].wakeup_evt);
+ a[i].ident = NULL;
+ --cnt;
+ if (i < cnt)
+ a[i] = a[cnt];
+ }
+ LeaveCriticalSection (&cs);
}
- void wakeup (int idx)
+ void wakeup (void *ident)
{
- ReleaseSemaphore (wakeup_evt[idx], 1, NULL);
+ EnterCriticalSection (&cs);
+ int i = find_ident (ident, MSLEEP_WAKEUP);
+ if (i < cnt && a[i].ident)
+ SetEvent (a[i].wakeup_evt);
+ LeaveCriticalSection (&cs);
}
};
static msleep_sync_array *msleep_sync;
-extern struct msginfo msginfo;
-extern struct seminfo seminfo;
-extern struct shminfo shminfo;
-int32_t mni[3];
-int32_t off[3];
-
void
msleep_init (void)
{
+ extern struct msginfo msginfo;
+ extern struct seminfo seminfo;
+
msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
if (!msleep_glob_evt)
panic ("CreateEvent in msleep_init failed: %u", GetLastError ());
- mni[SHM] = support_sharedmem ? shminfo.shmmni : 0;
- mni[MSQ] = support_msgqueues ? msginfo.msgmni : 0;
- mni[SEM] = support_semaphores ? seminfo.semmni : 0;
- TUNABLE_INT_FETCH ("kern.ipc.shmmni", &mni[SHM]);
- TUNABLE_INT_FETCH ("kern.ipc.msgmni", &mni[MSQ]);
- TUNABLE_INT_FETCH ("kern.ipc.semmni", &mni[SEM]);
- debug ("Allocating shmmni (%d) + msgmni (%d) + semmni (%d) msleep records",
- mni[SHM], mni[MSQ], mni[SEM]);
- msleep_sync = new msleep_sync_array (mni[SHM] + mni[MSQ] + mni[SEM]);
+ int32_t msgmni = support_msgqueues ? msginfo.msgmni : 0;
+ int32_t semmni = support_semaphores ? seminfo.semmni : 0;
+ TUNABLE_INT_FETCH ("kern.ipc.msgmni", &msgmni);
+ TUNABLE_INT_FETCH ("kern.ipc.semmni", &semmni);
+ debug ("Try allocating msgmni (%d) + semmni (%d) msleep records",
+ msgmni, semmni);
+ msleep_sync = new msleep_sync_array (msgmni + semmni);
if (!msleep_sync)
panic ("Allocating msleep records in msleep_init failed: %d", errno);
- /* Convert mni values to offsets. */
- off[SHM] = 0;
- off[MSQ] = mni[SHM];
- off[SEM] = mni[SHM] + mni[MSQ];
}
int
-_sleep (ipc_type type, int ident, struct mtx *mtx, int priority,
+_msleep (void *ident, struct mtx *mtx, int priority,
const char *wmesg, int timo, struct thread *td)
{
int ret = -1;
- HANDLE evt = msleep_sync->enter (off[type] + ident);
+ HANDLE evt = msleep_sync->enter (ident);
if (mtx)
mtx_unlock (mtx);
-
int old_priority = set_priority (priority);
-
HANDLE obj[4] =
{
evt,
@@ -271,7 +319,6 @@ _sleep (ipc_type type, int ident, struct mtx *mtx, int priority,
int obj_cnt = 3;
if ((priority & PCATCH) && obj[3])
obj_cnt = 4;
-
switch (WaitForMultipleObjects (obj_cnt, obj, FALSE, timo ?: INFINITE))
{
case WAIT_OBJECT_0: /* wakeup() has been called. */
@@ -307,13 +354,12 @@ _sleep (ipc_type type, int ident, struct mtx *mtx, int priority,
break;
}
+ msleep_sync->leave (ident);
+
set_priority (old_priority);
if (mtx && !(priority & PDROP))
mtx_lock (mtx);
-
- msleep_sync->leave (off[type] + ident);
-
return ret;
}
@@ -321,9 +367,9 @@ _sleep (ipc_type type, int ident, struct mtx *mtx, int priority,
* Make all threads sleeping on the specified identifier runnable.
*/
int
-_wakeup (ipc_type type, int ident)
+wakeup (void *ident)
{
- msleep_sync->wakeup (off[type] + ident);
+ msleep_sync->wakeup (ident);
return 0;
}
diff --git a/winsup/cygserver/bsd_mutex.h b/winsup/cygserver/bsd_mutex.h
index 9ac970b..ac33de4 100644
--- a/winsup/cygserver/bsd_mutex.h
+++ b/winsup/cygserver/bsd_mutex.h
@@ -26,12 +26,6 @@ struct mtx {
unsigned long cnt;
};
-enum ipc_type {
- SHM,
- MSQ,
- SEM
-};
-
/* Some BSD kernel global mutex. */
extern struct mtx Giant;
@@ -47,10 +41,10 @@ void _mtx_unlock (mtx *, const char *, int);
void mtx_destroy (mtx *);
void msleep_init (void);
-int _sleep (ipc_type, int, struct mtx *, int, const char *, int, struct thread *);
-#define _msleep(T,i,m,p,w,t) _sleep((T),(i),(m),(p),(w),(t),(td))
-#define _tsleep(T,i,p,w,t) _sleep((T),(i),NULL,(p),(w),(t),(td))
-int _wakeup (ipc_type, int);
+int _msleep (void *, struct mtx *, int, const char *, int, struct thread *);
+#define msleep(i,m,p,w,t) _msleep((i),(m),(p),(w),(t),(td))
+#define tsleep(i,p,w,t) _msleep((i),NULL,(p),(w),(t),(td))
+int wakeup (void *);
void wakeup_all (void);
#endif /* _BSD_MUTEX_H */
diff --git a/winsup/cygserver/sysv_msg.cc b/winsup/cygserver/sysv_msg.cc
index 87ac125..21b5086 100644
--- a/winsup/cygserver/sysv_msg.cc
+++ b/winsup/cygserver/sysv_msg.cc
@@ -46,9 +46,6 @@ __FBSDID("$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/kern/sysv_msg.c,v 1.5
#ifdef __CYGWIN__
#define MSG_DEBUG
-#define _mk_msgid(P) ((P) - msqids)
-#define msleep(P,m,p,w,t) _msleep(MSQ,_mk_msgid(P),(m),(p),(w),(t))
-#define wakeup(P) _wakeup(MSQ,_mk_msgid(P))
#endif /* __CYGWIN__ */
#ifdef MSG_DEBUG
diff --git a/winsup/cygserver/sysv_sem.cc b/winsup/cygserver/sysv_sem.cc
index 98ddbf3..349322c 100644
--- a/winsup/cygserver/sysv_sem.cc
+++ b/winsup/cygserver/sysv_sem.cc
@@ -43,9 +43,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_sem.c,v 1.70 2004/05/30 20
#define __semctl semctl
#define __semctl_args semctl_args
#define SEM_DEBUG
-#define _mk_semid(P) ((P) - sema)
-#define msleep(P,m,p,w,t) _msleep(SEM,_mk_semid(P),(m),(p),(w),(t))
-#define wakeup(P) _wakeup(SEM,_mk_semid(P))
#endif /* __CYGWIN__ */
#ifdef SEM_DEBUG
diff --git a/winsup/cygserver/sysv_shm.cc b/winsup/cygserver/sysv_shm.cc
index 05acc2e..4578c53 100644
--- a/winsup/cygserver/sysv_shm.cc
+++ b/winsup/cygserver/sysv_shm.cc
@@ -60,12 +60,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_shm.c,v 1.89 2003/11/07 04
#include "cygserver_ipc.h"
#ifdef __CYGWIN__
-#define _mk_shmid(P) ((P) - shmsegs)
-#define tsleep(P,p,w,t) _tsleep(SHM,_mk_shmid(P),(p),(w),(t))
-#define wakeup(P) _wakeup(SHM,_mk_shmid(P))
-#endif
-
-#ifdef __CYGWIN__
#ifndef PAGE_SIZE
#define PAGE_SIZE (getpagesize ())
#endif