Changeset: 54dd0625ee0b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/54dd0625ee0b
Modified Files:
clients/Tests/exports.stable.out
gdk/gdk_system.c
gdk/gdk_system.h
sql/backends/monet5/UDF/capi/capi.c
Branch: default
Log Message:
Use thread-local storage instead of arrays indexed by thread id for CAPI.
diffs (276 lines):
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -357,6 +357,7 @@ size_t HEAPvmsize(Heap *h);
void IMPSdestroy(BAT *b);
lng IMPSimprintsize(BAT *b);
int MT_access(const char *pathname, int mode);
+gdk_return MT_alloc_tls(MT_TLS_t *newkey);
int MT_check_nr_cores(void);
void MT_cond_broadcast(MT_Cond *cond);
void MT_cond_destroy(MT_Cond *cond);
@@ -393,6 +394,8 @@ void MT_thread_setdata(void *data);
void MT_thread_setlockwait(MT_Lock *lock);
void MT_thread_setsemawait(MT_Sema *sema);
void MT_thread_setworking(const char *work);
+void *MT_tls_get(MT_TLS_t key);
+void MT_tls_set(MT_TLS_t key, void *val);
void OIDXdestroy(BAT *b);
ssize_t OIDfromStr(const char *src, size_t *len, oid **dst, bool external);
ssize_t OIDtoStr(str *dst, size_t *len, const oid *src, bool external);
diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -225,11 +225,11 @@ static pthread_key_t threadkey;
#define thread_setself(self) pthread_setspecific(threadkey, self)
#else
static CRITICAL_SECTION winthread_cs;
-static DWORD threadslot = TLS_OUT_OF_INDEXES;
+static DWORD threadkey = TLS_OUT_OF_INDEXES;
#define thread_lock() EnterCriticalSection(&winthread_cs)
#define thread_unlock() LeaveCriticalSection(&winthread_cs)
-#define thread_self() TlsGetValue(threadslot)
-#define thread_setself(self) TlsSetValue(threadslot, self)
+#define thread_self() TlsGetValue(threadkey)
+#define thread_setself(self) TlsSetValue(threadkey, self)
#endif
static bool thread_initialized = false;
@@ -361,16 +361,16 @@ MT_thread_init(void)
return false;
}
#else
- threadslot = TlsAlloc();
- if (threadslot == TLS_OUT_OF_INDEXES) {
+ threadkey = TlsAlloc();
+ if (threadkey == TLS_OUT_OF_INDEXES) {
GDKwinerror("Creating thread-local slot for thread failed");
return false;
}
mainthread.wtid = GetCurrentThreadId();
if (thread_setself(&mainthread) == 0) {
GDKwinerror("Setting thread-local value failed");
- TlsFree(threadslot);
- threadslot = TLS_OUT_OF_INDEXES;
+ TlsFree(threadkey);
+ threadkey = TLS_OUT_OF_INDEXES;
return false;
}
InitializeCriticalSection(&winthread_cs);
@@ -457,6 +457,46 @@ find_mtthread(MT_Id tid)
return t;
}
+gdk_return
+MT_alloc_tls(MT_TLS_t *newkey)
+{
+#ifdef HAVE_PTHREAD_H
+ int ret;
+ if ((ret = pthread_key_create(newkey, NULL)) != 0) {
+ GDKsyserr(ret, "Creating TLS key for thread failed");
+ return GDK_FAIL;
+ }
+#else
+ if ((*newkey = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
+ GDKwinerror("Creating TLS key for thread failed");
+ return GDK_FAIL;
+ }
+#endif
+ return GDK_SUCCEED;
+}
+
+void
+MT_tls_set(MT_TLS_t key, void *val)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_setspecific(key, val);
+#else
+ assert(key != TLS_OUT_OF_INDEXES);
+ TlsSetValue(key, val);
+#endif
+}
+
+void *
+MT_tls_get(MT_TLS_t key)
+{
+#ifdef HAVE_PTHREAD_H
+ return pthread_getspecific(key);
+#else
+ assert(key != TLS_OUT_OF_INDEXES);
+ return TlsGetValue(key);
+#endif
+}
+
const char *
MT_thread_getname(void)
{
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -436,6 +436,8 @@ typedef struct MT_RWLock {
#define MT_rwlock_wrunlock(l) ReleaseSRWLockExclusive(&(l)->lock)
+typedef DWORD MT_TLS_t;
+
#else
typedef struct MT_Lock {
@@ -606,8 +608,14 @@ MT_rwlock_wrtry(MT_RWLock *l)
#endif
+typedef pthread_key_t MT_TLS_t;
+
#endif
+gdk_export gdk_return MT_alloc_tls(MT_TLS_t *newkey);
+gdk_export void MT_tls_set(MT_TLS_t key, void *val);
+gdk_export void *MT_tls_get(MT_TLS_t key);
+
#ifdef LOCK_STATS
gdk_export void GDKlockstatistics(int);
gdk_export MT_Lock * volatile GDKlocklist;
diff --git a/sql/backends/monet5/UDF/capi/capi.c
b/sql/backends/monet5/UDF/capi/capi.c
--- a/sql/backends/monet5/UDF/capi/capi.c
+++ b/sql/backends/monet5/UDF/capi/capi.c
@@ -39,7 +39,6 @@ static bool option_enable_mprotect = fal
const char *longjmp_enableflag = "enable_longjmp";
static bool option_enable_longjmp = false;
-struct _allocated_region;
typedef struct _allocated_region {
struct _allocated_region *next;
} allocated_region;
@@ -54,8 +53,11 @@ typedef struct _mprotected_region {
static char *mprotect_region(void *addr, size_t len,
mprotected_region
**regions);
-static allocated_region *allocated_regions[THREADS];
-static jmp_buf jump_buffer[THREADS];
+struct capi_tls_s {
+ allocated_region *ar;
+ jmp_buf jb;
+};
+static MT_TLS_t capi_tls_key;
typedef char *(*jitted_function)(void **inputs, void **outputs,
malloc_function_ptr malloc, free_function_ptr free);
@@ -94,6 +96,7 @@ static str CUDFprelude(void)
cudf_initialized = true;
option_enable_mprotect = GDKgetenv_istrue(mprotect_enableflag)
|| GDKgetenv_isyes(mprotect_enableflag);
option_enable_longjmp = GDKgetenv_istrue(longjmp_enableflag) ||
GDKgetenv_isyes(longjmp_enableflag);
+ MT_alloc_tls(&capi_tls_key);
}
return MAL_SUCCEED;
}
@@ -111,13 +114,12 @@ static bool WriteTextToFile(FILE *f, con
static _Noreturn void handler(int sig, siginfo_t *si, void *unused)
{
- MT_Id tid = MT_getpid();
-
(void)sig;
(void)si;
(void)unused;
- longjmp(jump_buffer[tid-1], 1);
+ struct capi_tls_s *tls = MT_tls_get(capi_tls_key);
+ longjmp(tls->jb, 1);
}
static bool can_mprotect_region(void* addr) {
@@ -173,18 +175,18 @@ static void *jump_GDK_malloc(size_t size
return NULL;
void *ptr = GDKmalloc(size);
if (!ptr && option_enable_longjmp) {
- longjmp(jump_buffer[MT_getpid()-1], 2);
+ struct capi_tls_s *tls = MT_tls_get(capi_tls_key);
+ longjmp(tls->jb, 2);
}
return ptr;
}
-static void *add_allocated_region(void *ptr)
+static inline void *add_allocated_region(void *ptr)
{
- allocated_region *region;
- MT_Id tid = MT_getpid();
- region = (allocated_region *)ptr;
- region->next = allocated_regions[tid-1];
- allocated_regions[tid-1] = region;
+ allocated_region *region = (allocated_region *)ptr;
+ struct capi_tls_s *tls = MT_tls_get(capi_tls_key);
+ region->next = tls->ar;
+ tls->ar = region;
return (char *)ptr + sizeof(allocated_region);
}
@@ -215,7 +217,10 @@ static void wrapped_GDK_free(void* ptr)
}
\
b = COLnew(0, TYPE_##tpename, count, TRANSIENT);
\
if (!b) {
\
- if (option_enable_longjmp)
longjmp(jump_buffer[MT_getpid()-1], 2); \
+ if (option_enable_longjmp) {
\
+ struct capi_tls_s *tls =
MT_tls_get(capi_tls_key); \
+ longjmp(tls->jb, 2);
\
+ }
\
else return;
\
}
\
self->bat = (void*) b;
\
@@ -480,7 +485,6 @@ static str CUDFeval(Client cntxt, MalBlk
BUN expression_hash = 0, funcname_hash = 0;
cached_functions *cached_function;
char *function_parameters = NULL;
- MT_Id tid = MT_getpid();
size_t input_size = 0;
bit non_grouped_aggregate = 0;
@@ -490,9 +494,12 @@ static str CUDFeval(Client cntxt, MalBlk
size_t extra_inputs = 0;
- (void)cntxt;
+ struct capi_tls_s tls;
- allocated_regions[tid-1] = NULL;
+ tls.ar = NULL;
+ MT_tls_set(capi_tls_key, &tls);
+
+ (void)cntxt;
if (!GDKgetenv_istrue("embedded_c") && !GDKgetenv_isyes("embedded_c"))
throw(MAL, "cudf.eval", "Embedded C has not been enabled. "
@@ -1325,7 +1332,8 @@ static str CUDFeval(Client cntxt, MalBlk
// this longjmp point is used for some error handling in the C function
// such as failed mallocs
if (option_enable_longjmp) {
- ret = setjmp(jump_buffer[tid-1]);
+ struct capi_tls_s *tls = MT_tls_get(capi_tls_key);
+ ret = setjmp(tls->jb);
if (ret < 0) {
// error value
msg = createException(MAL, "cudf.eval", "Failed setjmp:
%s",
@@ -1588,6 +1596,7 @@ wrapup:
GDKfree(fname);
GDKfree(oname);
GDKfree(libname);
+ MT_tls_set(capi_tls_key, NULL);
if (option_enable_mprotect) {
if (sa.sa_sigaction) {
(void) sigaction(SIGSEGV, &oldsa, NULL);
@@ -1603,10 +1612,10 @@ wrapup:
regions = next;
}
}
- while (allocated_regions[tid-1]) {
- allocated_region *next = allocated_regions[tid-1]->next;
- GDKfree(allocated_regions[tid-1]);
- allocated_regions[tid-1] = next;
+ while (tls.ar != NULL) {
+ allocated_region *next = tls.ar->next;
+ GDKfree(tls.ar);
+ tls.ar = next;
}
if (option_enable_mprotect) {
// block segfaults and bus errors again after we exit
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]