From: Ramiro Polla <ramiro.polla@gmail.com>
To: pthreads-win32@sourceware.org
Subject: Re: Static Library Initialization (again?)
Date: Fri, 22 May 2009 00:08:00 -0000 [thread overview]
Message-ID: <f460258d0905211708t6e995ffj7aa422078efb1bb0@mail.gmail.com> (raw)
In-Reply-To: <54b165660806171627i489ec78at85e8576762fe97af@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2153 bytes --]
Hi,
On Tue, Jun 17, 2008 at 8:27 PM, Brian Cole <coleb2@gmail.com> wrote:
> It looks like I'm running into the same problem as others. I need to
> distribute a static library with pthreads-win32 included without
> requiring end-users of our library to call any pthreads-win32 specific
> attach or detach code. Based on previous posts to the mailing list it
> looks like the boost library has dealt with this before:
> http://sourceware.org/ml/pthreads-win32/2008/msg00022.html
>
> I also found this bit of code inside the Google performance tools:
> #ifdef _MSC_VER
>
> // This tells the linker to run these functions.
> #pragma data_seg(push, old_seg)
> #pragma data_seg(".CRT$XLB")
> static void (NTAPI *p_thread_callback)(HINSTANCE h, DWORD dwReason, PVOID pv)
> = on_tls_callback;
> #pragma data_seg(".CRT$XTU")
> static int (*p_process_term)(void) = on_process_term;
> #pragma data_seg(pop, old_seg)
>
> #else // #ifdef _MSC_VER [probably msys/mingw]
>
> // We have to try the DllMain solution here, because we can't use the
> // msvc-specific pragmas.
> <snipped for brevity>
>
> #endif // #ifdef _MSC_VER
>
> Any reason pthreads-win32 can't use these same mechanisms to initialize itself?
>
> Why can't DllMain be used for this? MSDN seems to imply that DllMain
> is called for static libraries
> (http://msdn.microsoft.com/en-us/library/ms682583.aspx):
> "The lpReserved parameter indicates whether the DLL is being loaded
> statically or dynamically."
>
> I just looked through boost and found their implementation
> (boost-trunk/libs/thread/src/win32/tss_pe.cpp). Any objection to me
> creating a patch based on this code for pthreads-win32?
I attached an ugly but working patch for this. I haven't tested
building pthreads with MSVC but the initialization code worked on a
standalone test app.
I added a new make clean GC-autostatic to build the library.
make clean GC-static tests pass. I also tested a bit with FFmpeg (but
not extensively).
I'm sure it can be dramatically improved (comments, documentation,
stress test, etc), but as a start it's good enough.
Ramiro Polla
[-- Attachment #2: static_library_initialization.diff --]
[-- Type: application/octet-stream, Size: 5485 bytes --]
diff -ur pthreads.orig/GNUmakefile pthreads/GNUmakefile
--- pthreads.orig/GNUmakefile Thu May 21 20:13:16 2009
+++ pthreads/GNUmakefile Thu May 21 20:31:09 2009
@@ -455,6 +455,7 @@
@ echo "make clean GC-inlined (to build the GNU C inlined dll with C cleanup code)"
@ echo "make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling)"
@ echo "make clean GC-static (to build the GNU C inlined static lib with C cleanup code)"
+ @ echo "make clean GC-autostatic (to build the GNU C inlined static lib with C cleanup code and automatic library initialization)"
@ echo "make clean GC-debug (to build the GNU C debug dll with C cleanup code)"
@ echo "make clean GCE-debug (to build the GNU C debug dll with C++ exception handling)"
@ echo "make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code)"
@@ -491,6 +492,9 @@
GC-static:
$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP)
+
+GC-autostatic:
+ $(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_AUTOSTATIC -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP)
GC-static-debug:
$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_STATIC_STAMP)
diff -ur pthreads.orig/autostatic.c pthreads/autostatic.c
--- pthreads.orig/autostatic.c Thu May 21 20:55:22 2009
+++ pthreads/autostatic.c Thu May 21 20:27:26 2009
@@ -0,0 +1,109 @@
+/*
+ * autostatic.c
+ *
+ * Description:
+ * This translation unit implements static library initialisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef PTW32_AUTOSTATIC
+
+#include "pthread.h"
+#include "implement.h"
+
+static void on_process_init(void)
+{
+ pthread_win32_process_attach_np ();
+}
+
+static void on_process_exit(void)
+{
+ pthread_win32_thread_detach_np ();
+ pthread_win32_process_detach_np ();
+}
+
+static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv)
+{
+ switch (dwReason) {
+ case DLL_THREAD_ATTACH:
+ pthread_win32_thread_attach_np();
+ break;
+ case DLL_THREAD_DETACH:
+ pthread_win32_thread_detach_np();
+ break;
+ }
+}
+
+#if defined(__MINGW32__)
+ULONG __tls_index__ = 0;
+char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
+char __tls_start__ __attribute__((section(".tls"))) = 0;
+
+void *__crt_xla __attribute__ ((section(".CRT$XLA"))) = 0;
+void *__crt_xlb __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
+void *__crt_xlz __attribute__ ((section(".CRT$XLZ"))) = 0;
+
+const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
+{
+ (DWORD) &__tls_start__,
+ (DWORD) &__tls_end__,
+ (DWORD) &__tls_index__,
+ (DWORD) (&__crt_xla+1),
+ (DWORD) 0,
+ (DWORD) 0
+};
+
+void *__ctors __attribute__((section(".ctors"))) = on_process_init;
+void *__dtors __attribute__((section(".dtors.zzz"))) = on_process_exit;
+
+#elif defined(_MSC_VER)
+
+extern DWORD _tls_used;
+
+static int on_tls_prepare(void)
+{
+ DWORD volatile dw = _tls_used;
+
+ return 0;
+}
+
+#pragma section(".CRT$XLC",long,read)
+__declspec(allocate(".CRT$XLC")) void *__crt_xlc = on_tls_callback;
+#pragma section(".CRT$XIU",long,read)
+__declspec(allocate(".CRT$XIU")) void *__crt_xiu = on_tls_prepare;
+
+#pragma section(".CRT$XCU",long,read)
+__declspec(allocate(".CRT$XCU")) void *__crt_xcu = on_process_init;
+#pragma section(".CRT$XPU",long,read)
+__declspec(allocate(".CRT$XPU")) void *__crt_xtu = on_process_exit;
+#endif
+
+#endif /* PTW32_STATIC_LIB */
diff -ur pthreads.orig/pthread.c pthreads/pthread.c
--- pthreads.orig/pthread.c Thu May 21 20:13:16 2009
+++ pthreads/pthread.c Thu May 21 20:16:55 2009
@@ -49,6 +49,7 @@
#include "condvar.c"
#include "create.c"
#include "dll.c"
+#include "autostatic.c"
#include "errno.c"
#include "exit.c"
#include "fork.c"
next prev parent reply other threads:[~2009-05-22 0:08 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-17 23:28 Brian Cole
2008-06-18 1:25 ` Ross Johnson
2008-06-18 14:09 ` John E. Bossom
2009-05-22 0:08 ` Ramiro Polla [this message]
2009-05-22 2:36 ` John E. Bossom
2009-06-07 23:39 ` Ramiro Polla
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f460258d0905211708t6e995ffj7aa422078efb1bb0@mail.gmail.com \
--to=ramiro.polla@gmail.com \
--cc=pthreads-win32@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).