Changeset: ddae91507838 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ddae91507838
Modified Files:
common/utils/matomic.h
gdk/gdk.h
gdk/gdk_bbp.c
gdk/gdk_bbp.h
Branch: Jul2021
Log Message:
Use atomic instructions to manipulate BBP record status field.
diffs (223 lines):
diff --git a/common/utils/matomic.h b/common/utils/matomic.h
--- a/common/utils/matomic.h
+++ b/common/utils/matomic.h
@@ -87,15 +87,17 @@ typedef unsigned long long ATOMIC_BASE_T
#endif
#define ATOMIC_INIT(var, val) atomic_init(var, (ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_DESTROY(var) ((void) 0)
-#define ATOMIC_GET(var) atomic_load(var)
+#define ATOMIC_DESTROY(var) ((void) 0)
+#define ATOMIC_GET(var) atomic_load(var)
#define ATOMIC_SET(var, val) atomic_store(var, (ATOMIC_BASE_TYPE) (val))
#define ATOMIC_XCG(var, val) atomic_exchange(var, (ATOMIC_BASE_TYPE) (val))
#define ATOMIC_CAS(var, exp, des) atomic_compare_exchange_strong(var,
exp, (ATOMIC_BASE_TYPE) (des))
#define ATOMIC_ADD(var, val) atomic_fetch_add(var, (ATOMIC_BASE_TYPE) (val))
#define ATOMIC_SUB(var, val) atomic_fetch_sub(var, (ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_INC(var) (atomic_fetch_add(var, 1) + 1)
-#define ATOMIC_DEC(var) (atomic_fetch_sub(var, 1) - 1)
+#define ATOMIC_INC(var) (atomic_fetch_add(var, 1) + 1)
+#define ATOMIC_DEC(var) (atomic_fetch_sub(var, 1) - 1)
+#define ATOMIC_OR(var, val) atomic_fetch_or(var, (ATOMIC_BASE_TYPE)
(val))
+#define ATOMIC_AND(var, val) atomic_fetch_and(var, (ATOMIC_BASE_TYPE) (val))
#ifdef __INTEL_COMPILER
typedef volatile atomic_address ATOMIC_PTR_TYPE;
@@ -166,8 +168,10 @@ ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE
#define ATOMIC_CAS(var, exp, des) ATOMIC_CAS(var, exp, (ATOMIC_BASE_TYPE)
(des))
#define ATOMIC_ADD(var, val) _InterlockedExchangeAdd64(var,
(ATOMIC_BASE_TYPE) (val))
#define ATOMIC_SUB(var, val) _InterlockedExchangeAdd64(var,
-(ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_INC(var) _InterlockedIncrement64(var)
-#define ATOMIC_DEC(var) _InterlockedDecrement64(var)
+#define ATOMIC_INC(var) _InterlockedIncrement64(var)
+#define ATOMIC_DEC(var) _InterlockedDecrement64(var)
+#define ATOMIC_OR(var, val) _InterlockedOr64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_AND(var, val) _InterlockedAnd64(var, (ATOMIC_BASE_TYPE) (val))
#else
@@ -179,6 +183,23 @@ ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE
#define ATOMIC_GET(var)
_InlineInterlockedExchangeAdd64(var, 0)
#define ATOMIC_SET(var, val) _InlineInterlockedExchange64(var,
(ATOMIC_BASE_TYPE) (val))
#define ATOMIC_XCG(var, val) _InlineInterlockedExchange64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_ADD(var, val) _InlineInterlockedExchangeAdd64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_SUB(var, val) _InlineInterlockedExchangeAdd64(var,
-(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_INC(var)
_InlineInterlockedIncrement64(var)
+#define ATOMIC_DEC(var)
_InlineInterlockedDecrement64(var)
+#define ATOMIC_OR(var, val) _InlineInterlockedOr64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_AND(var, val) _InlineInterlockedAnd64(var, (ATOMIC_BASE_TYPE)
(val))
+#else
+#define ATOMIC_GET(var) _InterlockedExchangeAdd64(var,
0)
+#define ATOMIC_SET(var, val) _InterlockedExchange64(var, (ATOMIC_BASE_TYPE)
(val))
+#define ATOMIC_XCG(var, val) _InterlockedExchange64(var, (ATOMIC_BASE_TYPE)
(val))
+#define ATOMIC_ADD(var, val) _InterlockedExchangeAdd64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_SUB(var, val) _InterlockedExchangeAdd64(var,
-(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_INC(var) _InterlockedIncrement64(var)
+#define ATOMIC_DEC(var) _InterlockedDecrement64(var)
+#define ATOMIC_OR(var, val) _InterlockedOr64(var,
(ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_AND(var, val) _InterlockedAnd64(var, (ATOMIC_BASE_TYPE) (val))
+#endif
static inline bool
ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE *exp, ATOMIC_BASE_TYPE des)
{
@@ -190,30 +211,6 @@ ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE
return false;
}
#define ATOMIC_CAS(var, exp, des) ATOMIC_CAS(var, exp, (ATOMIC_BASE_TYPE)
(des))
-#define ATOMIC_ADD(var, val) _InlineInterlockedExchangeAdd64(var,
(ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_SUB(var, val) _InlineInterlockedExchangeAdd64(var,
-(ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_INC(var) _InlineInterlockedIncrement64(var)
-#define ATOMIC_DEC(var) _InlineInterlockedDecrement64(var)
-#else
-#define ATOMIC_GET(var) _InterlockedExchangeAdd64(var,
0)
-#define ATOMIC_SET(var, val) _InterlockedExchange64(var, (ATOMIC_BASE_TYPE)
(val))
-#define ATOMIC_XCG(var, val) _InterlockedExchange64(var, (ATOMIC_BASE_TYPE)
(val))
-static inline bool
-ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE *exp, ATOMIC_BASE_TYPE des)
-{
- ATOMIC_BASE_TYPE old;
- old = _InterlockedCompareExchange64(var, des, *exp);
- if (old == *exp)
- return true;
- *exp = old;
- return false;
-}
-#define ATOMIC_CAS(var, exp, des) ATOMIC_CAS(var, exp, (ATOMIC_BASE_TYPE)
(des))
-#define ATOMIC_ADD(var, val) _InterlockedExchangeAdd64(var,
(ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_SUB(var, val) _InterlockedExchangeAdd64(var,
-(ATOMIC_BASE_TYPE) (val))
-#define ATOMIC_INC(var) _InterlockedIncrement64(var)
-#define ATOMIC_DEC(var) _InterlockedDecrement64(var)
-#endif
#endif
@@ -259,14 +256,16 @@ typedef volatile int ATOMIC_TYPE;
#define ATOMIC_INIT(var, val) (*(var) = (val))
#define ATOMIC_DESTROY(var) ((void) 0)
-#define ATOMIC_GET(var) __atomic_load_n(var, __ATOMIC_SEQ_CST)
+#define ATOMIC_GET(var) __atomic_load_n(var,
__ATOMIC_SEQ_CST)
#define ATOMIC_SET(var, val) __atomic_store_n(var, (ATOMIC_BASE_TYPE) (val),
__ATOMIC_SEQ_CST)
#define ATOMIC_XCG(var, val) __atomic_exchange_n(var, (ATOMIC_BASE_TYPE)
(val), __ATOMIC_SEQ_CST)
#define ATOMIC_CAS(var, exp, des) __atomic_compare_exchange_n(var, exp,
(ATOMIC_BASE_TYPE) (des), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define ATOMIC_ADD(var, val) __atomic_fetch_add(var, (ATOMIC_BASE_TYPE)
(val), __ATOMIC_SEQ_CST)
-#define ATOMIC_SUB(var, val) __atomic_fetch_sub(var, (ATOMIC_BASE_TYPE)
(val), __ATOMIC_SEQ_CST)
-#define ATOMIC_INC(var) __atomic_add_fetch(var, 1,
__ATOMIC_SEQ_CST)
-#define ATOMIC_DEC(var) __atomic_sub_fetch(var, 1,
__ATOMIC_SEQ_CST)
+#define ATOMIC_SUB(var, val) __atomic_fetch_sub(var, (ATOMIC_BASE_TYPE)
(val), __ATOMIC_SEQ_CST)#
+define ATOMIC_INC(var) __atomic_add_fetch(var, 1,
__ATOMIC_SEQ_CST)
+#define ATOMIC_DEC(var) __atomic_sub_fetch(var, 1,
__ATOMIC_SEQ_CST)
+#define ATOMIC_OR(var, val) __atomic_fetch_or(var,
(ATOMIC_BASE_TYPE) (val), __ATOMIC_SEQ_CST)
+#define ATOMIC_AND(var, val) __atomic_fetch_and(var, (ATOMIC_BASE_TYPE)
(val), __ATOMIC_SEQ_CST)
typedef void *volatile ATOMIC_PTR_TYPE;
#define ATOMIC_PTR_INIT(var, val) (*(var) = (val))
@@ -397,6 +396,30 @@ ATOMIC_DEC(ATOMIC_TYPE *var)
return new;
}
+static inline ATOMIC_BASE_TYPE
+ATOMIC_OR(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE val)
+{
+ ATOMIC_BASE_TYPE old;
+ pthread_mutex_lock(&var->lck);
+ old = var->val;
+ var->val += val;
+ pthread_mutex_unlock(&var->lck);
+ return old;
+}
+#define ATOMIC_OR(var, val) ATOMIC_OR(var, (ATOMIC_BASE_TYPE) (val))
+
+static inline ATOMIC_BASE_TYPE
+ATOMIC_AND(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE val)
+{
+ ATOMIC_BASE_TYPE old;
+ pthread_mutex_lock(&var->lck);
+ old = var->val;
+ var->val += val;
+ pthread_mutex_unlock(&var->lck);
+ return old;
+}
+#define ATOMIC_AND(var, val) ATOMIC_AND(var, (ATOMIC_BASE_TYPE) (val))
+
typedef struct {
void *val;
pthread_mutex_t lck;
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1392,7 +1392,7 @@ typedef struct {
bat next; /* next BBP slot in linked list */
int refs; /* in-memory references on which the loaded
status of a BAT relies */
int lrefs; /* logical references on which the existence of
a BAT relies */
- volatile unsigned status; /* status mask used for spin locking */
+ ATOMIC_TYPE status; /* status mask used for spin locking */
/* MT_Id pid; non-zero thread-id if this BAT is private */
} BBPrec;
@@ -1424,7 +1424,7 @@ gdk_export BBPrec *BBP[N_BBPINIT];
#define BBP_desc(i) BBP_record(i).desc
#define BBP_refs(i) BBP_record(i).refs
#define BBP_lrefs(i) BBP_record(i).lrefs
-#define BBP_status(i) BBP_record(i).status
+#define BBP_status(i) ((unsigned) ATOMIC_GET(&BBP_record(i).status))
#define BBP_pid(i) BBP_record(i).pid
#define BATgetId(b) BBP_logical((b)->batCacheid)
#define BBPvalid(i) (BBP_logical(i) != NULL && *BBP_logical(i) != '.')
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -361,12 +361,15 @@ BBPextend(int idx, bool buildhash)
/* make sure the new size is at least BBPsize large */
while (BBPlimit < (bat) ATOMIC_GET(&BBPsize)) {
- assert(BBP[BBPlimit >> BBPINITLOG] == NULL);
- BBP[BBPlimit >> BBPINITLOG] = GDKzalloc(BBPINIT *
sizeof(BBPrec));
- if (BBP[BBPlimit >> BBPINITLOG] == NULL) {
+ BUN limit = BBPlimit >> BBPINITLOG;
+ assert(BBP[limit] == NULL);
+ BBP[limit] = GDKzalloc(BBPINIT * sizeof(BBPrec));
+ if (BBP[limit] == NULL) {
GDKerror("failed to extend BAT pool\n");
return GDK_FAIL;
}
+ for (BUN i = 0; i < BBPINIT; i++)
+ ATOMIC_INIT(&BBP[limit][i].status, 0);
BBPlimit += BBPINIT;
}
@@ -719,7 +722,7 @@ BBPreadEntries(FILE *fp, unsigned bbpver
BBP_refs(bid) = 0;
BBP_lrefs(bid) = 1; /* any BAT we encounter here is
persistent, so has a logical reference */
BBP_desc(bid) = bn;
- BBP_status(bid) = BBPEXISTING; /* do we need other status
bits? */
+ BBP_status_set(bid, BBPEXISTING); /* do we need other
status bits? */
}
return GDK_SUCCEED;
}
diff --git a/gdk/gdk_bbp.h b/gdk/gdk_bbp.h
--- a/gdk/gdk_bbp.h
+++ b/gdk/gdk_bbp.h
@@ -81,16 +81,14 @@ gdk_export void BBPshare(bat b);
#define BBPtmpcheck(s) (strncmp(s, "tmp_", 4) == 0)
-#define BBP_status_set(bid, mode) \
- do { \
- BBP_status(bid) = mode; \
- } while (0)
+#define BBP_status_set(bid, mode) \
+ ATOMIC_SET(&BBP_record(bid).status, mode)
-#define BBP_status_on(bid, flags) \
- BBP_status_set(bid, BBP_status(bid) | flags)
+#define BBP_status_on(bid, flags) \
+ ATOMIC_OR(&BBP_record(bid).status, flags)
-#define BBP_status_off(bid, flags) \
- BBP_status_set(bid, BBP_status(bid) & ~(flags))
+#define BBP_status_off(bid, flags) \
+ ATOMIC_AND(&BBP_record(bid).status, ~(flags))
#define BBPswappable(b) ((b) && (b)->batCacheid && BBP_refs((b)->batCacheid)
== 0)
#define BBPtrimmable(b) (BBPswappable(b) && isVIEW(b) == 0 &&
(BBP_status((b)->batCacheid)&BBPWAITING) == 0)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list