diff --git a/winsup/cygserver/bsd_mutex.cc b/winsup/cygserver/bsd_mutex.cc index f21e4d7e9..b95692ba9 100644 --- a/winsup/cygserver/bsd_mutex.cc +++ b/winsup/cygserver/bsd_mutex.cc @@ -13,9 +13,11 @@ details. */ #include #include #include +#include #include #include +#include "bsd_helper.h" #include "process.h" #include "cygserver_ipc.h" @@ -172,141 +174,91 @@ class msleep_sync_array }; CRITICAL_SECTION cs; - 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; - } + PHANDLE wakeup_evt; public: - msleep_sync_array (int count) : cnt (0), max_cnt (count) + msleep_sync_array (int count) { InitializeCriticalSection (&cs); - if (!(a = new msleep_record[count])) + wakeup_evt = (PHANDLE) calloc (count, sizeof (HANDLE)); + if (!wakeup_evt) panic ("Allocating msleep records failed: %d", errno); } - ~msleep_sync_array () { delete a; } + ~msleep_sync_array () { free (wakeup_evt); } - HANDLE enter (void *ident) + HANDLE enter (int idx) { - HANDLE evt = NULL; - while (!evt) + 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))) + EnterCriticalSection (&cs); + if (!wakeup_evt[idx]) { - /* wakeup has been called, so sleep to wait until all - formerly waiting threads have left and retry. */ - LeaveCriticalSection (&cs); - Sleep (1L); + wakeup_evt[idx] = CreateSemaphore (NULL, 0, 1024, NULL); + if (!wakeup_evt[idx]) + panic ("CreateSemaphore failed: %u", GetLastError ()); } + LeaveCriticalSection (&cs); } - LeaveCriticalSection (&cs); - return evt; + return wakeup_evt[idx]; } - void leave (void *ident) + void leave (int idx) { - 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); + /* Placeholder */ } - void wakeup (void *ident) + void wakeup (int idx) { - EnterCriticalSection (&cs); - int i = find_ident (ident, MSLEEP_WAKEUP); - if (i < cnt && a[i].ident) - SetEvent (a[i].wakeup_evt); - LeaveCriticalSection (&cs); + ReleaseSemaphore (wakeup_evt[idx], 1, NULL); } }; 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 ()); - 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); + 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]); 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 -_msleep (void *ident, struct mtx *mtx, int priority, +_sleep (ipc_type type, int ident, struct mtx *mtx, int priority, const char *wmesg, int timo, struct thread *td) { int ret = -1; - HANDLE evt = msleep_sync->enter (ident); + HANDLE evt = msleep_sync->enter (off[type] + ident); if (mtx) mtx_unlock (mtx); + int old_priority = set_priority (priority); + HANDLE obj[4] = { evt, @@ -319,6 +271,7 @@ _msleep (void *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. */ @@ -354,12 +307,13 @@ _msleep (void *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; } @@ -367,9 +321,9 @@ _msleep (void *ident, struct mtx *mtx, int priority, * Make all threads sleeping on the specified identifier runnable. */ int -wakeup (void *ident) +_wakeup (ipc_type type, int ident) { - msleep_sync->wakeup (ident); + msleep_sync->wakeup (off[type] + ident); return 0; } diff --git a/winsup/cygserver/bsd_mutex.h b/winsup/cygserver/bsd_mutex.h index de38bcece..cb0cf22b9 100644 --- a/winsup/cygserver/bsd_mutex.h +++ b/winsup/cygserver/bsd_mutex.h @@ -26,6 +26,12 @@ struct mtx { unsigned long cnt; }; +enum ipc_type { + SHM, + MSQ, + SEM +}; + /* Some BSD kernel global mutex. */ extern struct mtx Giant; @@ -41,10 +47,10 @@ void _mtx_unlock (mtx *, const char *, int); void mtx_destroy (mtx *); void msleep_init (void); -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 *); +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); void wakeup_all (void); #endif /* _BSD_MUTEX_H */ diff --git a/winsup/cygserver/sysv_msg.cc b/winsup/cygserver/sysv_msg.cc index 9e90d05a9..b3a49900e 100644 --- a/winsup/cygserver/sysv_msg.cc +++ b/winsup/cygserver/sysv_msg.cc @@ -46,6 +46,9 @@ __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 349322c6d..98ddbf318 100644 --- a/winsup/cygserver/sysv_sem.cc +++ b/winsup/cygserver/sysv_sem.cc @@ -43,6 +43,9 @@ __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 4578c53a2..05acc2ee6 100644 --- a/winsup/cygserver/sysv_shm.cc +++ b/winsup/cygserver/sysv_shm.cc @@ -59,6 +59,12 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_shm.c,v 1.89 2003/11/07 04 #include "process.h" #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 ())