#include "SMP.h"
#include "STM.h"
#include "Storage.h"
+#include "Trace.h"
#include <stdlib.h>
#include <stdio.h>
// If SHAKE is defined then validation will sometime spuriously fail. They helps test
// unusualy code paths if genuine contention is rare
-#if defined(DEBUG)
-#define SHAKE
-#if defined(THREADED_RTS)
-#define TRACE(_x...) IF_DEBUG(stm, debugBelch("STM (task %p): ", (void *)(unsigned long)(unsigned int)osThreadId()); debugBelch ( _x ))
-#else
-#define TRACE(_x...) IF_DEBUG(stm, debugBelch ( _x ))
-#endif
-#else
-#define TRACE(_x...) /*Nothing*/
-#endif
+#define TRACE(_x...) debugTrace(DEBUG_stm, "STM: " _x)
#ifdef SHAKE
static const int do_shake = TRUE;
do {
result = s -> current_value;
} while (GET_INFO(result) == &stg_TREC_HEADER_info);
- } while (cas(&(s -> current_value), result, trec) != result);
+ } while (cas((void *)&(s -> current_value),
+ (StgWord)result, (StgWord)trec) != (StgWord)result);
return result;
}
StgClosure *c,
StgBool force_update STG_UNUSED) {
TRACE("%p : unlock_tvar(%p, %p)\n", trec, s, c);
- ASSERT(s -> current_value == trec);
+ ASSERT(s -> current_value == (StgClosure *)trec);
s -> current_value = c;
}
StgTVar *s,
StgClosure *expected) {
StgClosure *result;
+ StgWord w;
TRACE("%p : cond_lock_tvar(%p, %p)\n", trec, s, expected);
- result = cas(&(s -> current_value), expected, trec);
+ w = cas((void *)&(s -> current_value), (StgWord)expected, (StgWord)trec);
+ result = (StgClosure *)w;
TRACE("%p : %s\n", trec, result ? "success" : "failure");
return (result == expected);
}
StgTVarWaitQueue *fq;
s = e -> tvar;
TRACE("%p : adding tso=%p to wait queue for tvar=%p\n", trec, tso, s);
- ACQ_ASSERT(s -> current_value == trec);
+ ACQ_ASSERT(s -> current_value == (StgClosure *)trec);
NACQ_ASSERT(s -> current_value == e -> expected_value);
fq = s -> first_wait_queue_entry;
q = alloc_stg_tvar_wait_queue(cap, tso);
StgClosure *saw = lock_tvar(trec, s);
q = (StgTVarWaitQueue *) (e -> new_value);
TRACE("%p : removing tso=%p from wait queue for tvar=%p\n", trec, q -> waiting_tso, s);
- ACQ_ASSERT(s -> current_value == trec);
+ ACQ_ASSERT(s -> current_value == (StgClosure *)trec);
nq = q -> next_queue_entry;
pq = q -> prev_queue_entry;
if (nq != END_STM_WAIT_QUEUE) {
result = FALSE;
BREAK_FOR_EACH;
} else {
- TRACE("%p : need to check version %d\n", trec, e -> num_updates);
+ TRACE("%p : need to check version %ld\n", trec, e -> num_updates);
}
});
}
StgTVar *s;
s = e -> tvar;
if (entry_is_read_only(e)) {
- TRACE("%p : check_read_only for TVar %p, saw %d\n", trec, s, e -> num_updates);
+ TRACE("%p : check_read_only for TVar %p, saw %ld", trec, s, e -> num_updates);
if (s -> num_updates != e -> num_updates) {
// ||s -> current_value != e -> expected_value) {
TRACE("%p : mismatch\n", trec);
static volatile StgInt64 max_commits = 0;
+#if defined(THREADED_RTS)
static volatile StgBool token_locked = FALSE;
-#if defined(THREADED_RTS)
static void getTokenBatch(Capability *cap) {
- while (cas(&token_locked, FALSE, TRUE) == TRUE) { /* nothing */ }
+ while (cas((void *)&token_locked, FALSE, TRUE) == TRUE) { /* nothing */ }
max_commits += TOKEN_BATCH_SIZE;
cap -> transaction_tokens = TOKEN_BATCH_SIZE;
token_locked = FALSE;
unlock_tvar(trec, s, e -> expected_value, FALSE);
}
merge_update_into(cap, et, s, e -> expected_value, e -> new_value);
- ACQ_ASSERT(s -> current_value != trec);
+ ACQ_ASSERT(s -> current_value != (StgClosure *)trec);
});
} else {
revert_ownership(trec, FALSE);