This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Revert "cygserver: Revamp thread sleep handling"


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c5ca43f35913a7d0b2ec786e27c629d1c5ed0715

commit c5ca43f35913a7d0b2ec786e27c629d1c5ed0715
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Tue Jun 20 13:09:07 2017 +0200

    Revert "cygserver: Revamp thread sleep handling"
    
    This reverts commit b80b2c011936f7f075b76b6e59f9e8a5ec49caa1.

Diff:
---
 winsup/cygserver/bsd_mutex.cc | 144 ++++++++++++++++++++++++++++--------------
 winsup/cygserver/bsd_mutex.h  |  14 ++--
 winsup/cygserver/sysv_msg.cc  |   3 -
 winsup/cygserver/sysv_sem.cc  |   3 -
 winsup/cygserver/sysv_shm.cc  |   6 --
 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]