From e5d6d5359038c83580f8a239d7cf2b9c3a85559d Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 10 Apr 2003 05:27:34 +0000 Subject: [PATCH] * 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). --- winsup/cygwin/ChangeLog | 12 +++++ winsup/cygwin/cygthread.cc | 91 +++++++++++++++++--------------------- winsup/cygwin/cygthread.h | 2 +- winsup/cygwin/pwdgrp.h | 8 ++-- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6d4972be4..5be0f5593 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2003-04-10 Christopher Faylor + + * 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 * fhandler_console.cc (fhandler_console::read) Handle certain key up diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index bc6c8bc9e..1787c415c 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -40,11 +40,21 @@ cygthread::stub (VOID *arg) cygthread *info = (cygthread *) arg; if (info->arg == cygself) + { + if (info->ev) + { + CloseHandle (info->ev); + CloseHandle (info->thread_sync); + } info->ev = info->thread_sync = info->stack_ptr = NULL; + } else { - info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + if (!info->ev) + { + info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + } info->stack_ptr = &arg; } while (1) @@ -118,8 +128,6 @@ cygthread::freerange () { cygthread *self = (cygthread *) calloc (1, sizeof (*self)); self->is_freerange = true; - self->h = CreateThread (&sec_none_nih, 0, cygthread::simplestub, self, - CREATE_SUSPENDED, &self->id); self->ev = self->h; return self; } @@ -127,31 +135,19 @@ cygthread::freerange () void * cygthread::operator new (size_t) { - LONG is_avail; cygthread *info; /* Search the threads array for an empty slot to use */ for (info = threads; info < threads + NTHREADS; info++) - if ((is_avail = InterlockedExchange (&info->avail, -1)) < 0) - /* in use */; - else if (is_avail > 0) + if (!InterlockedExchange (&info->inuse, 1)) { /* available */ #ifdef DEBUGGING if (info->__name) 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 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 char buf[1024]; @@ -166,27 +162,25 @@ out: } 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); - while (!h) -#ifndef DEBUGGING - low_priority_sleep (0); -#else + if (h) { - system_printf ("waiting for %s<%p> to become active", __name, h); - low_priority_sleep (0); + while (!thread_sync) + low_priority_sleep (0); + SetEvent (thread_sync); + thread_printf ("activated thread_sync %p", thread_sync); } -#endif - __name = name; - if (!thread_sync) - ResumeThread (h); else - SetEvent (thread_sync); + { + 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. @@ -241,29 +235,26 @@ void cygthread::terminate_thread () { if (!is_freerange) - SetEvent (*this); + { + ResetEvent (*this); + ResetEvent (thread_sync); + } (void) TerminateThread (h, 0); (void) WaitForSingleObject (h, INFINITE); + CloseHandle (h); + MEMORY_BASIC_INFORMATION m; memset (&m, 0, sizeof (m)); (void) VirtualQuery (stack_ptr, &m, sizeof m); if (m.RegionSize) - (void) VirtualFree (m.AllocationBase, m.RegionSize, MEM_DECOMMIT); + (void) VirtualFree (m.AllocationBase, 0, MEM_RELEASE); - if (is_freerange) - is_freerange = false; - else - { - CloseHandle (ev); - CloseHandle (thread_sync); - } - CloseHandle (h); - thread_sync = ev = h = NULL; + h = NULL; __name = NULL; - id = 0; - (void) InterlockedExchange (&avail, 0); /* No longer initialized */ + stack_ptr = NULL; + (void) InterlockedExchange (&inuse, 0); /* No longer in use */ } /* Detach the cygthread from the current thread. Note that the @@ -274,8 +265,8 @@ bool cygthread::detach (HANDLE sigwait) { bool signalled = false; - if (avail >= 0) - system_printf ("called detach but avail %d, thread %d?", avail, id); + if (!inuse) + system_printf ("called detach but inuse %d, thread %p?", inuse, id); else { DWORD res; @@ -317,8 +308,8 @@ cygthread::detach (HANDLE sigwait) else { ResetEvent (*this); - /* Mark the thread as available by setting avail to positive value */ - (void) InterlockedExchange (&avail, 1); + /* Mark the thread as available by setting inuse to zero */ + (void) InterlockedExchange (&inuse, 0); } } return signalled; diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index 3226f2a02..7af3f3183 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -8,7 +8,7 @@ details. */ class cygthread { - LONG avail; /* 1: available, 0: ininitialized, -1: not available */ + LONG inuse; DWORD id; HANDLE h; HANDLE ev; diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h index aea340d50..2b1e350a1 100644 --- a/winsup/cygwin/pwdgrp.h +++ b/winsup/cygwin/pwdgrp.h @@ -55,7 +55,7 @@ class pwdgrp i = (unsigned int) x; return res; } - bool next_num (int& i) + inline bool next_num (int& i) { unsigned long x; bool res = next_num (x); @@ -67,7 +67,7 @@ public: int curr_lines; void load (const char *); - void refresh (bool check) + inline void refresh (bool check) { if (!check && initialized) return; @@ -77,14 +77,14 @@ public: pglock->release (); } - pwdgrp (passwd *&pbuf) : + inline pwdgrp (passwd *&pbuf) : pwdgrp_buf_elem_size (sizeof (*pbuf)), passwd_buf (&pbuf) { read = &pwdgrp::read_passwd; parse = &pwdgrp::parse_passwd; new_muto (pglock); } - pwdgrp (__group32 *&gbuf) : + inline pwdgrp (__group32 *&gbuf) : pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf) { read = &pwdgrp::read_group;