Changeset: 5f5bb6837930 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5f5bb6837930 Modified Files: gdk/gdk_bbp.c gdk/gdk_posix.c gdk/gdk_sample.c gdk/gdk_system.h gdk/gdk_tracer.c gdk/gdk_utils.c monetdb5/extras/rapi/rapi.c monetdb5/mal/mal.c monetdb5/mal/mal_dataflow.c monetdb5/mal/mal_namespace.c monetdb5/mal/mal_resource.c monetdb5/mal/mal_scenario.c monetdb5/modules/kernel/mmath.c monetdb5/modules/mal/querylog.c monetdb5/modules/mal/tablet.c monetdb5/modules/mal/wlc.c monetdb5/optimizer/opt_pipes.c sql/backends/monet5/UDF/capi/capi.c sql/backends/monet5/UDF/pyapi3/pyapi3.c sql/backends/monet5/sql_scenario.c sql/backends/monet5/wlr.c sql/storage/bat/bat_storage.c sql/storage/store.c tools/monetdbe/monetdbe.c Branch: default Log Message:
With some slight hackery we can have "static" initialization of locks on Windows. The initialization is not static, but does happen before main is called, so we don't need run-time initialization of static/extern locks. diffs (truncated from 472 to 300 lines): diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -235,7 +235,7 @@ static volatile MT_Id locked_by = 0; } while (0) static int BBPunloadCnt = 0; -static MT_Lock GDKunloadLock = MT_LOCK_INITIALIZER("GDKunloadLock"); +static MT_Lock GDKunloadLock = MT_LOCK_INITIALIZER(GDKunloadLock); void BBPlock(void) diff --git a/gdk/gdk_posix.c b/gdk/gdk_posix.c --- a/gdk/gdk_posix.c +++ b/gdk/gdk_posix.c @@ -1048,7 +1048,7 @@ MT_sleep_ms(unsigned int ms) } #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) || !defined(HAVE_ASCTIME_R) || !defined(HAVE_CTIME_R) -static MT_Lock timelock = MT_LOCK_INITIALIZER("timelock"); +static MT_Lock timelock = MT_LOCK_INITIALIZER(timelock); #endif #ifndef HAVE_LOCALTIME_R @@ -1108,7 +1108,7 @@ ctime_r(const time_t *restrict t, char * #endif #ifndef HAVE_STRERROR_R -static MT_Lock strerrlock = MT_LOCK_INITIALIZER("strerrlock"); +static MT_Lock strerrlock = MT_LOCK_INITIALIZER(strerrlock); int strerror_r(int errnum, char *buf, size_t buflen) diff --git a/gdk/gdk_sample.c b/gdk/gdk_sample.c --- a/gdk/gdk_sample.c +++ b/gdk/gdk_sample.c @@ -172,11 +172,11 @@ BATsample_with_seed(BAT *b, BUN n, unsig return do_batsample(b, n, rse, NULL); } +static MT_Lock rse_lock = MT_LOCK_INITIALIZER(rse_lock); BAT * BATsample(BAT *b, BUN n) { static random_state_engine rse; - static MT_Lock rse_lock = MT_LOCK_INITIALIZER("rse_lock"); MT_lock_set(&rse_lock); if (rse[0] == 0 && rse[1] == 0 && rse[2] == 0 && rse[3] == 0) diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h --- a/gdk/gdk_system.h +++ b/gdk/gdk_system.h @@ -172,17 +172,11 @@ gdk_export int MT_join_thread(MT_Id t); #include "matomic.h" /* define this to keep lock statistics (can be expensive) */ -/* #define LOCK_STATS */ +/* #define LOCK_STATS 1 */ /* define this if you want to use pthread (or Windows) locks instead * of atomic instructions for locking (latching) */ -#ifndef WIN32 -/* on Linux (and in general pthread using systems) use native locks; - * on Windows use locks based on atomic instructions and sleeps since - * the Windows lock implementations (Mutex and CriticalSection) are - * too heavy and impossible to initialize statically */ #define USE_NATIVE_LOCKS 1 -#endif #ifdef LOCK_STATS @@ -302,11 +296,29 @@ typedef struct MT_Lock { #endif } MT_Lock; -#ifdef LOCK_STATS -#define MT_LOCK_INITIALIZER(n) { .lock = NULL, .name = n, .next = (struct MT_Lock *) -1, } +/* Windows defines read as _read and adds a deprecation warning to read + * if you were to still use that. We need the token "read" here. We + * cannot simply #undef read, since that messes up the deprecation + * stuff. So we define _read as read to change the token back to "read" + * where replacement stops (recursive definitions are allowed in C and + * are handled well). After our use, we remove the definition of _read + * so everything reverts back to the way it was. Bonus: this also works + * if "read" was not defined. */ +#define _read read +#pragma section(".CRT$XCU", read) +#undef _read +#ifdef _WIN64 +#define _LOCK_PREF_ "" #else -#define MT_LOCK_INITIALIZER(n) { .lock = NULL, .name = n, } +#define _LOCK_PREF_ "_" #endif +#define MT_LOCK_INITIALIZER(n) { 0 }; \ +static void wininit_##n(void) \ +{ \ + MT_lock_init(&n, #n); \ +} \ +__declspec(allocate(".CRT$XCU")) void (*wininit_##n##_)(void) = wininit_##n; \ +__pragma(comment(linker, "/include:" _LOCK_PREF_ "wininit_" #n "_")) #pragma intrinsic(_InterlockedCompareExchangePointer) @@ -321,12 +333,7 @@ typedef struct MT_Lock { static bool inline MT_lock_try(MT_Lock *l) { - if (l->lock == NULL) { - HANDLE p = CreateMutex(NULL, 0, NULL); - if (_InterlockedCompareExchangePointer( - &l->lock, p, NULL) != NULL) - CloseHandle(p); - } + assert(l->lock != NULL); return WaitForSingleObject(l->lock, 0) == WAIT_OBJECT_0; } @@ -377,9 +384,9 @@ typedef struct MT_Lock { } MT_Lock; #ifdef LOCK_STATS -#define MT_LOCK_INITIALIZER(n) { .lock = PTHREAD_MUTEX_INITIALIZER, .name = n, .next = (struct MT_Lock *) -1, } +#define MT_LOCK_INITIALIZER(n) { .lock = PTHREAD_MUTEX_INITIALIZER, .name = #n, .next = (struct MT_Lock *) -1, } #else -#define MT_LOCK_INITIALIZER(n) { .lock = PTHREAD_MUTEX_INITIALIZER, .name = n, } +#define MT_LOCK_INITIALIZER(n) { .lock = PTHREAD_MUTEX_INITIALIZER, .name = #n, } #endif #define MT_lock_init(l, n) \ @@ -442,9 +449,9 @@ typedef struct MT_Lock { } MT_Lock; #ifdef LOCK_STATS -#define MT_LOCK_INITIALIZER(n) { .next = (struct MT_Lock *) -1, .name = n, } +#define MT_LOCK_INITIALIZER(n) { .next = (struct MT_Lock *) -1, .name = #n, } #else -#define MT_LOCK_INITIALIZER(n) { .name = n, } +#define MT_LOCK_INITIALIZER(n) { .name = #n, } #endif #define MT_lock_try(l) (ATOMIC_TAS(&(l)->lock) == 0) diff --git a/gdk/gdk_tracer.c b/gdk/gdk_tracer.c --- a/gdk/gdk_tracer.c +++ b/gdk/gdk_tracer.c @@ -23,7 +23,7 @@ #define GENERATE_STRING(STRING) #STRING, static FILE *active_tracer; -MT_Lock lock = MT_LOCK_INITIALIZER("GDKtracer_1"); +MT_Lock GDKtracer_lock = MT_LOCK_INITIALIZER(GDKtracer_lock); static char file_name[FILENAME_MAX]; @@ -145,11 +145,11 @@ set_level_for_layer(int layer, int lvl) log_level_t level = (log_level_t) lvl; // make sure we initialize before changing the component level - MT_lock_set(&lock); + MT_lock_set(&GDKtracer_lock); if (file_name[0] == 0) { _GDKtracer_init_basic_adptr(); } - MT_lock_unset(&lock); + MT_lock_unset(&GDKtracer_lock); for (int i = 0; i < COMPONENTS_COUNT; i++) { if (layer == MDB_ALL) { @@ -257,7 +257,7 @@ GDKtracer_reinit_basic(int sig) return; // Make sure that GDKtracer is not trying to flush the buffer - MT_lock_set(&lock); + MT_lock_set(&GDKtracer_lock); if (active_tracer) { if (active_tracer != stderr) @@ -268,7 +268,7 @@ GDKtracer_reinit_basic(int sig) } _GDKtracer_init_basic_adptr(); - MT_lock_unset(&lock); + MT_lock_unset(&GDKtracer_lock); } @@ -295,11 +295,11 @@ GDKtracer_set_component_level(const char } // make sure we initialize before changing the component level - MT_lock_set(&lock); + MT_lock_set(&GDKtracer_lock); if (file_name[0] == 0) { _GDKtracer_init_basic_adptr(); } - MT_lock_unset(&lock); + MT_lock_unset(&GDKtracer_lock); lvl_per_component[component] = level; @@ -510,12 +510,12 @@ GDKtracer_log(const char *file, const ch if (active_tracer == NULL || active_tracer == stderr) return; } - MT_lock_set(&lock); + MT_lock_set(&GDKtracer_lock); if (file_name[0] == 0) { - MT_lock_unset(&lock); + MT_lock_unset(&GDKtracer_lock); return; } - MT_lock_unset(&lock); + MT_lock_unset(&GDKtracer_lock); if (syserr) fprintf(active_tracer, "%s: %s\n", buffer, syserr); else diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c --- a/gdk/gdk_utils.c +++ b/gdk/gdk_utils.c @@ -630,7 +630,7 @@ static gdk_return GDKlockHome(int farmid #ifndef STATIC_CODE_ANALYSIS #ifndef NDEBUG -static MT_Lock mallocsuccesslock = MT_LOCK_INITIALIZER("mallocsuccesslk"); +static MT_Lock mallocsuccesslock = MT_LOCK_INITIALIZER(mallocsuccesslock); #endif #endif @@ -1157,9 +1157,9 @@ GDKexit(int status) batlock_t GDKbatLock[BBP_BATMASK + 1]; bbplock_t GDKbbpLock[BBP_THREADMASK + 1]; -MT_Lock GDKnameLock = MT_LOCK_INITIALIZER("GDKnameLock"); -MT_Lock GDKthreadLock = MT_LOCK_INITIALIZER("GDKthreadLock"); -MT_Lock GDKtmLock = MT_LOCK_INITIALIZER("GDKtmLock"); +MT_Lock GDKnameLock = MT_LOCK_INITIALIZER(GDKnameLock); +MT_Lock GDKthreadLock = MT_LOCK_INITIALIZER(GDKthreadLock); +MT_Lock GDKtmLock = MT_LOCK_INITIALIZER(GDKtmLock); /* * @+ Concurrency control diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c --- a/monetdb5/extras/rapi/rapi.c +++ b/monetdb5/extras/rapi/rapi.c @@ -360,7 +360,7 @@ static bool RAPIEnabled(void) { } // The R-environment should be single threaded, calling for some protective measures. -static MT_Lock rapiLock = MT_LOCK_INITIALIZER("rapiLock"); +static MT_Lock rapiLock = MT_LOCK_INITIALIZER(rapiLock); static bool rapiInitialized = false; #if 0 static char* rtypenames[] = { "NIL", "SYM", "LIST", "CLO", "ENV", "PROM", diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c --- a/monetdb5/mal/mal.c +++ b/monetdb5/mal/mal.c @@ -34,12 +34,12 @@ lng MALdebug; #include "mal_resource.h" #include "mal_atom.h" -MT_Lock mal_contextLock = MT_LOCK_INITIALIZER("mal_contextLock"); -MT_Lock mal_remoteLock = MT_LOCK_INITIALIZER("mal_remoteLock"); -MT_Lock mal_profileLock = MT_LOCK_INITIALIZER("mal_profileLock"); -MT_Lock mal_copyLock = MT_LOCK_INITIALIZER("mal_copyLock"); -MT_Lock mal_delayLock = MT_LOCK_INITIALIZER("mal_delayLock"); -MT_Lock mal_oltpLock = MT_LOCK_INITIALIZER("mal_oltpLock"); +MT_Lock mal_contextLock = MT_LOCK_INITIALIZER(mal_contextLock); +MT_Lock mal_remoteLock = MT_LOCK_INITIALIZER(mal_remoteLock); +MT_Lock mal_profileLock = MT_LOCK_INITIALIZER(mal_profileLock); +MT_Lock mal_copyLock = MT_LOCK_INITIALIZER(mal_copyLock); +MT_Lock mal_delayLock = MT_LOCK_INITIALIZER(mal_delayLock); +MT_Lock mal_oltpLock = MT_LOCK_INITIALIZER(mal_oltpLock); /* * Initialization of the MAL context diff --git a/monetdb5/mal/mal_dataflow.c b/monetdb5/mal/mal_dataflow.c --- a/monetdb5/mal/mal_dataflow.c +++ b/monetdb5/mal/mal_dataflow.c @@ -89,7 +89,7 @@ static struct worker { static Queue *todo = 0; /* pending instructions */ static ATOMIC_TYPE exiting = ATOMIC_VAR_INIT(0); -static MT_Lock dataflowLock = MT_LOCK_INITIALIZER("dataflowLock"); +static MT_Lock dataflowLock = MT_LOCK_INITIALIZER(dataflowLock); static void stopMALdataflow(void); void diff --git a/monetdb5/mal/mal_namespace.c b/monetdb5/mal/mal_namespace.c --- a/monetdb5/mal/mal_namespace.c +++ b/monetdb5/mal/mal_namespace.c @@ -18,7 +18,7 @@ #define MAXIDENTIFIERS 4096 #define HASHMASK 4095 -MT_Lock mal_namespaceLock = MT_LOCK_INITIALIZER("mal_namespaceLk"); +MT_Lock mal_namespaceLock = MT_LOCK_INITIALIZER(mal_namespaceLock); /* taken from gdk_atoms */ #define NME_HASH(_key,y,K) \ diff --git a/monetdb5/mal/mal_resource.c b/monetdb5/mal/mal_resource.c _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list