Changeset: e1ab5c093c74 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e1ab5c093c74
Branch: strimps_update
Log Message:

Merge with default


diffs (truncated from 3259 to 300 lines):

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -763,3 +763,4 @@ cab90a348501b045e19cee5cebcc44f3800bd0a8
 5872f047d97c98d3a848514438b8f97fa446855d Jan2022_11
 025239a5a6f122042798c0f1132a2c6298514e06 Jan2022_13
 025239a5a6f122042798c0f1132a2c6298514e06 Jan2022_SP2_release
+2e54857a91306cc6304825c5596f65d00595db6b Jul2021_23
diff --git a/MonetDB.spec b/MonetDB.spec
--- a/MonetDB.spec
+++ b/MonetDB.spec
@@ -365,6 +365,7 @@ developer.
 %{_bindir}/smack00
 %{_bindir}/smack01
 %{_bindir}/streamcat
+%{_bindir}/testcondvar
 %{_bindir}/testgetinfo
 %{_bindir}/testStmtAttr
 %{_bindir}/malsample.pl
diff --git a/buildtools/conf/Maddlog b/buildtools/conf/Maddlog
--- a/buildtools/conf/Maddlog
+++ b/buildtools/conf/Maddlog
@@ -189,6 +189,9 @@ fi
 
 file=ChangeLog.$RANDOM
 
