* cygthread.h: Change 'avail' cygthread element to 'inuse' throughout.

* cygthread.cc: Ditto.
(cygthread::stub): Don't initialize already initialized events.
(cygthread::freerange): Don't create thread here.
(cygthread::cygthread): Create thread here.  Die if thread not created.
(cygthread::operator new): Simplify.  Just grab a thread structure from the
pool.  Don't try to start the thread.
(cygthread::terminate_thread): Don't close event handles.  Just reuse them.
Call MEM_RELEASE rather than MEM_DECOMMIT (from Joe Buehler).
This commit is contained in:
Christopher Faylor 2003-04-10 05:27:34 +00:00
parent 57efd527df
commit e5d6d53590
4 changed files with 58 additions and 55 deletions

View File

@ -1,3 +1,15 @@
2003-04-10 Christopher Faylor <cgf@redhat.com>
* cygthread.h: Change 'avail' cygthread element to 'inuse' throughout.
* cygthread.cc: Ditto.
(cygthread::stub): Don't initialize already initialized events.
(cygthread::freerange): Don't create thread here.
(cygthread::cygthread): Create thread here. Die if thread not created.
(cygthread::operator new): Simplify. Just grab a thread structure from
the pool. Don't try to start the thread.
(cygthread::terminate_thread): Don't close event handles. Just reuse
them. Call MEM_RELEASE rather than MEM_DECOMMIT (from Joe Buehler).
2003-04-08 Bob Cassels <bcassels@abinitio.com> 2003-04-08 Bob Cassels <bcassels@abinitio.com>
* fhandler_console.cc (fhandler_console::read) Handle certain key up * fhandler_console.cc (fhandler_console::read) Handle certain key up

View File

