Changeset: 66024113e38e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/66024113e38e
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
Branch: default
Log Message:

Merge qcancel branch into default.


diffs (truncated from 4933 to 300 lines):

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -47,6 +47,7 @@ tags
 *.pyo
 *.rej
 *.orig
+compile_commands.json
 
 # package building on Mac OS X
 MacOSX/build
diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -8354,6 +8354,7 @@ stdout of test 'MAL-signatures` in direc
 [ "clients",   "ripemd160sum", "command clients.ripemd160sum(X_0:str):str ",   
"CLTripemd160sum;",     ""      ]
 [ "clients",   "setListing",   "pattern clients.setListing(X_0:int):int ",     
"CLTsetListing;",       ""      ]
 [ "clients",   "setPassword",  "pattern clients.setPassword(X_0:str, 
X_1:str):void ",  "CLTsetPassword;",      ""      ]
+[ "clients",   "setQryTimeoutMicro",   "pattern 
clients.setQryTimeoutMicro(X_0:lng):void ",    "CLTqueryTimeoutMicro;",        
""      ]
 [ "clients",   "setScenario",  "pattern clients.setScenario(X_0:str):str ",    
"CLTsetScenario;",      ""      ]
 [ "clients",   "setmemorylimit",       "pattern 
clients.setmemorylimit(X_0:int):void ",        "CLTsetmemorylimit;",   ""      ]
 [ "clients",   "setmemorylimit",       "pattern 
clients.setmemorylimit(X_0:int, X_1:int):void ",       "CLTsetmemorylimit;",   
""      ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -11640,6 +11640,7 @@ stdout of test 'MAL-signatures` in direc
 [ "clients",   "ripemd160sum", "command clients.ripemd160sum(X_0:str):str ",   
"CLTripemd160sum;",     ""      ]
 [ "clients",   "setListing",   "pattern clients.setListing(X_0:int):int ",     
"CLTsetListing;",       ""      ]
 [ "clients",   "setPassword",  "pattern clients.setPassword(X_0:str, 
X_1:str):void ",  "CLTsetPassword;",      ""      ]
+[ "clients",   "setQryTimeoutMicro",   "pattern 
clients.setQryTimeoutMicro(X_0:lng):void ",    "CLTqueryTimeoutMicro;",        
""      ]
 [ "clients",   "setScenario",  "pattern clients.setScenario(X_0:str):str ",    
"CLTsetScenario;",      ""      ]
 [ "clients",   "setmemorylimit",       "pattern 
clients.setmemorylimit(X_0:int):void ",        "CLTsetmemorylimit;",   ""      ]
 [ "clients",   "setmemorylimit",       "pattern 
clients.setmemorylimit(X_0:int, X_1:int):void ",       "CLTsetmemorylimit;",   
""      ]
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
@@ -369,10 +369,12 @@ int MT_rename(const char *old, const cha
 int MT_rmdir(const char *dirname);
 void MT_sleep_ms(unsigned int ms);
 int MT_stat(const char *filename, struct stat *stb);
+QryCtx *MT_thread_get_qry_ctx(void);
 const char *MT_thread_getalgorithm(void);
 void *MT_thread_getdata(void);
 const char *MT_thread_getname(void);
 bool MT_thread_init(void);
+void MT_thread_set_qry_ctx(QryCtx *ctx);
 void MT_thread_setalgorithm(const char *algo);
 void MT_thread_setdata(void *data);
 void MT_thread_setlockwait(MT_Lock *lock);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -450,7 +450,7 @@ typedef bool msk;
 typedef int8_t bit;
 typedef int8_t bte;
 typedef int16_t sht;
-typedef int64_t lng;
+/* typedef int64_t lng; -- defined in gdk_system.h */
 typedef uint64_t ulng;
 
 #define SIZEOF_OID     SIZEOF_SIZE_T
@@ -2208,4 +2208,84 @@ gdk_export BAT *BATsample_with_seed(BAT 
  */
 #define MAXPARAMS      32
 
+#define CHECK_QRY_TIMEOUT_SHIFT        14
+#define CHECK_QRY_TIMEOUT_STEP (1 << CHECK_QRY_TIMEOUT_SHIFT)
+#define CHECK_QRY_TIMEOUT_MASK (CHECK_QRY_TIMEOUT_STEP - 1)
+
+#define TIMEOUT_MSG "Timeout was reached!"
+
+#define TIMEOUT_HANDLER(rtpe)                  \
+       do {                                    \
+               GDKerror(TIMEOUT_MSG);          \
+               return rtpe;                    \
+       } while(0)
+
+#define GOTO_LABEL_TIMEOUT_HANDLER(label)      \
+       do {                                    \
+               GDKerror(TIMEOUT_MSG);          \
+               goto label;                     \
+       } while(0)
+
+#define GDK_CHECK_TIMEOUT_BODY(timeoffset, callback)           \
+       do {                                                    \
+               if (timeoffset && GDKusec() > timeoffset) {     \
+                       callback;                               \
+               }                                               \
+       } while (0)
+
+#define GDK_CHECK_TIMEOUT(timeoffset, counter, callback)               \
+       do {                                                            \
+               if (timeoffset) {                                       \
+                       if (counter > CHECK_QRY_TIMEOUT_STEP) {         \
+                               GDK_CHECK_TIMEOUT_BODY(timeoffset, callback); \
+                               counter = 0;                            \
+                       } else {                                        \
+                               counter++;                              \
+                       }                                               \
+               }                                                       \
+       } while (0)
+
+/* here are some useful construct to iterate a number of times (the
+ * REPEATS argument--only evaluated once) and checking for a timeout
+ * every once in a while; the TIMEOFFSET value is a variable of type lng
+ * which is either 0 or the GDKusec() compatible time after which the
+ * loop should terminate; check for this condition after the loop using
+ * the TIMEOUT_CHECK macro; in order to break out of any of these loops,
+ * use TIMEOUT_LOOP_BREAK since plain break won't do it; it is perfectly
+ * ok to use continue inside the body */
+
+/* use IDX as a loop variable, initializing it to 0 and incrementing it
+ * on each iteration */
+#define TIMEOUT_LOOP_IDX(IDX, REPEATS, TIMEOFFSET)                     \
+       for (BUN REPS = (IDX = 0, (REPEATS)); REPS > 0; REPS = 0) /* "loops" at 
most once */ \
+               for (BUN CTR1 = 0, END1 = (REPS + CHECK_QRY_TIMEOUT_MASK) >> 
CHECK_QRY_TIMEOUT_SHIFT; CTR1 < END1 && TIMEOFFSET >= 0; CTR1++, TIMEOFFSET = 
TIMEOFFSET > 0 && GDKusec() > TIMEOFFSET ? -1 : TIMEOFFSET) \
+                       for (BUN CTR2 = 0, END2 = CTR1 == END1 - 1 ? REPS & 
CHECK_QRY_TIMEOUT_MASK : CHECK_QRY_TIMEOUT_STEP; CTR2 < END2; CTR2++, IDX++)
+
+/* declare and use IDX as a loop variable, initializing it to 0 and
+ * incrementing it on each iteration */
+#define TIMEOUT_LOOP_IDX_DECL(IDX, REPEATS, TIMEOFFSET)                        
\
+       for (BUN IDX = 0, REPS = (REPEATS); REPS > 0; REPS = 0) /* "loops" at 
most once */ \
+               for (BUN CTR1 = 0, END1 = (REPS + CHECK_QRY_TIMEOUT_MASK) >> 
CHECK_QRY_TIMEOUT_SHIFT; CTR1 < END1 && TIMEOFFSET >= 0; CTR1++, TIMEOFFSET = 
TIMEOFFSET > 0 && GDKusec() > TIMEOFFSET ? -1 : TIMEOFFSET) \
+                       for (BUN CTR2 = 0, END2 = CTR1 == END1 - 1 ? REPS & 
CHECK_QRY_TIMEOUT_MASK : CHECK_QRY_TIMEOUT_STEP; CTR2 < END2; CTR2++, IDX++)
+
+/* there is no user-visible loop variable */
+#define TIMEOUT_LOOP(REPEATS, TIMEOFFSET)                              \
+       for (BUN CTR1 = 0, REPS = (REPEATS), END1 = (REPS + 
CHECK_QRY_TIMEOUT_MASK) >> CHECK_QRY_TIMEOUT_SHIFT; CTR1 < END1 && TIMEOFFSET 
>= 0; CTR1++, TIMEOFFSET = TIMEOFFSET > 0 && GDKusec() > TIMEOFFSET ? -1 : 
TIMEOFFSET) \
+               for (BUN CTR2 = 0, END2 = CTR1 == END1 - 1 ? REPS & 
CHECK_QRY_TIMEOUT_MASK : CHECK_QRY_TIMEOUT_STEP; CTR2 < END2; CTR2++)
+
+/* break out of the loop (cannot use do/while trick here) */
+#define TIMEOUT_LOOP_BREAK                     \
+       {                                       \
+               END1 = END2 = 0;                \
+               continue;                       \
+       }
+
+/* check whether a timeout occurred, and execute the CALLBACK argument
+ * if it did */
+#define TIMEOUT_CHECK(TIMEOFFSET, CALLBACK)    \
+       do {                                    \
+               if (TIMEOFFSET == -1)           \
+                       CALLBACK;               \
+       } while (0)
+
 #endif /* _GDK_H_ */
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -200,6 +200,12 @@ dofsum(const void *restrict values, oid 
        BUN nils = 0;
        volatile flt f;
 
+       lng timeoffset = 0;
+       QryCtx *qry_ctx = MT_thread_get_qry_ctx();
+       if (qry_ctx != NULL) {
+               timeoffset = (qry_ctx->starttime && qry_ctx->querytimeout) ? 
(qry_ctx->starttime + qry_ctx->querytimeout) : 0;
+       }
+
        /* we only deal with the two floating point types */
        assert(tp1 == TYPE_flt || tp1 == TYPE_dbl);
        assert(tp2 == TYPE_flt || tp2 == TYPE_dbl);
@@ -228,8 +234,7 @@ dofsum(const void *restrict values, oid 
                        return BUN_NONE;
                }
        }
-       while (ncand > 0) {
-               ncand--;
+       TIMEOUT_LOOP(ncand, timeoffset) {
                listi = canditer_next(ci) - seqb;
                grp = gids ? gids[listi] : 0;
                if (grp < min || grp > max)
@@ -250,7 +255,7 @@ dofsum(const void *restrict values, oid 
                                GDKfree(pergroup[grp].partials);
                                pergroup[grp].partials = NULL;
                                if (++nils == ngrp)
-                                       break;
+                                       TIMEOUT_LOOP_BREAK;
                        }
                        continue;
                }
@@ -293,7 +298,7 @@ dofsum(const void *restrict values, oid 
                }
                pergroup[grp].npartials = i;
        }
-
+       TIMEOUT_CHECK(timeoffset, GOTO_LABEL_TIMEOUT_HANDLER(bailout));
        for (grp = 0; grp < ngrp; grp++) {
                if (pergroup[grp].partials == NULL)
                        continue;
@@ -449,21 +454,24 @@ dofsum(const void *restrict values, oid 
                        sum = 0;                                        \
                        if (nonil) {                                    \
                                *seen = ncand > 0;                      \
-                               for (i = 0; i < ncand && nils == 0; i++) { \
+                               TIMEOUT_LOOP_IDX(i, ncand, timeoffset) { \
                                        x = vals[ci->seq + i - seqb];   \
                                        ADD_WITH_CHECK(x, sum,          \
                                                       TYPE2, sum,      \
                                                       GDK_##TYPE2##_max, \
                                                       goto overflow);  \
                                }                                       \
+                               TIMEOUT_CHECK(timeoffset,               \
+                                             
GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                        } else {                                        \
                                bool seenval = false;                   \
-                               for (i = 0; i < ncand && nils == 0; i++) { \
+                               TIMEOUT_LOOP_IDX(i, ncand, timeoffset) { \
                                        x = vals[ci->seq + i - seqb];   \
                                        if (is_##TYPE1##_nil(x)) {      \
                                                if (!skip_nils) {       \
                                                        sum = TYPE2##_nil; \
                                                        nils = 1;       \
+                                                       TIMEOUT_LOOP_BREAK; \
                                                }                       \
                                        } else {                        \
                                                ADD_WITH_CHECK(x, sum,  \
@@ -473,6 +481,8 @@ dofsum(const void *restrict values, oid 
                                                seenval = true;         \
                                        }                               \
                                }                                       \
+                               TIMEOUT_CHECK(timeoffset,               \
+                                             
GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                                *seen = seenval;                        \
                        }                                               \
                        if (*seen)                                      \
@@ -483,12 +493,13 @@ dofsum(const void *restrict values, oid 
                        bool seenval = false;                           \
                        *algo = "sum: with candidates, no groups";      \
                        sum = 0;                                        \
-                       for (i = 0; i < ncand && nils == 0; i++) {      \
+                       TIMEOUT_LOOP_IDX(i, ncand, timeoffset) {        \
                                x = vals[canditer_next(ci) - seqb];     \
                                if (is_##TYPE1##_nil(x)) {              \
                                        if (!skip_nils) {               \
                                                sum = TYPE2##_nil;      \
                                                nils = 1;               \
+                                               TIMEOUT_LOOP_BREAK;     \
                                        }                               \
                                } else {                                \
                                        ADD_WITH_CHECK(x, sum,          \
@@ -498,12 +509,14 @@ dofsum(const void *restrict values, oid 
                                        seenval = true;                 \
                                }                                       \
                        }                                               \
+                       TIMEOUT_CHECK(timeoffset,                       \
+                                     GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                        if (seenval)                                    \
                                *sums = sum;                            \
                } else if (ci->tpe == cand_dense) {                     \
                        /* multiple groups, no candidate list */        \
                        *algo = "sum: no candidates, with groups";      \
-                       for (i = 0; i < ncand; i++) {                   \
+                       TIMEOUT_LOOP_IDX(i, ncand, timeoffset) {        \
                                if (gids == NULL ||                     \
                                    (gids[i] >= min && gids[i] <= max)) { \
                                        gid = gids ? gids[i] - min : (oid) i; \
@@ -531,11 +544,12 @@ dofsum(const void *restrict values, oid 
                                        }                               \
                                }                                       \
                        }                                               \
+                       TIMEOUT_CHECK(timeoffset,                       \
+                                     GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                } else {                                                \
                        /* multiple groups, with candidate list */      \
                        *algo = "sum: with candidates, with groups";    \
-                       while (ncand > 0) {                             \
-                               ncand--;                                \
+                       TIMEOUT_LOOP(ncand, timeoffset) {               \
                                i = canditer_next(ci) - seqb;           \
                                if (gids == NULL ||                     \
                                    (gids[i] >= min && gids[i] <= max)) { \
@@ -564,6 +578,8 @@ dofsum(const void *restrict values, oid 
                                        }                               \
                                }                                       \
                        }                                               \
+                       TIMEOUT_CHECK(timeoffset,                       \
+                                     GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                }                                                       \
        } while (0)
 
@@ -578,24 +594,29 @@ dofsum(const void *restrict values, oid 
                        if (nonil) {                                    \
                                *algo = "sum: no candidates, no groups, no 
nils, no overflow"; \
                                *seen = ncand > 0;                      \
-                               for (i = 0; i < ncand && nils == 0; i++) { \
+                               TIMEOUT_LOOP_IDX(i, ncand, timeoffset) { \
                                        sum += vals[ci->seq + i - seqb]; \
                                }                                       \
+                               TIMEOUT_CHECK(timeoffset,               \
+                                             
GOTO_LABEL_TIMEOUT_HANDLER(bailout)); \
                        } else {                                        \
                                bool seenval = false;                   \
                                *algo = "sum: no candidates, no groups, no 
overflow"; \
-                               for (i = 0; i < ncand && nils == 0; i++) { \
+                               TIMEOUT_LOOP_IDX(i, ncand, timeoffset) { \
                                        x = vals[ci->seq + i - seqb];   \
                                        if (is_##TYPE1##_nil(x)) {      \
                                                if (!skip_nils) {       \
                                                        sum = TYPE2##_nil; \
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to