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

Reply via email to