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