Revert "cygserver: Revamp thread sleep handling"
This reverts commit b80b2c0119.
			
			
This commit is contained in:
		| @@ -13,11 +13,9 @@ details. */ | |||||||
| #include <sys/smallprint.h> | #include <sys/smallprint.h> | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <sys/shm.h> |  | ||||||
| #include <sys/msg.h> | #include <sys/msg.h> | ||||||
| #include <sys/sem.h> | #include <sys/sem.h> | ||||||
|  |  | ||||||
| #include "bsd_helper.h" |  | ||||||
| #include "process.h" | #include "process.h" | ||||||
| #include "cygserver_ipc.h" | #include "cygserver_ipc.h" | ||||||
|  |  | ||||||
| @@ -174,91 +172,141 @@ class msleep_sync_array | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   CRITICAL_SECTION cs; |   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: | public: | ||||||
|  |  | ||||||
|   msleep_sync_array (int count) |   msleep_sync_array (int count) : cnt (0), max_cnt (count) | ||||||
|   { |   { | ||||||
|     InitializeCriticalSection (&cs); |     InitializeCriticalSection (&cs); | ||||||
|     wakeup_evt = (PHANDLE) calloc (count, sizeof (HANDLE)); |     if (!(a = new msleep_record[count])) | ||||||
|     if (!wakeup_evt) |  | ||||||
|       panic ("Allocating msleep records failed: %d", errno); |       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); |         EnterCriticalSection (&cs); | ||||||
| 	if (!wakeup_evt[idx]) | 	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); | 	    /* wakeup has been called, so sleep to wait until all | ||||||
| 	    if (!wakeup_evt[idx]) | 	       formerly waiting threads have left and retry. */ | ||||||
| 	      panic ("CreateSemaphore failed: %u", GetLastError ()); | 	    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; | 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 | void | ||||||
| msleep_init (void) | msleep_init (void) | ||||||
| { | { | ||||||
|  |   extern struct msginfo msginfo; | ||||||
|  |   extern struct seminfo seminfo; | ||||||
|  |  | ||||||
|   msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL); |   msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL); | ||||||
|   if (!msleep_glob_evt) |   if (!msleep_glob_evt) | ||||||
|     panic ("CreateEvent in msleep_init failed: %u", GetLastError ()); |     panic ("CreateEvent in msleep_init failed: %u", GetLastError ()); | ||||||
|   mni[SHM] = support_sharedmem ? shminfo.shmmni : 0; |   int32_t msgmni = support_msgqueues ? msginfo.msgmni : 0; | ||||||
|   mni[MSQ] = support_msgqueues ? msginfo.msgmni : 0; |   int32_t semmni = support_semaphores ? seminfo.semmni : 0; | ||||||
|   mni[SEM] = support_semaphores ? seminfo.semmni : 0; |   TUNABLE_INT_FETCH ("kern.ipc.msgmni", &msgmni); | ||||||
|   TUNABLE_INT_FETCH ("kern.ipc.shmmni", &mni[SHM]); |   TUNABLE_INT_FETCH ("kern.ipc.semmni", &semmni); | ||||||
|   TUNABLE_INT_FETCH ("kern.ipc.msgmni", &mni[MSQ]); |   debug ("Try allocating msgmni (%d) + semmni (%d) msleep records", | ||||||
|   TUNABLE_INT_FETCH ("kern.ipc.semmni", &mni[SEM]); |   	 msgmni, semmni); | ||||||
|   debug ("Allocating shmmni (%d) + msgmni (%d) + semmni (%d) msleep records", |   msleep_sync = new msleep_sync_array (msgmni + semmni); | ||||||
| 	 mni[SHM], mni[MSQ], mni[SEM]); |  | ||||||
|   msleep_sync = new msleep_sync_array (mni[SHM] + mni[MSQ] + mni[SEM]); |  | ||||||
|   if (!msleep_sync) |   if (!msleep_sync) | ||||||
|     panic ("Allocating msleep records in msleep_init failed: %d", errno); |     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 | 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) | 	const char *wmesg, int timo, struct thread *td) | ||||||
| { | { | ||||||
|   int ret = -1; |   int ret = -1; | ||||||
|  |  | ||||||
|   HANDLE evt = msleep_sync->enter (off[type] + ident); |   HANDLE evt = msleep_sync->enter (ident); | ||||||
|  |  | ||||||
|   if (mtx) |   if (mtx) | ||||||
|     mtx_unlock (mtx); |     mtx_unlock (mtx); | ||||||
|  |  | ||||||
|   int old_priority = set_priority (priority); |   int old_priority = set_priority (priority); | ||||||
|  |  | ||||||
|   HANDLE obj[4] = |   HANDLE obj[4] = | ||||||
|     { |     { | ||||||
|       evt, |       evt, | ||||||
| @@ -271,7 +319,6 @@ _sleep (ipc_type type, int ident, struct mtx *mtx, int priority, | |||||||
|   int obj_cnt = 3; |   int obj_cnt = 3; | ||||||
|   if ((priority & PCATCH) && obj[3]) |   if ((priority & PCATCH) && obj[3]) | ||||||
|     obj_cnt = 4; |     obj_cnt = 4; | ||||||
|  |  | ||||||
|   switch (WaitForMultipleObjects (obj_cnt, obj, FALSE, timo ?: INFINITE)) |   switch (WaitForMultipleObjects (obj_cnt, obj, FALSE, timo ?: INFINITE)) | ||||||
|     { |     { | ||||||
|       case WAIT_OBJECT_0:	/* wakeup() has been called. */ |       case WAIT_OBJECT_0:	/* wakeup() has been called. */ | ||||||
| @@ -307,13 +354,12 @@ _sleep (ipc_type type, int ident, struct mtx *mtx, int priority, | |||||||
| 	break; | 	break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   msleep_sync->leave (ident); | ||||||
|  |  | ||||||
|   set_priority (old_priority); |   set_priority (old_priority); | ||||||
|  |  | ||||||
|   if (mtx && !(priority & PDROP)) |   if (mtx && !(priority & PDROP)) | ||||||
|     mtx_lock (mtx); |     mtx_lock (mtx); | ||||||
|  |  | ||||||
|   msleep_sync->leave (off[type] + ident); |  | ||||||
|  |  | ||||||
|   return ret; |   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. |  * Make all threads sleeping on the specified identifier runnable. | ||||||
|  */ |  */ | ||||||
| int | int | ||||||
| _wakeup (ipc_type type, int ident) | wakeup (void *ident) | ||||||
| { | { | ||||||
|   msleep_sync->wakeup (off[type] + ident); |   msleep_sync->wakeup (ident); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,12 +26,6 @@ struct mtx { | |||||||
|   unsigned long cnt; |   unsigned long cnt; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum ipc_type { |  | ||||||
|   SHM, |  | ||||||
|   MSQ, |  | ||||||
|   SEM |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* Some BSD kernel global mutex. */ | /* Some BSD kernel global mutex. */ | ||||||
| extern struct mtx Giant; | extern struct mtx Giant; | ||||||
|  |  | ||||||
| @@ -47,10 +41,10 @@ void _mtx_unlock (mtx *, const char *, int); | |||||||
| void mtx_destroy (mtx *); | void mtx_destroy (mtx *); | ||||||
|  |  | ||||||
| void msleep_init (void); | void msleep_init (void); | ||||||
| int _sleep (ipc_type, int, struct mtx *, int, const char *, int, struct thread *); | int _msleep (void *, 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 msleep(i,m,p,w,t) _msleep((i),(m),(p),(w),(t),(td)) | ||||||
| #define _tsleep(T,i,p,w,t)   _sleep((T),(i),NULL,(p),(w),(t),(td)) | #define tsleep(i,p,w,t)   _msleep((i),NULL,(p),(w),(t),(td)) | ||||||
| int _wakeup (ipc_type, int); | int wakeup (void *); | ||||||
| void wakeup_all (void); | void wakeup_all (void); | ||||||
|  |  | ||||||
| #endif /* _BSD_MUTEX_H */ | #endif /* _BSD_MUTEX_H */ | ||||||
|   | |||||||
| @@ -46,9 +46,6 @@ __FBSDID("$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/kern/sysv_msg.c,v 1.5 | |||||||
|  |  | ||||||
| #ifdef __CYGWIN__ | #ifdef __CYGWIN__ | ||||||
| #define MSG_DEBUG | #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__ */ | #endif /* __CYGWIN__ */ | ||||||
|  |  | ||||||
| #ifdef MSG_DEBUG | #ifdef MSG_DEBUG | ||||||
|   | |||||||
| @@ -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 semctl | ||||||
| #define __semctl_args semctl_args | #define __semctl_args semctl_args | ||||||
| #define SEM_DEBUG | #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__ */ | #endif /* __CYGWIN__ */ | ||||||
|  |  | ||||||
| #ifdef SEM_DEBUG | #ifdef SEM_DEBUG | ||||||
|   | |||||||
| @@ -59,12 +59,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_shm.c,v 1.89 2003/11/07 04 | |||||||
| #include "process.h" | #include "process.h" | ||||||
| #include "cygserver_ipc.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__ | #ifdef __CYGWIN__ | ||||||
| #ifndef PAGE_SIZE | #ifndef PAGE_SIZE | ||||||
| #define PAGE_SIZE (getpagesize ()) | #define PAGE_SIZE (getpagesize ()) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user