@ -40,11 +40,21 @@ cygthread::stub (VOID *arg)
cygthread *info = (cygthread *) arg; cygthread *info = (cygthread *) arg;
if (info->arg == cygself) if (info->arg == cygself)
{
if (info->ev)
{
CloseHandle (info->ev);
CloseHandle (info->thread_sync);
}
info->ev = info->thread_sync = info->stack_ptr = NULL; info->ev = info->thread_sync = info->stack_ptr = NULL;
}
else else
{
if (!info->ev)
{ {
info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
}
info->stack_ptr = &arg; info->stack_ptr = &arg;
} }
while (1) while (1)
@ -118,8 +128,6 @@ cygthread::freerange ()
{ {
cygthread *self = (cygthread *) calloc (1, sizeof (*self)); cygthread *self = (cygthread *) calloc (1, sizeof (*self));
self->is_freerange = true; self->is_freerange = true;
self->h = CreateThread (&sec_none_nih, 0, cygthread::simplestub, self,
CREATE_SUSPENDED, &self->id);
self->ev = self->h; self->ev = self->h;
return self; return self;
} }
@ -127,31 +135,19 @@ cygthread::freerange ()
void * cygthread::operator void * cygthread::operator
new (size_t) new (size_t)
{ {
LONG is_avail;
cygthread *info; cygthread *info;
/* Search the threads array for an empty slot to use */ /* Search the threads array for an empty slot to use */
for (info = threads; info < threads + NTHREADS; info++) for (info = threads; info < threads + NTHREADS; info++)
if ((is_avail = InterlockedExchange (&info->avail, -1)) < 0) if (!InterlockedExchange (&info->inuse, 1))
/* in use */;
else if (is_avail > 0)
{ {
/* available */ /* available */
#ifdef DEBUGGING #ifdef DEBUGGING
if (info->__name) if (info->__name)
api_fatal ("name not NULL? id %p, i %d", info->id, info - threads); api_fatal ("name not NULL? id %p, i %d", info->id, info - threads);
if (!info->h)
api_fatal ("h not set? id %p, i %d", info->id, info - threads);
#endif #endif
goto out; goto out;
} }
else
{
/* Uninitialized. Available as soon as thread is created */
info->h = CreateThread (&sec_none_nih, 0, cygthread::stub, info,
CREATE_SUSPENDED, &info->id);
goto out;
}
#ifdef DEBUGGING #ifdef DEBUGGING
char buf[1024]; char buf[1024];
@ -166,27 +162,25 @@ out:
} }
cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param,
const char *name): func (start), arg (param) const char *name): __name (name),
func (start), arg (param)
{ {
#ifdef DEBUGGGING
if (!__name)
api_fatal ("name should never be NULL");
#endif
thread_printf ("name %s, id %p", name, id); thread_printf ("name %s, id %p", name, id);
while (!h) if (h)
#ifndef DEBUGGING
low_priority_sleep (0);
#else
{ {
system_printf ("waiting for %s<%p> to become active", __name, h); while (!thread_sync)
low_priority_sleep (0); low_priority_sleep (0);
}
#endif
__name = name;
if (!thread_sync)
ResumeThread (h);
else
SetEvent (thread_sync); SetEvent (thread_sync);
thread_printf ("activated thread_sync %p", thread_sync);
}
else
{
h = CreateThread (&sec_none_nih, 0, is_freerange ? simplestub : stub,
this, 0, &id);
if (!h)
api_fatal ("thread handle not set - %p<%p>, %E", h, id);
thread_printf ("created thread %p", h);
}
} }
/* Return the symbolic name of the current thread for debugging. /* Return the symbolic name of the current thread for debugging.
@ -241,29 +235,26 @@ void
cygthread::terminate_thread () cygthread::terminate_thread ()
{ {
if (!is_freerange) if (!is_freerange)
SetEvent (*this); {
ResetEvent (*this);
ResetEvent (thread_sync);
}
(void) TerminateThread (h, 0); (void) TerminateThread (h, 0);
(void) WaitForSingleObject (h, INFINITE); (void) WaitForSingleObject (h, INFINITE);
CloseHandle (h);
MEMORY_BASIC_INFORMATION m; MEMORY_BASIC_INFORMATION m;
memset (&m, 0, sizeof (m)); memset (&m, 0, sizeof (m));
(void) VirtualQuery (stack_ptr, &m, sizeof m); (void) VirtualQuery (stack_ptr, &m, sizeof m);
if (m.RegionSize) if (m.RegionSize)
(void) VirtualFree (m.AllocationBase, m.RegionSize, MEM_DECOMMIT); (void) VirtualFree (m.AllocationBase, 0, MEM_RELEASE);
if (is_freerange) h = NULL;
is_freerange = false;
else
{
CloseHandle (ev);
CloseHandle (thread_sync);
}
CloseHandle (h);
thread_sync = ev = h = NULL;
__name = NULL; __name = NULL;
id = 0; stack_ptr = NULL;
(void) InterlockedExchange (&avail, 0); /* No longer initialized */ (void) InterlockedExchange (&inuse, 0); /* No longer in use */
} }
/* Detach the cygthread from the current thread. Note that the /* Detach the cygthread from the current thread. Note that the
@ -274,8 +265,8 @@ bool
cygthread::detach (HANDLE sigwait) cygthread::detach (HANDLE sigwait)
{ {
bool signalled = false; bool signalled = false;
if (avail >= 0) if (!inuse)
system_printf ("called detach but avail %d, thread %d?", avail, id); system_printf ("called detach but inuse %d, thread %p?", inuse, id);
else else
{ {
DWORD res; DWORD res;
@ -317,8 +308,8 @@ cygthread::detach (HANDLE sigwait)
else else
{ {
ResetEvent (*this); ResetEvent (*this);
/* Mark the thread as available by setting avail to positive value */ /* Mark the thread as available by setting inuse to zero */
(void) InterlockedExchange (&avail, 1); (void) InterlockedExchange (&inuse, 0);
} }
} }
return signalled; return signalled;

View File

@ -8,7 +8,7 @@ details. */
class cygthread class cygthread
{ {
LONG avail; /* 1: available, 0: ininitialized, -1: not available */ LONG inuse;
DWORD id; DWORD id;
HANDLE h; HANDLE h;
HANDLE ev; HANDLE ev;

View File

@ -55,7 +55,7 @@ class pwdgrp
i = (unsigned int) x; i = (unsigned int) x;
return res; return res;
} }
bool next_num (int& i) inline bool next_num (int& i)
{ {
unsigned long x; unsigned long x;
bool res = next_num (x); bool res = next_num (x);
@ -67,7 +67,7 @@ public:
int curr_lines; int curr_lines;
void load (const char *); void load (const char *);
void refresh (bool check) inline void refresh (bool check)
{ {
if (!check && initialized) if (!check && initialized)
return; return;
@ -77,14 +77,14 @@ public:
pglock->release (); pglock->release ();
} }
pwdgrp (passwd *&pbuf) : inline pwdgrp (passwd *&pbuf) :
pwdgrp_buf_elem_size (sizeof (*pbuf)), passwd_buf (&pbuf) pwdgrp_buf_elem_size (sizeof (*pbuf)), passwd_buf (&pbuf)
{ {
read = &pwdgrp::read_passwd; read = &pwdgrp::read_passwd;
parse = &pwdgrp::parse_passwd; parse = &pwdgrp::parse_passwd;
new_muto (pglock); new_muto (pglock);
} }
pwdgrp (__group32 *&gbuf) : inline pwdgrp (__group32 *&gbuf) :
pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf) pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf)
{ {
read = &pwdgrp::read_group; read = &pwdgrp::read_group;