summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/init.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/init.cc')
-rw-r--r--winsup/cygwin/init.cc58
1 files changed, 51 insertions, 7 deletions
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index f6a29f2d6..a85a8a270 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -16,51 +16,95 @@ details. */
#include "cygtls.h"
int NO_COPY dynamically_loaded;
+static char *search_for = (char *) cygthread::stub;
+static unsigned threadfunc_ix __attribute__((section ("cygwin_dll_common"), shared)) = 0;
+DWORD tls_func;
+
+HANDLE sync_startup;
+
+#define OLDFUNC_OFFSET -1
static void WINAPI
threadfunc_fe (VOID *arg)
{
- _threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[-1]), arg);
+ _threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
+ // void *threadfunc = (void *) TlsGetValue (tls_func);
+ // TlsFree (tls_func);
+ // _threadinfo::call ((DWORD (*) (void *, void *)) (threadfunc), arg);
+}
+
+static DWORD WINAPI
+calibration_thread (VOID *arg)
+{
+ ExitThread (0);
}
static void
munge_threadfunc (HANDLE cygwin_hmodule)
{
- char **ebp = (char **) __builtin_frame_address (0);
- static unsigned threadfunc_ix;
+ char **ebp = (char **) __builtin_frame_address (0);
if (!threadfunc_ix)
{
for (char **peb = ebp; peb < (char **) _tlsbase; peb++)
- if (*peb == (char *) cygthread::stub)
+ if (*peb == search_for)
{
threadfunc_ix = peb - ebp;
goto foundit;
}
+#ifdef DEBUGGING
+ system_printf ("non-fatal warning: unknown thread! search_for %p, cygthread::stub %p, calibration_thread %p, possible func offset %p",
+ search_for, cygthread::stub, calibration_thread, ebp[137]);
+#endif
+ try_to_debug ();
return;
}
foundit:
char *threadfunc = ebp[threadfunc_ix];
- ebp[threadfunc_ix] = (char *) threadfunc_fe;
- ((char **) _tlsbase)[-1] = threadfunc;
+ if (threadfunc == (char *) calibration_thread)
+ /* no need for the overhead */;
+ else
+ {
+ ebp[threadfunc_ix] = (char *) threadfunc_fe;
+ ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
+ // TlsSetValue (tls_func, (void *) threadfunc);
+ }
}
+void
+prime_threads ()
+{
+ // tls_func = TlsAlloc ();
+ if (!threadfunc_ix)
+ {
+ DWORD id;
+ search_for = (char *) calibration_thread;
+ sync_startup = CreateThread (NULL, 0, calibration_thread, 0, 0, &id);
+ }
+}
+
+extern void __stdcall dll_crt0_0 ();
+
extern "C" int WINAPI
dll_entry (HANDLE h, DWORD reason, void *static_load)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
+ prime_threads ();
dynamically_loaded = (static_load == NULL);
// __cygwin_user_data.impure_ptr = &_my_tls.local_clib;
- _my_tls.stackptr = NULL;
+ dll_crt0_0 ();
+ // small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
munge_threadfunc (h);
+ // small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break;
case DLL_THREAD_DETACH:
+ _my_tls.remove (0);
break;
}
return 1;