The attached patch series explore the idea of making portlib mostly independent
of threading library. It changes portlib to use OS services (via thrdsup.h
macro wrappers). I have only tried it on Windows, and would like to have some
feedback before expending more effort on Linux version.
With these patches applied, the only threading functions called from portlib
are hythread_attach() and hythread_detach().
One pair of attach/detach calls was at portlib initialization and shutdown
stages. I figured it is not needed anymore, since portlib does not use thread
library services directly. Thus, the startup thread will be attached to the
thread library by the VM itself.
Another attach/detach pair is in consoleCtrlHandler, which obviously needs to
call into real thread library in order to provide signal handlers with fully
functional VM environment. Fortunately, after the VM is started, it could
initialize a thread library and pass a function table pointer to the portlib
(this is not in the patch series, but can be done).
Tim Ellison wrote:
> So the problem is that if we combine portlib & threadlib functions we
> would need a 'two-phase' portlib initialization, so that the launcher
> can use some of the portlib functions to find&load the VM-specific
> threadlib functions.
Exactly. The VM will need to set up a thread library and pass thread function
table pointer to the portlib at some stage.
>> Practically, at this moment this issue prevents having J9 and DRLVM
>> installation in the same jre/ directory, as both depend on different
>> hythr.dll,
>> which needs to be along with hyprt.dll, and thus cannot be put into vmdir.
>
> Agreed. The proposed patch hythread.c is providing a stub, so when we call:
> hyport_init_library
> hyport_startup_library
> hythread_allocate_library <- we want this provided by a vm-specific
> hythr.dll loaded from the vm subdir,
> in much the same way the launcher uses
> the portlib functionality to load a specific VM's vmi.dll from the vm
> subdir.
I propose a bit different approach: do not use threading library at portlib
initialization stage at all. In this way, port library will never need to load
a dummy library, and will always work with a genuine thread library provided by
the VM. In return, port library will only be able to use thread library after
VM was initialized.
Thus, thread library will not be initialized from within hyport_init_library(),
we will need to invent some new interface like
hyport_set_thread_library()
and call that from the VM after it loaded the thread library.
Thoughts, objections?
--
Salikh Zakirov
>From ae4097ccd0fc4b06c63793dd8a509fb9a4b62101 Mon Sep 17 00:00:00 2001
From: Salikh Zakirov <[EMAIL PROTECTED]>
Date: Thu, 1 Feb 2007 19:19:02 +0300
Subject: [PATCH] removed references to hythread_self()
---
.../portlib/src/main/native/port/unix/hysignal.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/modules/portlib/src/main/native/port/unix/hysignal.c
b/modules/portlib/src/main/native/port/unix/hysignal.c
index 524b8c2..7d89cde 100644
--- a/modules/portlib/src/main/native/port/unix/hysignal.c
+++ b/modules/portlib/src/main/native/port/unix/hysignal.c
@@ -225,7 +225,6 @@ hysig_protect (struct HyPortLibrary * portLibrary,
hysig_protected_fn fn,
{
struct HySignalHandlerRecord thisRecord;
- hythread_t thisThread;
U_32 rc = 0;
U_32 allowHandlers;
@@ -252,8 +251,6 @@ hysig_protect (struct HyPortLibrary * portLibrary,
hysig_protected_fn fn,
return HYPORT_SIG_ERROR;
}
- thisThread = hythread_self ();
-
thisRecord.previous = TLS_GET (tlsKey);
thisRecord.portLibrary = portLibrary;
thisRecord.handler = handler;
@@ -554,7 +551,6 @@ masterSynchSignalHandler (int signal, siginfo_t * sigInfo,
void *contextInfo)
struct HySignalHandlerRecord *thisRecord;
struct HyCurrentSignal currentSignal;
struct HyCurrentSignal *previousSignal;
- hythread_t thisThread = hythread_self ();
thisRecord = NULL;
--
1.4.4.4.g05d6b
>From 3c8944c905d2f65e1d9a611c5349c28ccf36932b Mon Sep 17 00:00:00 2001
From: Salikh Zakirov <[EMAIL PROTECTED]>
Date: Fri, 2 Feb 2007 11:56:57 +0300
Subject: [PATCH] replaced monitors with CONDs and MUTEXes
---
.../portlib/src/main/native/port/shared/hynls.c | 17 ++--
.../portlib/src/main/native/port/shared/portpriv.h | 2 +-
.../src/main/native/port/windows/hysignal.c | 100 ++++++++++++++-----
3 files changed, 82 insertions(+), 37 deletions(-)
diff --git a/modules/portlib/src/main/native/port/shared/hynls.c
b/modules/portlib/src/main/native/port/shared/hynls.c
index 9d1d1bc..1b40016 100644
--- a/modules/portlib/src/main/native/port/shared/hynls.c
+++ b/modules/portlib/src/main/native/port/shared/hynls.c
@@ -90,7 +90,7 @@ hynls_set_locale (struct HyPortLibrary *portLibrary, const
char *lang,
#endif
- hythread_monitor_enter (nls->monitor);
+ MUTEX_ENTER (nls->mutex);
if (lang && strlen (lang) <= 2)
strcpy (nls->language, lang);
@@ -99,7 +99,7 @@ hynls_set_locale (struct HyPortLibrary *portLibrary, const
char *lang,
if (variant && strlen (variant) <= 31)
strcpy (nls->variant, variant);
- hythread_monitor_exit (nls->monitor);
+ MUTEX_EXIT (nls->mutex);
}
@@ -272,7 +272,7 @@ hynls_lookup_message (struct HyPortLibrary *portLibrary,
UDATA flags,
#endif
- hythread_monitor_enter (nls->monitor);
+ MUTEX_ENTER (nls->mutex);
if (!nls->catalog)
open_catalog (portLibrary);
@@ -288,7 +288,7 @@ hynls_lookup_message (struct HyPortLibrary *portLibrary,
UDATA flags,
HYNLS_ERROR_MESSAGE (HYNLS_PORT_NLS_FAILURE, "NLS Failure\n");
}
- hythread_monitor_exit (nls->monitor);
+ MUTEX_EXIT (nls->mutex);
return message;
}
@@ -323,7 +323,7 @@ hynls_set_catalog (struct HyPortLibrary *portLibrary, const
char **paths,
#endif
- hythread_monitor_enter (nls->monitor);
+ MUTEX_ENTER (nls->mutex);
if (!baseName || !extension)
goto clean_exit;
@@ -375,7 +375,7 @@ hynls_set_catalog (struct HyPortLibrary *portLibrary, const
char **paths,
}
clean_exit:
- hythread_monitor_exit (nls->monitor);
+ MUTEX_EXIT (nls->mutex);
}
@@ -1060,8 +1060,7 @@ hynls_startup (struct HyPortLibrary *portLibrary)
{
HyNLSDataCache *nls = &portLibrary->portGlobals->nls_data;
- if (0 !=
- hythread_monitor_init_with_name (&nls->monitor, 0, "NLS hash table"))
+ if (!MUTEX_INIT (nls->mutex))
{
return (I_32) HYPORT_ERROR_STARTUP_NLS;
}
@@ -1131,7 +1130,7 @@ hynls_shutdown (struct HyPortLibrary *portLibrary)
if (nls->catalog)
portLibrary->mem_free_memory (portLibrary, nls->catalog);
- hythread_monitor_destroy (nls->monitor);
+ MUTEX_DESTROY(nls->mutex);
}
#undef CDEV_CURRENT_FUNCTION
diff --git a/modules/portlib/src/main/native/port/shared/portpriv.h
b/modules/portlib/src/main/native/port/shared/portpriv.h
index 8e1e1be..e91968b 100644
--- a/modules/portlib/src/main/native/port/shared/portpriv.h
+++ b/modules/portlib/src/main/native/port/shared/portpriv.h
@@ -68,7 +68,7 @@ typedef struct HyNLSDataCache
char language[4];
char region[4];
char variant[32];
- struct HyThreadMonitor *monitor;
+ MUTEX mutex;
struct HyNLSHashEntry *hash_buckets[256];
struct HyNLSHashEntry *old_hashEntries;
} HyNLSDataCache;
diff --git a/modules/portlib/src/main/native/port/windows/hysignal.c
b/modules/portlib/src/main/native/port/windows/hysignal.c
index 9c12521..26d7923 100644
--- a/modules/portlib/src/main/native/port/windows/hysignal.c
+++ b/modules/portlib/src/main/native/port/windows/hysignal.c
@@ -20,6 +20,7 @@
#include "hyport.h"
#include "hythread.h"
#include "hysignal.h"
+#include "thrdsup.h"
typedef struct HyWin32AsyncHandlerRecord
{
@@ -31,7 +32,10 @@ typedef struct HyWin32AsyncHandlerRecord
} HyWin32AsyncHandlerRecord;
static HyWin32AsyncHandlerRecord *asyncHandlerList;
-static hythread_monitor_t asyncMonitor;
+static U_32 initialized = 0;
+static MUTEX globalMutex;
+static MUTEX asyncMutex;
+static COND asyncCondition;
static U_32 asyncThreadCount;
static U_32 attachedPortLibraries;
/* holds the options set by hysig_set_options */
@@ -146,12 +150,17 @@ hysig_set_async_signal_handler (struct HyPortLibrary *
portLibrary,
HyWin32AsyncHandlerRecord *cursor;
HyWin32AsyncHandlerRecord **previousLink;
- hythread_monitor_enter (asyncMonitor);
+ MUTEX_ENTER (asyncMutex);
/* wait until no signals are being reported */
- while (asyncThreadCount > 0)
+ if (asyncThreadCount > 0)
{
- hythread_monitor_wait (asyncMonitor);
+ COND_WAIT (asyncCondition, asyncMutex);
+ if (asyncThreadCount == 0)
+ {
+ break;
+ }
+ COND_WAIT_LOOP ();
}
/* is this handler already registered? */
@@ -215,7 +224,7 @@ hysig_set_async_signal_handler (struct HyPortLibrary *
portLibrary,
}
}
- hythread_monitor_exit (asyncMonitor);
+ MUTEX_EXIT (asyncMutex);
return rc;
}
@@ -252,18 +261,17 @@ hysig_can_protect (struct HyPortLibrary * portLibrary,
U_32 flags)
void VMCALL
hysig_shutdown (struct HyPortLibrary *portLibrary)
{
- hythread_monitor_t globalMonitor = hythread_global_monitor ();
-
removeAsyncHandlers (portLibrary);
- hythread_monitor_enter (globalMonitor);
+ MUTEX_ENTER (globalMutex);
if (--attachedPortLibraries == 0)
{
- hythread_monitor_destroy (asyncMonitor);
+ MUTEX_DESTROY (asyncMutex);
+ COND_DESTROY (asyncCondition);
}
- hythread_monitor_exit (globalMonitor);
+ MUTEX_EXIT (globalMutex);
}
#undef CDEV_CURRENT_FUNCTION
@@ -275,21 +283,19 @@ hysig_shutdown (struct HyPortLibrary *portLibrary)
I_32 VMCALL
hysig_startup (struct HyPortLibrary *portLibrary)
{
- hythread_monitor_t globalMonitor = hythread_global_monitor ();
I_32 result = 0;
- hythread_monitor_enter (globalMonitor);
+ MUTEX_ENTER (globalMutex);
if (attachedPortLibraries++ == 0)
{
- if (hythread_monitor_init_with_name
- (&asyncMonitor, 0, "portLibrary_hysig_async_monitor"))
- {
- result = -1;
- }
+ if (!MUTEX_INIT (asyncMutex) || !COND_INIT (asyncCondition))
+ {
+ result = -1;
+ }
}
- hythread_monitor_exit (globalMonitor);
+ MUTEX_EXIT (globalMutex);
return result;
}
@@ -675,9 +681,9 @@ consoleCtrlHandler (DWORD dwCtrlType)
U_32 handlerCount = 0;
/* incrementing the asyncThreadCount will prevent the list from being
modified while we use it */
- hythread_monitor_enter (asyncMonitor);
+ MUTEX_ENTER (asyncMutex);
asyncThreadCount++;
- hythread_monitor_exit (asyncMonitor);
+ MUTEX_EXIT (asyncMutex);
cursor = asyncHandlerList;
while (cursor)
@@ -691,12 +697,12 @@ consoleCtrlHandler (DWORD dwCtrlType)
cursor = cursor->next;
}
- hythread_monitor_enter (asyncMonitor);
+ MUTEX_ENTER (asyncMutex);
if (--asyncThreadCount == 0)
{
- hythread_monitor_notify_all (asyncMonitor);
+ COND_NOTIFY_ALL (asyncCondition);
}
- hythread_monitor_exit (asyncMonitor);
+ MUTEX_EXIT (asyncMutex);
/* TODO: possible timing hole. The thread library could be unloaded by
the time we
* reach this line. We can't use hythread_exit(), as that kills the
async reporting thread
@@ -717,12 +723,17 @@ removeAsyncHandlers (HyPortLibrary * portLibrary)
HyWin32AsyncHandlerRecord *cursor;
HyWin32AsyncHandlerRecord **previousLink;
- hythread_monitor_enter (asyncMonitor);
+ MUTEX_ENTER (asyncMutex);
/* wait until no signals are being reported */
- while (asyncThreadCount > 0)
+ if (asyncThreadCount > 0)
{
- hythread_monitor_wait (asyncMonitor);
+ COND_WAIT (asyncCondition, asyncMutex);
+ if (asyncThreadCount == 0)
+ {
+ break;
+ }
+ COND_WAIT_LOOP ();
}
previousLink = &asyncHandlerList;
@@ -747,7 +758,7 @@ removeAsyncHandlers (HyPortLibrary * portLibrary)
SetConsoleCtrlHandler (consoleCtrlHandler, FALSE);
}
- hythread_monitor_exit (asyncMonitor);
+ MUTEX_EXIT (asyncMutex);
}
#undef CDEV_CURRENT_FUNCTION
@@ -782,3 +793,38 @@ hysig_get_options (struct HyPortLibrary * portLibrary)
}
#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION DllMain
+#if (!defined(HYVM_STATIC_LINKAGE))
+/*
+ * Initialize global mutex.
+ *
+ * @param hModule handle to module being loaded
+ * @param ul_reason_for_call reason why DllMain being called
+ * @param lpReserved reserved
+ * @return TRUE on success, FALSE on failure.
+ */
+BOOL APIENTRY
+DllMain (HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ if (!initialized) {
+ MUTEX_INIT(globalMutex);
+ initialized = 1;
+ }
+ return TRUE;
+ }
+ case DLL_PROCESS_DETACH:
+ {
+ initialized = 0;
+ MUTEX_DESTROY(globalMutex);
+ }
+ }
+ return TRUE;
+}
+#endif /* !HYVM_STATIC_LINKAGE */
+#undef CDEV_CURRENT_FUNCTION
+
--
1.4.4.4.g05d6b
>From f4bad656ad383202e2662c43bfdfbb76051c1d30 Mon Sep 17 00:00:00 2001
From: Salikh Zakirov <[EMAIL PROTECTED]>
Date: Fri, 2 Feb 2007 11:55:06 +0300
Subject: [PATCH] removed thread attaching in port library startup and shutdown
---
.../portlib/src/main/native/port/shared/hyport.c | 11 -----------
1 files changed, 0 insertions(+), 11 deletions(-)
diff --git a/modules/portlib/src/main/native/port/shared/hyport.c
b/modules/portlib/src/main/native/port/shared/hyport.c
index 034606e..1b0bd8a 100644
--- a/modules/portlib/src/main/native/port/shared/hyport.c
+++ b/modules/portlib/src/main/native/port/shared/hyport.c
@@ -100,8 +100,6 @@ hyport_shutdown_library (struct HyPortLibrary * portLibrary)
hyport_tls_shutdown (portLibrary);
portLibrary->mem_shutdown (portLibrary);
- hythread_detach (portLibrary->attached_thread);
-
/* Last thing to do. If this port library was self allocated free this
memory */
if (NULL != portLibrary->self_handle)
{
@@ -201,15 +199,6 @@ hyport_startup_library (struct HyPortLibrary * portLibrary)
{
I_32 rc = 0;
- /* NLS uses the thread library */
- rc = hythread_attach (&portLibrary->attached_thread);
- if (0 != rc)
- {
- /* Reassign return code as hythread_attach only returns -1 on error */
- rc = HYPORT_ERROR_STARTUP_THREAD;
- goto cleanup;
- }
-
/* Must not access anything in portGlobals, as this allocates them */
rc =
portLibrary->mem_startup (portLibrary, sizeof (HyPortLibraryGlobalData));
--
1.4.4.4.g05d6b
>From 1cbca4007aff21923f3df1fd8e08c95fa9cc3c7a Mon Sep 17 00:00:00 2001
From: Salikh Zakirov <[EMAIL PROTECTED]>
Date: Thu, 1 Feb 2007 15:59:13 +0300
Subject: [PATCH] replaced hythread_tls_* calls with TLS_ macros
---
.../src/main/native/port/shared/hytlshelpers.c | 22 +-
.../portlib/src/main/native/port/shared/portpriv.h | 4 +-
.../portlib/src/main/native/port/unix/hysignal.c | 38 ++--
.../portlib/src/main/native/port/unix/thrdsup.h | 258 ++++++++++++++++++++
.../portlib/src/main/native/port/windows/thrdsup.h | 148 +++++++++++
5 files changed, 437 insertions(+), 33 deletions(-)
diff --git a/modules/portlib/src/main/native/port/shared/hytlshelpers.c
b/modules/portlib/src/main/native/port/shared/hytlshelpers.c
index c59c889..39bde5e 100644
--- a/modules/portlib/src/main/native/port/shared/hytlshelpers.c
+++ b/modules/portlib/src/main/native/port/shared/hytlshelpers.c
@@ -36,6 +36,8 @@
#include "hythread.h"
#include "hyportptb.h"
+#include "thrdsup.h"
+
/**
* @internal
* @brief Per Thread Buffer Support
@@ -51,8 +53,7 @@ hyport_tls_get (struct HyPortLibrary *portLibrary)
{
PortlibPTBuffers_t ptBuffers;
- ptBuffers =
- hythread_tls_get (hythread_self (), portLibrary->portGlobals->tls_key);
+ ptBuffers = TLS_GET (portLibrary->portGlobals->tls_key);
if (NULL == ptBuffers)
{
MUTEX_ENTER (portLibrary->portGlobals->tls_mutex);
@@ -62,9 +63,7 @@ hyport_tls_get (struct HyPortLibrary *portLibrary)
sizeof (PortlibPTBuffers_struct));
if (NULL != ptBuffers)
{
- if (0 ==
- hythread_tls_set (hythread_self (),
- portLibrary->portGlobals->tls_key, ptBuffers))
+ if (0 == TLS_SET (portLibrary->portGlobals->tls_key, ptBuffers))
{
memset (ptBuffers, 0, sizeof (PortlibPTBuffers_struct));
ptBuffers->next = portLibrary->portGlobals->buffer_list;
@@ -100,12 +99,10 @@ hyport_tls_free (struct HyPortLibrary *portLibrary)
PortlibPTBuffers_t ptBuffers;
MUTEX_ENTER (portLibrary->portGlobals->tls_mutex);
- ptBuffers =
- hythread_tls_get (hythread_self (), portLibrary->portGlobals->tls_key);
+ ptBuffers = TLS_GET (portLibrary->portGlobals->tls_key);
if (ptBuffers)
{
- hythread_tls_set (hythread_self (), portLibrary->portGlobals->tls_key,
- NULL);
+ TLS_SET (portLibrary->portGlobals->tls_key, NULL);
/* Unlink */
if (ptBuffers->next)
@@ -147,7 +144,7 @@ hyport_tls_free (struct HyPortLibrary *portLibrary)
I_32 VMCALL
hyport_tls_startup (struct HyPortLibrary *portLibrary)
{
- if (hythread_tls_alloc (&portLibrary->portGlobals->tls_key))
+ if (TLS_ALLOC (portLibrary->portGlobals->tls_key))
{
return HYPORT_ERROR_STARTUP_TLS_ALLOC;
}
@@ -187,7 +184,7 @@ hyport_tls_shutdown (struct HyPortLibrary *portLibrary)
MUTEX_EXIT (portLibrary->portGlobals->tls_mutex);
/* Now dispose of the tls_key and the mutex */
- hythread_tls_free (portLibrary->portGlobals->tls_key);
+ TLS_DESTROY (portLibrary->portGlobals->tls_key);
MUTEX_DESTROY (portLibrary->portGlobals->tls_mutex);
}
@@ -207,6 +204,5 @@ hyport_tls_shutdown (struct HyPortLibrary *portLibrary)
void *VMCALL
hyport_tls_peek (struct HyPortLibrary *portLibrary)
{
- return hythread_tls_get (hythread_self (),
- portLibrary->portGlobals->tls_key);
+ return TLS_GET (portLibrary->portGlobals->tls_key);
}
diff --git a/modules/portlib/src/main/native/port/shared/portpriv.h
b/modules/portlib/src/main/native/port/shared/portpriv.h
index 3312fb9..8e1e1be 100644
--- a/modules/portlib/src/main/native/port/shared/portpriv.h
+++ b/modules/portlib/src/main/native/port/shared/portpriv.h
@@ -24,6 +24,8 @@
#include "hyport.h"
#include "hymutex.h"
+#include "thrdsup.h"
+
/* The following defines are used by hyshmem and hyshsem */
#define HYSH_MAXPATH HyMaxPath
#define HyVersionMajor 0
@@ -82,7 +84,7 @@ typedef struct HyPortLibraryGlobalData
{
struct HyPortControlData control;
struct HyNLSDataCache nls_data;
- hythread_tls_key_t tls_key;
+ TLSKEY tls_key;
MUTEX tls_mutex;
void *buffer_list;
struct HyPortPlatformGlobals platformGlobals;
diff --git a/modules/portlib/src/main/native/port/unix/hysignal.c
b/modules/portlib/src/main/native/port/unix/hysignal.c
index 2d9e203..524b8c2 100644
--- a/modules/portlib/src/main/native/port/unix/hysignal.c
+++ b/modules/portlib/src/main/native/port/unix/hysignal.c
@@ -29,6 +29,7 @@
#include <jsig.h>
#include "hysignal_context.h"
+#include "thrdsup.h"
#define MAX_PORTLIB_SIGNAL_TYPES 8
@@ -92,10 +93,10 @@ typedef struct HyCurrentSignal
} HyCurrentSignal;
/* key to get the end of the synchronous handler records */
-static hythread_tls_key_t tlsKey;
+static TLSKEY tlsKey;
/* key to get the current synchronous signal */
-static hythread_tls_key_t tlsKeyCurrentSignal;
+static TLSKEY tlsKeyCurrentSignal;
struct
{
@@ -253,7 +254,7 @@ hysig_protect (struct HyPortLibrary * portLibrary,
hysig_protected_fn fn,
thisThread = hythread_self ();
- thisRecord.previous = hythread_tls_get (thisThread, tlsKey);
+ thisRecord.previous = TLS_GET (tlsKey);
thisRecord.portLibrary = portLibrary;
thisRecord.handler = handler;
thisRecord.handler_arg = handler_arg;
@@ -267,13 +268,13 @@ hysig_protect (struct HyPortLibrary * portLibrary,
hysig_protected_fn fn,
{
/* the handler had long jumped back here -- reset the signal
handler stack and return */
- hythread_tls_set (thisThread, tlsKey, thisRecord.previous);
+ TLS_SET (tlsKey, thisRecord.previous);
*result = 0;
return HYPORT_SIG_EXCEPTION_OCCURRED;
}
}
- if (hythread_tls_set (thisThread, tlsKey, &thisRecord))
+ if (TLS_SET (tlsKey, &thisRecord))
{
return HYPORT_SIG_ERROR;
}
@@ -282,8 +283,8 @@ hysig_protect (struct HyPortLibrary * portLibrary,
hysig_protected_fn fn,
*result = fn (portLibrary, fn_arg);
- /* if the first hythread_tls_set succeeded, then this one will always
succeed */
- hythread_tls_set (thisThread, tlsKey, thisRecord.previous);
+ /* if the first TLS_SET succeeded, then this one will always succeed */
+ TLS_SET (tlsKey, thisRecord.previous);
return 0;
}
@@ -564,12 +565,12 @@ masterSynchSignalHandler (int signal, siginfo_t *
sigInfo, void *contextInfo)
currentSignal.sigInfo = sigInfo;
currentSignal.contextInfo = contextInfo;
- previousSignal = hythread_tls_get (thisThread, tlsKeyCurrentSignal);
+ previousSignal = TLS_GET (tlsKeyCurrentSignal);
- hythread_tls_set (thisThread, tlsKeyCurrentSignal, ¤tSignal);
+ TLS_SET (tlsKeyCurrentSignal, ¤tSignal);
/* walk the stack of registered handlers from top to bottom searching for
one which handles this type of exception */
- thisRecord = hythread_tls_get (thisThread, tlsKey);
+ thisRecord = TLS_GET (tlsKey);
while (thisRecord)
{
@@ -594,7 +595,7 @@ masterSynchSignalHandler (int signal, siginfo_t * sigInfo,
void *contextInfo)
&hyInfo);
/* remove the handler we are about to invoke, now, in case the
handler crashes */
- hythread_tls_set (thisThread, tlsKey, thisRecord->previous);
+ TLS_SET (tlsKey, thisRecord->previous);
result =
thisRecord->handler (thisRecord->portLibrary, portLibType,
@@ -602,7 +603,7 @@ masterSynchSignalHandler (int signal, siginfo_t * sigInfo,
void *contextInfo)
/* The only case in which we don't want the previous handler back on
top is if it just returned HYPORT_SIG_EXCEPTION_RETURN
* In this case we will remove it from the top after
executing the siglongjmp */
- hythread_tls_set (thisThread, tlsKey, thisRecord);
+ TLS_SET (tlsKey, thisRecord);
if (result == HYPORT_SIG_EXCEPTION_CONTINUE_SEARCH)
{
@@ -610,13 +611,13 @@ masterSynchSignalHandler (int signal, siginfo_t *
sigInfo, void *contextInfo)
}
else if (result == HYPORT_SIG_EXCEPTION_CONTINUE_EXECUTION)
{
- hythread_tls_set (thisThread, tlsKeyCurrentSignal,
+ TLS_SET (tlsKeyCurrentSignal,
previousSignal);
return;
}
else /* if (result == HYPORT_SIG_EXCEPTION_RETURN)
*/
{
- hythread_tls_set (thisThread, tlsKeyCurrentSignal,
+ TLS_SET (tlsKeyCurrentSignal,
previousSignal);
siglongjmp (thisRecord->returnBuf, 0);
}
@@ -883,13 +884,13 @@ initializeSignalTools (HyPortLibrary * portLibrary)
{
/* use this to record the end of the list of signal infos */
- if (hythread_tls_alloc (&tlsKey))
+ if (TLS_ALLOC (tlsKey))
{
return -1;
}
/* use this to record the last signal that occured such that we can call
jsig_handler in hyexit_shutdown_and_exit */
- if (hythread_tls_alloc (&tlsKeyCurrentSignal))
+ if (TLS_ALLOC (tlsKeyCurrentSignal))
{
return -1;
}
@@ -950,7 +951,7 @@ initializeSignalTools (HyPortLibrary * portLibrary)
static U_32
destroySignalTools (HyPortLibrary * portLibrary)
{
- hythread_tls_free (tlsKey);
+ TLS_DESTROY (tlsKey);
hythread_monitor_destroy (masterHandlerMonitor);
hythread_monitor_destroy (asyncReporterShutdownMonitor);
hythread_monitor_destroy (asyncMonitor);
@@ -1085,8 +1086,7 @@ void VMCALL
hysig_chain_at_shutdown_and_exit (struct HyPortLibrary *portLibrary)
{
- HyCurrentSignal *currentSignal =
- hythread_tls_get (hythread_self (), tlsKeyCurrentSignal);
+ HyCurrentSignal *currentSignal = TLS_GET (tlsKeyCurrentSignal);
if (currentSignal != NULL)
{
diff --git a/modules/portlib/src/main/native/port/unix/thrdsup.h
b/modules/portlib/src/main/native/port/unix/thrdsup.h
new file mode 100644
index 0000000..e1c25a6
--- /dev/null
+++ b/modules/portlib/src/main/native/port/unix/thrdsup.h
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(thrdsup_h)
+#define thrdsup_h
+#define HY_POSIX_THREADS
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <setjmp.h>
+#include "hycomp.h"
+
+#if (defined(LINUX))
+#include <sys/time.h>
+#endif
+
+#include "hymutex.h"
+/* ostypes */
+typedef pthread_t OSTHREAD;
+typedef pthread_key_t TLSKEY;
+typedef pthread_cond_t COND;
+#define WRAPPER_TYPE void*
+typedef void *WRAPPER_ARG;
+#define WRAPPER_RETURN() return NULL
+#if defined(LINUX) || defined(FREEBSD)
+#include <semaphore.h>
+typedef sem_t OSSEMAPHORE;
+#else
+
+typedef IDATA OSSEMAPHORE;
+
+#endif
+#include "thrtypes.h"
+#include "priority.h"
+#include "thrcreate.h"
+
+int linux_pthread_cond_timedwait
+PROTOTYPE ((pthread_cond_t * cond, pthread_mutex_t * mutex,
+ const struct timespec * abstime));
+IDATA VMCALL hythread_sigthreadmask_sigQuit PROTOTYPE ((void));
+IDATA init_thread_library PROTOTYPE ((void));
+IDATA VMCALL hythread_signalThread_sigQuit
+PROTOTYPE ((hythread_t sigQuitThread));
+IDATA VMCALL hythread_sigwait_sigQuit PROTOTYPE ((int *sig));
+IDATA nto_cond_init PROTOTYPE ((pthread_cond_t * cond));
+extern struct HyThreadLibrary default_library;
+/* priority_map */
+#if defined(HY_PRIORITY_MAP)
+extern const int priority_map[];
+#else
+extern int priority_map[];
+#endif
+
+/* SETUP_TIMEOUT */
+
+#define HYDIV_T div_t
+#define HYDIV div
+/* do we really need nanosecond clock accuracy even on platforms which support
gettime? */
+
+#define TIMEOUT_CLOCK CLOCK_REALTIME
+
+#if (defined(LINUX))
+#define SETUP_TIMEOUT(ts_, millis, nanos) {
\
+ struct timeval tv_;
\
+ HYDIV_T secs_ = HYDIV(millis, 1000);
\
+ int nanos_ = secs_.rem * 1000000 + nanos;
\
+ gettimeofday(&tv_, NULL);
\
+ nanos_ += tv_.tv_usec * 1000;
\
+ if (nanos_ >= 1000000000) {
\
+ ts_.tv_sec = tv_.tv_sec + secs_.quot + 1;
\
+ ts_.tv_nsec = nanos_ - 1000000000;
\
+ } else {
\
+ ts_.tv_sec = tv_.tv_sec + secs_.quot;
\
+ ts_.tv_nsec = nanos_;
\
+ } }
+#elif defined(HYOSE)
+#define SETUP_TIMEOUT(ts_, millis, nanos) { \
+ struct TimePair tvp; \
+ HYDIV_T secs_ = HYDIV(millis, 1000); \
+ int nanos_ = secs_.rem * 1000000 + nanos; \
+ rtc_get_time(&tvp); \
+ nanos_ += tvp.micros * 1000; \
+ if (nanos_ >= 1000000000) { \
+ ts_.tv_sec = tvp.seconds + secs_.quot + 1; \
+ ts_.tv_nsec = nanos_ - 1000000000; \
+ } else { \
+ ts_.tv_sec = tvp.seconds + secs_.quot; \
+ ts_.tv_nsec = nanos_; \
+ } }
+#else
+#define SETUP_TIMEOUT(ts_, millis, nanos) {
\
+ HYDIV_T secs_ = HYDIV(millis, 1000);
\
+ int nanos_ = secs_.rem * 1000000 + nanos;
\
+ clock_gettime(TIMEOUT_CLOCK, &ts_); \
+ nanos_ += ts_.tv_nsec;
\
+ if (nanos_ >= 1000000000) {
\
+ ts_.tv_sec += secs_.quot + 1;
\
+ ts_.tv_nsec = nanos_ - 1000000000;
\
+ } else {
\
+ ts_.tv_sec += secs_.quot;
\
+ ts_.tv_nsec = nanos_;
\
+ } }
+#endif
+
+/* COND_DESTROY */
+#define COND_DESTROY(cond) pthread_cond_destroy(&(cond))
+
+/* TLS_GET */
+#define TLS_GET(key) (pthread_getspecific(key))
+
+/* TLS_ALLOC */
+#define TLS_ALLOC(key) (pthread_key_create(&key, NULL))
+
+/* TLS_SET */
+#define TLS_SET(key, value) (pthread_setspecific(key, value))
+
+/* COND_WAIT */
+/* NOTE: the calling thread must already own mutex */
+/* NOTE: a timeout less than zero indicates infinity */
+#define COND_WAIT(cond, mutex) \
+ do { \
+ pthread_cond_wait(&(cond), &(mutex))
+#define COND_WAIT_LOOP() } while(1)
+
+/* THREAD_SELF */
+#define THREAD_SELF() (pthread_self())
+
+/* THREAD_YIELD */
+#if defined(LINUX) || defined(FREEBSD)
+#define THREAD_YIELD() (sched_yield())
+#endif
+
+#if defined(LINUX) && defined(HARDHAT)
+#undef THREAD_YIELD /* undo the one defined above */
+#define THREAD_YIELD() (usleep(0))
+#endif
+
+/* last chance. If it's not defined by now, use yield */
+#if !defined(THREAD_YIELD)
+#define THREAD_YIELD() (yield())
+#endif
+
+/* THREAD_CREATE */
+#define THREAD_CREATE(thread, stacksize, priority, entrypoint, entryarg)
\
+ (create_pthread(&(thread)->handle, (stacksize),
priority_map[(priority)], (entrypoint), (entryarg)) == 0)
+
+/* THREAD_CANCEL */
+/* pthread_cancel is asynchronous. Use join to wait for it to complete */
+#define THREAD_CANCEL(thread) (pthread_cancel(thread) || pthread_join(thread,
NULL))
+
+/* COND_NOTIFY_ALL */
+#define COND_NOTIFY_ALL(cond) pthread_cond_broadcast(&(cond))
+
+/* COND_WAIT_IF_TIMEDOUT */
+/* NOTE: the calling thread must already own the mutex! */
+#if defined(LINUX) && defined(HYX86)
+#define PTHREAD_COND_TIMEDWAIT(x,y,z) linux_pthread_cond_timedwait(x,y,z)
+#else
+#define PTHREAD_COND_TIMEDWAIT(x,y,z) pthread_cond_timedwait(x,y,z)
+#endif
+
+#define COND_WAIT_RC_TIMEDOUT ETIMEDOUT
+
+#define COND_WAIT_IF_TIMEDOUT(cond, mutex, millis, nanos)
\
+ do {
\
+ struct timespec ts_;
\
+ SETUP_TIMEOUT(ts_, millis, nanos);
\
+ while (1) {
\
+ if (PTHREAD_COND_TIMEDWAIT(&(cond), &(mutex),
&ts_) == COND_WAIT_RC_TIMEDOUT)
+
+#define COND_WAIT_TIMED_LOOP() } } while(0)
+
+/* COND_INIT */
+#define COND_INIT(cond) (pthread_cond_init(&(cond), NULL) == 0)
+
+/* TLS_DESTROY */
+#define TLS_DESTROY(key) (pthread_key_delete(key))
+
+/* THREAD_EXIT */
+#define THREAD_EXIT() pthread_exit(NULL)
+
+/* THREAD_DETACH */
+#define THREAD_DETACH(thread) pthread_detach(thread)
+
+/* THREAD_SET_PRIORITY */
+#define THREAD_SET_PRIORITY(thread, priority) set_pthread_priority((thread),
(priority))
+
+/* SEM_CREATE */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_CREATE(initValue) thread_malloc(NULL, sizeof(OSSEMAPHORE))
+#else
+#define SEM_CREATE(initValue)
+#endif
+
+/* SEM_INIT */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_INIT(sm, pshrd, inval) (sem_init((sem_t*)sm, pshrd, inval))
+#else
+#define SEM_INIT(sm,pshrd,inval)
+#endif
+
+/* SEM_DESTROY */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_DESTROY(sm) (sem_destroy((sem_t*)sm))
+#else
+#define SEM_DESTROY(sm)
+#endif
+
+/* SEM_FREE */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_FREE(s) thread_free(NULL, (sem_t*)s);
+#endif
+
+/* SEM_POST */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_POST(smP) (sem_post((sem_t*)smP))
+#else
+#define SEM_POST(sm)
+#endif
+
+/* SEM_WAIT */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_WAIT(smP) (sem_wait((sem_t*)smP))
+#else
+#define SEM_WAIT(sm)
+#endif
+
+/* SEM_TRYWAIT */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_TRYWAIT(smP) (sem_trywait(smP))
+#else
+#define SEM_TRYWAIT(sm)
+#endif
+
+/* SEM_GETVALUE */
+#if defined(LINUX) || defined(FREEBSD)
+#define SEM_GETVALUE(smP, intP) (sem_getvalue(smP, intP))
+#else
+#define SEM_GETVALUE(sm)
+#endif
+
+#endif /* thrdsup_h */
diff --git a/modules/portlib/src/main/native/port/windows/thrdsup.h
b/modules/portlib/src/main/native/port/windows/thrdsup.h
new file mode 100644
index 0000000..1599bdb
--- /dev/null
+++ b/modules/portlib/src/main/native/port/windows/thrdsup.h
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(thrdsup_h)
+#define thrdsup_h
+
+/* windows.h defined UDATA. Ignore its definition */
+#define UDATA UDATA_win32_
+#include <windows.h>
+#undef UDATA /* this is safe because our UDATA is a typedef,
not a macro */
+#include <process.h>
+#include "hymutex.h"
+
+/* ostypes */
+typedef HANDLE OSTHREAD;
+typedef DWORD TLSKEY;
+typedef HANDLE COND;
+
+#define WRAPPER_TYPE void _cdecl
+
+typedef void *WRAPPER_ARG;
+#define WRAPPER_RETURN() return
+typedef HANDLE OSSEMAPHORE;
+
+#include "hycomp.h"
+void initialize_thread_priority PROTOTYPE ((hythread_t thread));
+IDATA init_thread_library PROTOTYPE ((void));
+extern const int priority_map[];
+extern struct HyThreadLibrary default_library;
+extern BOOL (WINAPI * f_yield) (void);
+
+/* Unused ID variable. */
+extern DWORD unusedThreadID;
+/* COND_DESTROY */
+#define COND_DESTROY(cond) CloseHandle(cond)
+/* TLS_GET */
+#define TLS_GET(key) (TlsGetValue(key))
+/* TLS_ALLOC */
+#define TLS_ALLOC(key) ((key = TlsAlloc()) == 0xFFFFFFFF)
+/* TLS_SET */
+#define TLS_SET(key, value) (TlsSetValue(key, value) != 0)
+/* THREAD_SELF */
+#define THREAD_SELF() (GetCurrentThread())
+/* THREAD_YIELD */
+
+#define _WIN32_WINNT 0x0400
+#define THREAD_YIELD() (f_yield())
+
+/* THREAD_CREATE */
+
+#define THREAD_CREATE(thread, stacksize, priority, entrypoint, entryarg)
\
+ (((thread)->handle = (HANDLE)_beginthread((entrypoint), (stacksize),
(entryarg))) != (HANDLE)(-1) && \
+ hythread_set_priority((thread), (priority)) == 0)
+
+/* COND_NOTIFY_ALL */
+#define COND_NOTIFY_ALL(cond) SetEvent(cond)
+/* COND_WAIT_IF_TIMEDOUT */
+/* NOTE: the calling thread must already own mutex */
+#define ADJUST_TIMEOUT(millis, nanos) (((nanos) && ((millis) != ((IDATA)
(((UDATA)-1) >> 1)))) ? ((millis) + 1) : (millis))
+#define COND_WAIT_IF_TIMEDOUT(cond, mutex, millis, nanos) \
+ do {
\
+ DWORD starttime_ = GetTickCount(); \
+ IDATA initialtimeout_, timeout_, rc_; \
+ initialtimeout_ = timeout_ = ADJUST_TIMEOUT(millis, nanos);
\
+ while (1) { \
+ ResetEvent((cond));
\
+ MUTEX_EXIT(mutex);
\
+ rc_ = WaitForSingleObject((cond), timeout_); \
+ MUTEX_ENTER(mutex); \
+ if (rc_ == WAIT_TIMEOUT)
+
+#define COND_WAIT_TIMED_LOOP() \
+ timeout_ = initialtimeout_ - (GetTickCount() -
starttime_); \
+ if (timeout_ < 0) { timeout_ = 0; } \
+ } } while(0)
+
+/* COND_WAIT */
+/* NOTE: the calling thread must already own mutex */
+#define COND_WAIT(cond, mutex) \
+ do { \
+ ResetEvent((cond)); \
+ MUTEX_EXIT(mutex); \
+ WaitForSingleObject((cond), INFINITE); \
+ MUTEX_ENTER(mutex);
+
+#define COND_WAIT_LOOP() } while(1)
+
+/* COND_INIT */
+#define COND_INIT(cond) ((cond = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL)
+
+/* TLS_DESTROY */
+#define TLS_DESTROY(key) (TlsFree(key))
+
+/* THREAD_CANCEL */
+#define THREAD_CANCEL(thread) (TerminateThread(thread,
(DWORD)-1)&&WaitForSingleObject(thread,INFINITE))
+
+/* THREAD_EXIT */
+#define THREAD_EXIT() _endthread()
+
+/* THREAD_DETACH */
+#define THREAD_DETACH(thread) /* no need to do anything */
+
+/* THREAD_SET_PRIORITY */
+#define THREAD_SET_PRIORITY(thread, priority) (!SetThreadPriority((thread),
(priority)))
+
+/* SEM_CREATE */
+/* Arbitrary maximum count */
+#define SEM_CREATE(inval) CreateSemaphore(NULL,inval,2028,NULL)
+
+/* SEM_INIT */
+#define SEM_INIT(sm,pshrd,inval) (sm != NULL) ? 0: -1
+
+/* SEM_DESTROY */
+#define SEM_DESTROY(sm) CloseHandle(sm)
+
+/* SEM_FREE */
+#define SEM_FREE(s)
+
+/* SEM_POST */
+#define SEM_POST(sm) (ReleaseSemaphore((sm),1,NULL) ? 0 : -1)
+
+/* SEM_WAIT */
+#define SEM_WAIT(sm) ((WaitForSingleObject((sm), INFINITE) == WAIT_FAILED) ?
-1 : 0)
+
+/* SEM_TRYWAIT */
+#define SEM_TRYWAIT(sm) WaitForSingleObject(sm, 0)
+
+/* SEM_GETVALUE */
+#define SEM_GETVALUE(sm)
+#if !defined(HYVM_STATIC_LINKAGE)
+#define init_thread_library() (0)
+#endif
+
+#endif /* thrdsup_h */
--
1.4.4.4.g05d6b
>From f7f5b0e07f83c746fd20406b9853badbe4afb3f7 Mon Sep 17 00:00:00 2001
From: Salikh Zakirov <[EMAIL PROTECTED]>
Date: Thu, 1 Feb 2007 19:16:57 +0300
Subject: [PATCH] Fixed TLS_SET to return 0 on success, as expected by one caller
(and is consistent with pthread_setspecific)
---
.../portlib/src/main/native/port/windows/thrdsup.h | 2 +-
.../src/main/native/thread/windows/thrdsup.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/portlib/src/main/native/port/windows/thrdsup.h
b/modules/portlib/src/main/native/port/windows/thrdsup.h
index 1599bdb..214798c 100644
--- a/modules/portlib/src/main/native/port/windows/thrdsup.h
+++ b/modules/portlib/src/main/native/port/windows/thrdsup.h
@@ -52,7 +52,7 @@ extern DWORD unusedThreadID;
/* TLS_ALLOC */
#define TLS_ALLOC(key) ((key = TlsAlloc()) == 0xFFFFFFFF)
/* TLS_SET */
-#define TLS_SET(key, value) (TlsSetValue(key, value) != 0)
+#define TLS_SET(key, value) (TlsSetValue(key, value) == 0)
/* THREAD_SELF */
#define THREAD_SELF() (GetCurrentThread())
/* THREAD_YIELD */
diff --git a/modules/portlib/src/main/native/thread/windows/thrdsup.h
b/modules/portlib/src/main/native/thread/windows/thrdsup.h
index ed5d1ea..0408808 100644
--- a/modules/portlib/src/main/native/thread/windows/thrdsup.h
+++ b/modules/portlib/src/main/native/thread/windows/thrdsup.h
@@ -56,7 +56,7 @@ extern DWORD unusedThreadID;
/* TLS_ALLOC */
#define TLS_ALLOC(key) ((key = TlsAlloc()) == 0xFFFFFFFF)
/* TLS_SET */
-#define TLS_SET(key, value) (TlsSetValue(key, value))
+#define TLS_SET(key, value) (TlsSetValue(key, value) == 0)
/* THREAD_SELF */
#define THREAD_SELF() (GetCurrentThread())
/* THREAD_YIELD */
--
1.4.4.4.g05d6b