Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-08-09 23:58:53 +0400
committerChristopher Faylor <me@cgf.cx>2012-08-09 23:58:53 +0400
commit52d2371da52be037af8020220650645df497d90d (patch)
tree981b4d875ae69b48fc6dfd2451f72c82002f14cd
parentcc02df128665f400e911e1f67e9963e827962914 (diff)
* DevNotes: Add entry cgf-000014.
* cygheap.cc (tls_sentry): Move here, rename from 'sentry' in cygtls.cc (tls_sentry::lock): Ditto. (nthreads): Move from cygtls.cc (THREADLIST_CHUNK): Ditto. (cygheap_init): Call init_tls_list(). (init_cygheap::init_tls_list): Define new function. (init_cygheap::add_tls): Ditto. (init_cygheap::remove_tls): Ditto. (init_cygheap::find_tls): Ditto. Semi-resurrect from _cygtls::find_tls. * cygheap.h (init_cygheap::init_tls_list): Declare new function. (init_cygheap::add_tls): Ditto. (init_cygheap::remove_tls): Ditto. (init_cygheap::find_tls): Ditto. * cygtls.cc (sentry): Delete. (sentry::lock): Ditto. (nthreads): Ditto. (THREADLIST_CHUNK): Ditto. (_cygtls::init): Delete definition. (_cygtls::init_thread): Call cygheap->add_tls() to add thread to global list. (_cygtls::remove): cygheap->remove_tls() to remove thread from global list. * cygtls.h (_cygtls::init): Delete declaration. * dcrt0.cc (dll_crt0_0): Delete call to _cygtls::init(). * exceptions.cc (sigpacket::process): When no thread is specified, try to find one via cygheap->find_tls.
-rw-r--r--winsup/cygwin/ChangeLog31
-rw-r--r--winsup/cygwin/DevNotes13
-rw-r--r--winsup/cygwin/cygheap.cc99
-rw-r--r--winsup/cygwin/cygheap.h4
-rw-r--r--winsup/cygwin/cygtls.cc63
-rw-r--r--winsup/cygwin/cygtls.h1
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/exceptions.cc4
-rw-r--r--winsup/cygwin/release/1.7.173
9 files changed, 153 insertions, 67 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index ee1a2ccca..e6b69ccd2 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,34 @@
+2012-08-09 Christopher Faylor <me.cygwin2012@cgf.cx>
+
+ * DevNotes: Add entry cgf-000014.
+ * cygheap.cc (tls_sentry): Move here, rename from 'sentry' in cygtls.cc
+ (tls_sentry::lock): Ditto.
+ (nthreads): Move from cygtls.cc
+ (THREADLIST_CHUNK): Ditto.
+ (cygheap_init): Call init_tls_list().
+ (init_cygheap::init_tls_list): Define new function.
+ (init_cygheap::add_tls): Ditto.
+ (init_cygheap::remove_tls): Ditto.
+ (init_cygheap::find_tls): Ditto. Semi-resurrect from
+ _cygtls::find_tls.
+ * cygheap.h (init_cygheap::init_tls_list): Declare new function.
+ (init_cygheap::add_tls): Ditto.
+ (init_cygheap::remove_tls): Ditto.
+ (init_cygheap::find_tls): Ditto.
+ * cygtls.cc (sentry): Delete.
+ (sentry::lock): Ditto.
+ (nthreads): Ditto.
+ (THREADLIST_CHUNK): Ditto.
+ (_cygtls::init): Delete definition.
+ (_cygtls::init_thread): Call cygheap->add_tls() to add thread to global
+ list.
+ (_cygtls::remove): cygheap->remove_tls() to remove thread from global
+ list.
+ * cygtls.h (_cygtls::init): Delete declaration.
+ * dcrt0.cc (dll_crt0_0): Delete call to _cygtls::init().
+ * exceptions.cc (sigpacket::process): When no thread is specified, try
+ to find one via cygheap->find_tls.
+
2012-08-08 Corinna Vinschen <corinna@vinschen.de>
* include/sys/wait.h (_wait): Define when building newlib.
diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes
index e78348897..68d8320cd 100644
--- a/winsup/cygwin/DevNotes
+++ b/winsup/cygwin/DevNotes
@@ -1,3 +1,16 @@
+2012-08-09 cgf-000014
+
+So, apparently I got it somewhat right before wrt signal handling.
+Checking on linux, it appears that signals will be sent to a thread
+which can accept the signal. So resurrecting and extending the
+"find_tls" function is in order. This function will return the tls
+of any thread which 1) is waiting for a signal with sigwait*() or
+2) has the signal unmasked.
+
+In redoing this it became obvious that I had the class designation wrong
+for the threadlist handling so I moved the manipulation of the global
+threadlist into the cygheap where it logically belongs.
+
2012-07-21 cgf-000013
These changes reflect a revamp of the "wait for signal" functionality
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index c7f1f6ab4..639f4e662 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -47,6 +47,23 @@ struct cygheap_entry
char data[0];
};
+class tls_sentry
+{
+public:
+ static muto lock;
+ int destroy;
+ void init ();
+ bool acquired () {return lock.acquired ();}
+ tls_sentry () {destroy = 0;}
+ tls_sentry (DWORD wait) {destroy = lock.acquire (wait);}
+ ~tls_sentry () {if (destroy) lock.release ();}
+};
+
+muto NO_COPY tls_sentry::lock;
+static NO_COPY size_t nthreads;
+
+#define THREADLIST_CHUNK 256
+
#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0]))
#define N0 ((_cmalloc_entry *) NULL)
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (unsigned) (N0->data)))
@@ -256,6 +273,7 @@ cygheap_init ()
cygheap->fdtab.init ();
if (!cygheap->sigs)
sigalloc ();
+ cygheap->init_tls_list ();
}
/* Copyright (C) 1997, 2000 DJ Delorie */
@@ -545,3 +563,84 @@ cygheap_user::set_name (const char *new_name)
cfree_and_set (pdomain);
cfree_and_set (pwinname);
}
+
+void
+init_cygheap::init_tls_list ()
+{
+ if (threadlist)
+ memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
+ else
+ {
+ sthreads = THREADLIST_CHUNK;
+ threadlist = (_cygtls **) ccalloc_abort (HEAP_TLS, cygheap->sthreads,
+ sizeof (cygheap->threadlist[0]));
+ }
+ tls_sentry::lock.init ("thread_tls_sentry");
+}
+
+void
+init_cygheap::add_tls (_cygtls *t)
+{
+ cygheap->user.reimpersonate ();
+ tls_sentry here (INFINITE);
+ if (nthreads >= cygheap->sthreads)
+ {
+ threadlist = (_cygtls **)
+ crealloc_abort (threadlist, (sthreads += THREADLIST_CHUNK)
+ * sizeof (threadlist[0]));
+ // memset (threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (threadlist[0]));
+ }
+
+ threadlist[nthreads++] = t;
+}
+
+void
+init_cygheap::remove_tls (_cygtls *t, DWORD wait)
+{
+ tls_sentry here (wait);
+ if (here.acquired ())
+ {
+ for (size_t i = 0; i < nthreads; i++)
+ if (t == threadlist[i])
+ {
+ if (i < --nthreads)
+ threadlist[i] = threadlist[nthreads];
+ debug_only_printf ("removed %p element %d", this, i);
+ break;
+ }
+ }
+}
+
+_cygtls *
+init_cygheap::find_tls (int sig)
+{
+ debug_printf ("sig %d\n", sig);
+ tls_sentry here (INFINITE);
+
+ static int NO_COPY threadlist_ix;
+
+ _cygtls *t = _main_tls;
+
+ myfault efault;
+ if (efault.faulted ())
+ threadlist[threadlist_ix]->remove (INFINITE);
+ else
+ {
+ threadlist_ix = -1;
+ while (++threadlist_ix < (int) nthreads)
+ if (sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig))
+ {
+ t = cygheap->threadlist[threadlist_ix];
+ goto out;
+ }
+ threadlist_ix = -1;
+ while (++threadlist_ix < (int) nthreads)
+ if (!sigismember (&(threadlist[threadlist_ix]->sigmask), sig))
+ {
+ t = cygheap->threadlist[threadlist_ix];
+ break;
+ }
+ }
+out:
+ return t;
+}
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index f2b0cd9ec..e03774ffd 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -396,6 +396,10 @@ struct init_cygheap: public mini_cygheap
hook_chain hooks;
void close_ctty ();
void init_installation_root ();
+ void init_tls_list () __attribute__ ((regparm (1)));;
+ void add_tls (_cygtls *) __attribute__ ((regparm (2)));
+ void remove_tls (_cygtls *, DWORD) __attribute__ ((regparm (3)));
+ _cygtls *find_tls (int) __attribute__ ((regparm (2)));
};
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index da48622f1..abda77c5f 100644
--- a/winsup/cygwin/cygtls.cc
+++ b/winsup/cygwin/cygtls.cc
@@ -19,39 +19,6 @@ details. */
#include "sigproc.h"
#include "exception.h"
-class sentry
-{
- static muto lock;
- int destroy;
-public:
- void init ();
- bool acquired () {return lock.acquired ();}
- sentry () {destroy = 0;}
- sentry (DWORD wait) {destroy = lock.acquire (wait);}
- ~sentry () {if (destroy) lock.release ();}
- friend void _cygtls::init ();
-};
-
-muto NO_COPY sentry::lock;
-
-static size_t NO_COPY nthreads;
-
-#define THREADLIST_CHUNK 256
-
-void
-_cygtls::init ()
-{
- if (cygheap->threadlist)
- memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
- else
- {
- cygheap->sthreads = THREADLIST_CHUNK;
- cygheap->threadlist = (_cygtls **) ccalloc_abort (HEAP_TLS, cygheap->sthreads,
- sizeof (cygheap->threadlist[0]));
- }
- sentry::lock.init ("sentry_lock");
-}
-
/* Two calls to get the stack right... */
void
_cygtls::call (DWORD (*func) (void *, void *), void *arg)
@@ -167,18 +134,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|| (void *) func == (void *) cygthread::simplestub)
return;
- cygheap->user.reimpersonate ();
-
- sentry here (INFINITE);
- if (nthreads >= cygheap->sthreads)
- {
- cygheap->threadlist = (_cygtls **)
- crealloc_abort (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK)
- * sizeof (cygheap->threadlist[0]));
- memset (cygheap->threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (cygheap->threadlist[0]));
- }
-
- cygheap->threadlist[nthreads++] = this;
+ cygheap->add_tls (this);
}
void
@@ -237,22 +193,7 @@ _cygtls::remove (DWORD wait)
free_local (hostent_buf);
/* Free temporary TLS path buffers. */
locals.pathbufs.destroy ();
-
- do
- {
- sentry here (wait);
- if (here.acquired ())
- {
- for (size_t i = 0; i < nthreads; i++)
- if (this == cygheap->threadlist[i])
- {
- if (i < --nthreads)
- cygheap->threadlist[i] = cygheap->threadlist[nthreads];
- debug_printf ("removed %p element %d", this, i);
- break;
- }
- }
- } while (0);
+ cygheap->remove_tls (this, wait);
remove_wq (wait);
}
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 3db7e10b8..d683cf837 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -204,7 +204,6 @@ public:
unsigned initialized;
/*gentls_offsets*/
- static void init ();
void init_thread (void *, DWORD (*) (void *, void *));
static void call (DWORD (*) (void *, void *), void *);
void remove (DWORD);
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 7e32de0ef..0cda2e5d5 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -773,8 +773,6 @@ dll_crt0_0 ()
user_data->threadinterface->Init ();
- _cygtls::init ();
-
_main_tls = &_my_tls;
/* Initialize signal processing here, early, in the hopes that the creation
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index afbbff4cb..649574fc2 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1170,8 +1170,8 @@ sigpacket::process ()
sigproc_printf ("using tls %p", tls);
else
{
- tls = _main_tls;
- sigproc_printf ("using main tls %p", _main_tls);
+ tls = cygheap->find_tls (si.si_signo);
+ sigproc_printf ("using tls %p", tls);
}
if (si.si_signo == SIGKILL)
diff --git a/winsup/cygwin/release/1.7.17 b/winsup/cygwin/release/1.7.17
index 13ccae223..90df145be 100644
--- a/winsup/cygwin/release/1.7.17
+++ b/winsup/cygwin/release/1.7.17
@@ -1,9 +1,10 @@
Bug fixes:
----------
-- Revamp signals so that signals-to-threads more closely mimic linux
+- Revamp signals so that signals-to-threads more closely mimic Linux
operation.
First step of fix for: http://cygwin.com/ml/cygwin/2012-05/msg00186.html
+ as well as observed Linux behavior.
- Revert to only creating a new session leader when we know that a
console process is started in the background.