public inbox for pthreads-win32@sourceware.org
 help / color / mirror / Atom feed
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"

  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).