static unsigned long stm_regular_length_limit = ULONG_MAX;
-static volatile int break_please = 0;
+/* sync_required is either 0 or 0xffffffff */
+static volatile unsigned long sync_required = 0;
static void reached_safe_point(void);
void stm_add_atomic(long delta)
/* a single comparison to handle all cases:
+ - first, if sync_required == 0xffffffff, this should return True.
- if d->atomic, then we should return False. This is done by
- forcing reads_size_limit to ULONG_MAX as soon as atomic > 0,
- and no possible value of 'count_reads' is greater than ULONG_MAX.
+ forcing reads_size_limit to ULONG_MAX as soon as atomic > 0.
- otherwise, if is_inevitable(), then we should return True.
This is done by forcing both reads_size_limit and
assert(d->reads_size_limit_nonatomic == 0);
- return d->count_reads > d->reads_size_limit;
+ return (sync_required | d->count_reads) >= d->reads_size_limit;
void stm_set_transaction_length(long length_max)
+ /* atomic transaction: a common case is that callback() returned
+ even though we are atomic because we need a major GC. For
+ that case, release and require the rw lock here. */
/* invoke the callback in the new transaction */
result = callback(arg, counter);
/* Called by the GC, just after a minor collection, when we need to do
a major collection. When it returns, it acquired the "write lock"
- which prevents any other thread from running a transaction. */
+ which prevents any other thread from running in a transaction.
+ Warning, may block waiting for rwlock_in_transaction while another
+ thread runs a major GC itself! */
err = pthread_rwlock_unlock(&rwlock_in_transaction);
err = pthread_rwlock_wrlock(&rwlock_in_transaction);
assert(in_single_thread == NULL);
in_single_thread = thread_descriptor;
+ /* Warning, may block waiting for rwlock_in_transaction while another
+ thread runs a major GC */
assert(in_single_thread == thread_descriptor);
static void reached_safe_point(void)
+ /* Warning: all places that call this function from RPython code
+ must do so with a llop with canmallocgc=True! The release of
+ the rwlock_in_transaction below means a major GC could run in
struct tx_descriptor *d = thread_descriptor;
assert(in_single_thread != d);