Revert "cygserver: Revamp thread sleep handling"
This reverts commit b80b2c011936f7f075b76b6e59f9e8a5ec49caa1.
This commit is contained in:
parent
185cd97d24
commit
c5ca43f359
@ -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 ())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user