+# make sure we get the correct day and month names
+export LC_ALL=en_US.utf-8
+
 case "$CL" in
 */*)
     cd "${CL%/*}"
diff --git a/clients/Tests/All b/clients/Tests/All
--- a/clients/Tests/All
+++ b/clients/Tests/All
@@ -3,3 +3,4 @@ HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&H
 
!HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&HAVE_LIBPY3&HAVE_NETCDF&HAVE_SHP&NOT_WIN32?MAL-signatures
 NOT_WIN32&MERCURIAL?melcheck
 mclient-uri
+testcondvar
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
@@ -536,23 +536,23 @@ ssize_t lngFromStr(const char *src, size
 ssize_t lngToStr(str *dst, size_t *len, const lng *src, bool external);
 const lng lng_nil;
 struct tm *localtime_r(const time_t *restrict, struct tm *restrict);
+gdk_return log_activate(logger *lg);
 gdk_return log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt);
 gdk_return log_bat_clear(logger *lg, log_id id);
 gdk_return log_bat_persists(logger *lg, BAT *b, log_id id);
 gdk_return log_bat_transient(logger *lg, log_id id);
+lng log_changes(logger *lg);
 gdk_return log_constant(logger *lg, int type, ptr val, log_id id, lng offset, 
lng cnt);
+logger *log_create(int debug, const char *fn, const char *logdir, int version, 
preversionfix_fptr prefuncp, postversionfix_fptr postfuncp, void *funcdata);
 gdk_return log_delta(logger *lg, BAT *uid, BAT *uval, log_id id);
-gdk_return log_sequence(logger *lg, int seq, lng id);
+void log_destroy(logger *lg);
+log_bid log_find_bat(logger *lg, log_id id);
+gdk_return log_flush(logger *lg, ulng saved_id);
+int log_sequence(logger *lg, int seq, lng *id);
 gdk_return log_tend(logger *lg);
 gdk_return log_tflush(logger *lg, ulng log_file_id, ulng commit_ts);
+gdk_return log_tsequence(logger *lg, int seq, lng id);
 gdk_return log_tstart(logger *lg, bool flushnow, ulng *log_file_id);
-gdk_return logger_activate(logger *lg);
-lng logger_changes(logger *lg);
-logger *logger_create(int debug, const char *fn, const char *logdir, int 
version, preversionfix_fptr prefuncp, postversionfix_fptr postfuncp, void 
*funcdata);
-void logger_destroy(logger *lg);
-log_bid logger_find_bat(logger *lg, log_id id);
-gdk_return logger_flush(logger *lg, ulng saved_id);
-int logger_sequence(logger *lg, int seq, lng *id);
 log_level_t lvl_per_component[];
 void *mdlopen(const char *library, int mode);
 const char *mercurial_revision(void) __attribute__((__const__));
diff --git a/clients/Tests/testcondvar.py b/clients/Tests/testcondvar.py
new file mode 100644
--- /dev/null
+++ b/clients/Tests/testcondvar.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import subprocess
+import sys
+
+try:
+    subprocess.check_output("testcondvar", stderr=subprocess.STDOUT)
+except subprocess.CalledProcessError as e:
+    output = str(e.stdout, 'utf-8')
+    if not output.endswith('\n'):
+        output += '\n'
+    print(f"Test program failed with the following output:\n------", 
file=sys.stderr)
+    print(f"{output}-----", file=sys.stderr)
+    sys.exit('TEST FAILED')
diff --git a/clients/examples/C/CMakeLists.txt 
b/clients/examples/C/CMakeLists.txt
--- a/clients/examples/C/CMakeLists.txt
+++ b/clients/examples/C/CMakeLists.txt
@@ -45,6 +45,16 @@ if(TESTING)
     monetdb_config_header
     stream)
 
+  add_executable(testcondvar
+    testcondvar.c)
+
+  target_link_libraries(testcondvar
+    PRIVATE
+    monetdb_config_header
+    bat
+    Threads::Threads
+  )
+
   add_executable(bincopydata
     bincopydata.c
     bincopydata.h
@@ -75,6 +85,7 @@ if(TESTING)
     smack00
     smack01
     streamcat
+    testcondvar
     bincopydata
     RUNTIME
     DESTINATION
@@ -89,6 +100,7 @@ if(TESTING)
       $<TARGET_PDB_FILE:smack00>
       $<TARGET_PDB_FILE:smack01>
       $<TARGET_PDB_FILE:streamcat>
+      $<TARGET_PDB_FILE:testcondvar>
       $<TARGET_PDB_FILE:bincopydata>
       $<TARGET_PDB_FILE:bincopyloops>
       DESTINATION ${CMAKE_INSTALL_BINDIR}
diff --git a/clients/examples/C/testcondvar.c b/clients/examples/C/testcondvar.c
new file mode 100644
--- /dev/null
+++ b/clients/examples/C/testcondvar.c
@@ -0,0 +1,183 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V.
+ */
+
+#include "monetdb_config.h"
+#include "gdk.h"
+#include "gdk_system.h"
+
+#include <assert.h>
+
+#define NN (3)
+
+volatile int timeout = 100; // set this to 0 during interactive debugging
+
+/* global state protected by a lock: */
+
+MT_Lock lock = MT_LOCK_INITIALIZER(lock);
+MT_Cond condvar = MT_COND_INITIALIZER(the_condvar);
+struct state {
+       MT_Id id;
+       int ticks;
+       int permits;
+       bool terminate;
+       bool terminated;
+} states[NN] = { {0} };
+
+
+static void
+let_run(void)
+{
+       MT_lock_unset(&lock);
+
+       MT_sleep_ms(100);
+
+       int attempts = 0;
+       while (!MT_lock_try(&lock)) {
+               if (timeout > 0 && ++attempts > timeout) {
+                       fprintf(stderr, "Can't get hold of the lock after %d 
attempts\n", attempts);
+                       abort();
+               }
+               MT_sleep_ms(10);
+       }
+
+       fprintf(stderr, "\n");
+}
+
+
+static void
+worker(void *arg)
+{
+       struct state *st = arg;
+       int id = (int)(st - &states[0]);
+       fprintf(stderr, "worker %d starting\n", id);
+
+       MT_lock_set(&lock);
+       while (1) {
+               if (st->terminate) {
+                       fprintf(stderr, "worker %d terminating\n", id);
+                       break;
+               }
+               if (st->permits > 0) {
+                       fprintf(stderr, "worker %d ticking\n", id);
+                       st->ticks++;
+                       st->permits--;
+               }
+               fprintf(stderr, "worker %d waiting\n", id);
+               MT_cond_wait(&condvar, &lock);
+               fprintf(stderr, "worker %d woke up\n", id);
+       }
+       st->terminated = true;
+       MT_lock_unset(&lock);
+}
+
+
+static void clear(void)
+{
+       for (int i = 0; i < NN; i++) {
+               struct state *st = &states[i];
+               st->permits = 0;
+               st->ticks = 0;
+       }
+}
+
+
+static void
+check_impl(int line, int expected_sum_ticks, int expected_max_ticks, int 
expected_sum_permits)
+{
+       int sum_ticks = 0;
+       int max_ticks = -1;
+       int sum_permits = 0;
+
+       for (int i = 0; i < NN; i++) {
+               sum_permits += states[i].permits;
+               int ticks = states[i].ticks;
+               sum_ticks += ticks;
+               if (ticks > max_ticks)
+                       max_ticks = ticks;
+       }
+
+       bool good = true;
+       good &= (sum_ticks == expected_sum_ticks);
+       good &= (max_ticks == expected_max_ticks);
+       good &= (sum_permits == expected_sum_permits);
+       if (good)
+               return;
+
+       fprintf(stderr, "\nOn line %d:\n", line);
+       fprintf(stderr, "Expect sum ticks to be %d, is %d\n", 
expected_sum_ticks, sum_ticks);
+       fprintf(stderr, "Expect max ticks to be %d, is %d\n", 
expected_max_ticks, max_ticks);
+       fprintf(stderr, "Expect sum permits to be %d, is %d\n", 
expected_sum_permits, sum_permits);
+       for (int i = 0; i < NN; i++) {
+               fprintf(stderr, "worker %d: ticks=%d permits=%d\n", i, 
states[i].ticks, states[i].permits);
+       }
+       abort();
+}
+
+#define check(expected_sum, expected_max, expected_permits) 
check_impl(__LINE__, expected_sum, expected_max, expected_permits)
+
+int
+main(void)
+{
+       MT_thread_init();
+
+       MT_lock_set(&lock);
+       check(0, 0, 0);
+
+       for (int i = 0; i < NN; i++) {
+               struct state *st = &states[i];
+               char name[MT_NAME_LEN];
+               snprintf(name, sizeof(name), "worker%d", i);
+               MT_create_thread(&st->id, worker, st, MT_THR_JOINABLE, name);
+       }
+       check(0, 0, 0);
+
+       let_run();
+       check(0, 0, 0);
+
+       // give them all a permit and broadcast on the condvar. they should all 
run
+       for (int i = 0; i < NN; i++)
+               states[i].permits = 1;
+       let_run();
+       // haven't notified them yet:
+       check(0, 0, 3);
+       MT_cond_broadcast(&condvar);
+       let_run();
+       check(3, 1, 0);
+
+       // when using signal, we need to trigger them three times
+       clear();
+       for (int i = 0; i < NN; i++)
+               states[i].permits = 1;
+       let_run();
+       check(0, 0, 3);
+       MT_cond_signal(&condvar);
+       let_run();
+       check(1, 1, 2);
+       MT_cond_signal(&condvar);
+       let_run();
+       check(2, 1, 1);
+       MT_cond_signal(&condvar);
+       let_run();
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to