]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygthread.h (cygthread::avail): Make LONG for easier use with Interlocked*
authorChristopher Faylor <me@cgf.cx>
Fri, 4 Apr 2003 18:52:11 +0000 (18:52 +0000)
committerChristopher Faylor <me@cgf.cx>
Fri, 4 Apr 2003 18:52:11 +0000 (18:52 +0000)
functions.
* cygthread.cc (cygthread::init): Eliminate unneeded muto.
(cygthread::operator new): Don't lock.  Instead change use of avail variable
into tri-state: available (1), not available (-1), uninitialized (0).
(cygthread::terminate_thread): Set avail to uninitialized.
(cygthread::detach): Eliminate local 'avail'.  Always set avail to 1 unless
signalled.
* cygthread.cc (cygthread::operator new): Be more defensive when messing with

winsup/cygwin/ChangeLog
winsup/cygwin/cygthread.cc
winsup/cygwin/cygthread.h

index 7de1780fec52e4cb9aaf68ed4cdf47ac5aec63e7..ba78f9b7f685a108cf644ef849ee16b325c55470 100644 (file)
@@ -1,6 +1,18 @@
 2003-04-04  Christopher Faylor  <cgf@redhat.com>
 
-       * cygthread.cc (operator new): Be more defensive when messing with
+       * cygthread.h (cygthread::avail): Make LONG for easier use with
+       Interlocked* functions.
+       * cygthread.cc (cygthread::init): Eliminate unneeded muto.
+       (cygthread::operator new): Don't lock.  Instead change use of avail
+       variable into tri-state: available (1), not available (-1),
+       uninitialized (0).
+       (cygthread::terminate_thread): Set avail to uninitialized.
+       (cygthread::detach): Eliminate local 'avail'.  Always set avail to 1
+       unless signalled.
+
+2003-04-04  Christopher Faylor  <cgf@redhat.com>
+
+       * cygthread.cc (cygthread::operator new): Be more defensive when messing with
        threads that are marked "unavailable".
 
 2003-04-03  Christopher Faylor  <cgf@redhat.com>
index f7df503aaf775320ac5e835f5f142a1d60b079a1..bc6c8bc9eafa84e2b2a91cc3ae51ef7d1705f988 100644 (file)
@@ -94,12 +94,10 @@ cygthread::simplestub (VOID *arg)
   ExitThread (0);
 }
 
-static NO_COPY muto *cygthread_protect;
 /* Start things going.  Called from dll_crt0_1. */
 void
 cygthread::init ()
 {
-  new_muto (cygthread_protect);
   main_thread_id = GetCurrentThreadId ();
 }
 
@@ -129,30 +127,27 @@ cygthread::freerange ()
 void * cygthread::operator
 new (size_t)
 {
-  DWORD id;
+  LONG is_avail;
   cygthread *info;
 
-  cygthread_protect->acquire ();
-
   /* Search the threads array for an empty slot to use */
   for (info = threads; info < threads + NTHREADS; info++)
-    if ((LONG) (id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, -1)) < 0)
-      /* being considered */;
-    else if (id > 0)
+    if ((is_avail = InterlockedExchange (&info->avail, -1)) < 0)
+      /* in use */;
+    else if (is_avail > 0)
       {
+       /* available */
 #ifdef DEBUGGING
        if (info->__name)
-         api_fatal ("name not NULL? id %p, i %d", 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", id, info - threads);
+         api_fatal ("h not set? id %p, i %d", info->id, info - threads);
 #endif
        goto out;
       }
-    else if (info->id)
-      InterlockedExchange ((LPLONG) &info->avail, 0);  /* Not available yet */
     else
       {
-       /* Available as soon as thread is created */
+       /* Uninitialized.  Available as soon as thread is created */
        info->h = CreateThread (&sec_none_nih, 0, cygthread::stub, info,
                                CREATE_SUSPENDED, &info->id);
        goto out;
@@ -160,15 +155,13 @@ new (size_t)
 
 #ifdef DEBUGGING
   char buf[1024];
-  if (!GetEnvironmentVariable ("CYGWIN_NOFREERANGE_NOCHECK", buf, sizeof (buf)))
+  if (!GetEnvironmentVariable ("CYGWIN_FREERANGE_NOCHECK", buf, sizeof (buf)))
     api_fatal ("Overflowed cygwin thread pool");
 #endif
 
   info = freerange (); /* exhausted thread pool */
 
 out:
-  InterlockedExchange ((LPLONG) &info->avail, 0);
-  cygthread_protect->release ();
   return info;
 }
 
@@ -270,21 +263,21 @@ cygthread::terminate_thread ()
   thread_sync = ev = h = NULL;
   __name = NULL;
   id = 0;
+  (void) InterlockedExchange (&avail, 0); /* No longer initialized */
 }
 
 /* Detach the cygthread from the current thread.  Note that the
    theory is that cygthreads are only associated with one thread.
-   So, there should be no problems with multiple threads doing waits
-   on the one cygthread. */
+   So, there should be never be multiple threads doing waits
+   on the same cygthread. */
 bool
 cygthread::detach (HANDLE sigwait)
 {
   bool signalled = false;
-  if (avail)
-    system_printf ("called detach on available thread %d?", avail);
+  if (avail >= 0)
+    system_printf ("called detach but avail %d, thread %d?", avail, id);
   else
     {
-      DWORD avail = id;
       DWORD res;
 
       if (!sigwait)
@@ -304,18 +297,17 @@ cygthread::detach (HANDLE sigwait)
            res = WaitForSingleObject (*this, INFINITE);
          else
            {
+             signalled = true;
              terminate_thread ();
              set_sig_errno (EINTR);    /* caller should be dealing with return
                                           values. */
-             avail = 0;
-             signalled = true;
            }
        }
 
       thread_printf ("%s returns %d, id %p", sigwait ? "WFMO" : "WFSO",
                     res, id);
 
-      if (!avail)
+      if (signalled)
        /* already handled */;
       else if (is_freerange)
        {
@@ -325,8 +317,8 @@ cygthread::detach (HANDLE sigwait)
       else
        {
          ResetEvent (*this);
-         /* Mark the thread as available by setting avail to non-zero */
-         (void) InterlockedExchange ((LPLONG) &this->avail, avail);
+         /* Mark the thread as available by setting avail to positive value */
+         (void) InterlockedExchange (&avail, 1);
        }
     }
   return signalled;
index b0c07af0a656171052990909ddf289212a7d28b8..3226f2a02e78b1659ff3b1eb054a3c38f880ef58 100644 (file)
@@ -8,7 +8,7 @@ details. */
 
 class cygthread
 {
-  DWORD avail;
+  LONG avail;  /* 1: available, 0: ininitialized, -1: not available */
   DWORD id;
   HANDLE h;
   HANDLE ev;
This page took 0.03993 seconds and 5 git commands to generate.