Skip to content

Commit

Permalink
Convert deprecated functions to use modern atomic variable handling
Browse files Browse the repository at this point in the history
Replaced deprecated atomic functions with the recommended C11 equivalents.
  • Loading branch information
AreaZR committed Dec 16, 2023
1 parent ee39300 commit 19c218b
Show file tree
Hide file tree
Showing 21 changed files with 127 additions and 186 deletions.
13 changes: 2 additions & 11 deletions src/BlocksRuntime/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,11 @@
#define __has_builtin(builtin) 0
#endif

#if __has_builtin(__sync_bool_compare_and_swap)
#define OSAtomicCompareAndSwapInt(_Old, _New, _Ptr) \
__sync_bool_compare_and_swap(_Ptr, _Old, _New)
#else
#define _CRT_SECURE_NO_WARNINGS 1
#include <Windows.h>
#include <stdatomic.h>
static __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi,
int volatile *dst) {
// fixme barrier is overkill -- see objc-os.h
int original = InterlockedCompareExchange((LONG volatile *)dst, newi, oldi);
return (original == oldi);
return atomic_compare_exchange_weak((_Atomic(int)*)dst, &oldi, newi);
}
#endif

/***********************
Globals
************************/
Expand Down
34 changes: 18 additions & 16 deletions src/allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,31 +542,33 @@ _dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
}
// They are all unallocated, so we could madvise the page. Try to
// take ownership of them all.
int last_locked = 0;
do {
for (i = 0; i < BITMAPS_PER_PAGE; i++) {
if (!os_atomic_cmpxchg(&page_bitmaps[last_locked], BITMAP_C(0),
BITMAP_ALL_ONES, relaxed)) {
// We didn't get one; since there is a cont allocated in
// the page, we can't madvise. Give up and unlock all.
goto unlock;
break;
}
} while (++last_locked < (signed)BITMAPS_PER_PAGE);
}

if (i == BITMAPS_PER_PAGE) {
#if DISPATCH_DEBUG
//fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
// "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
// last_locked-1, BITMAPS_PER_PAGE, &page_bitmaps[0]);
// Scribble to expose use-after-free bugs
// madvise (syscall) flushes these stores
memset(page, DISPATCH_ALLOCATOR_SCRIBBLE, DISPATCH_ALLOCATOR_PAGE_SIZE);
// fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
// "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
// last_locked-1, BITMAPS_PER_PAGE, &page_bitmaps[0]);
// Scribble to expose use-after-free bugs
// madvise (syscall) flushes these stores
memset(page, DISPATCH_ALLOCATOR_SCRIBBLE, DISPATCH_ALLOCATOR_PAGE_SIZE);
#endif
(void)dispatch_assume_zero(madvise(page, DISPATCH_ALLOCATOR_PAGE_SIZE,
MADV_FREE));
// madvise the page
(void)dispatch_assume_zero(madvise(page, DISPATCH_ALLOCATOR_PAGE_SIZE,
MADV_FREE));
}

unlock:
while (last_locked > 1) {
page_bitmaps[--last_locked] = BITMAP_C(0);
while (i > 1) {
page_bitmaps[--i] = BITMAP_C(0);
}
if (last_locked) {
if (i) {
os_atomic_store(&page_bitmaps[0], BITMAP_C(0), relaxed);
}
return;
Expand Down
68 changes: 33 additions & 35 deletions tests/Foundation/bench.mm
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ virtual void virtfunc(void) {
return arg;
}

static volatile int32_t global;
static volatile int64_t w_global;
static atomic_int global;
static _Atomic(int64_t) w_global;

#if TARGET_OS_EMBEDDED
static const size_t cnt = 5000000;
Expand Down Expand Up @@ -191,7 +191,7 @@ static void __attribute__((noinline))
main(void)
{
pthread_mutex_t plock = PTHREAD_MUTEX_INITIALIZER;
OSSpinLock slock = OS_SPINLOCK_INIT;
os_unfair_lock slock = OS_UNFAIR_LOCK_INIT;
BasicObject *bo;
BasicClass *bc;
pthread_t pthr_pause;
Expand Down Expand Up @@ -219,8 +219,7 @@ static void __attribute__((noinline))
cycles_per_nanosecond = (long double)freq / (long double)NSEC_PER_SEC;

#if BENCH_SLOW
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
assert(pool);
@autoreleasepool {
#endif

/* Malloc has different logic for threaded apps. */
Expand Down Expand Up @@ -371,9 +370,7 @@ static void __attribute__((noinline))
}
print_result2(s, "\"description\" ObjC call:");

[pool release];

pool = NULL;
} // For the autorelease pool
#endif

s = mach_absolute_time();
Expand Down Expand Up @@ -554,30 +551,30 @@ __asm__ __volatile__ ("svc 0x80" : "+r" (_r0)

s = mach_absolute_time();
for (i = cnt; i; i--) {
__sync_lock_test_and_set(&global, 0);
atomic_xchg(&global, 0);
}
print_result(s, "Atomic xchg:");

s = mach_absolute_time();
for (i = cnt; i; i--) {
__sync_val_compare_and_swap(&global, 1, 0);
atomic_cmpxchg(&global, 1, 0);
}
print_result(s, "Atomic cmpxchg:");

s = mach_absolute_time();
for (i = cnt; i; i--) {
__sync_fetch_and_add(&global, 1);
atomic_fetch_add(&global, 1);
}
print_result(s, "Atomic increment:");

{
global = 0;
volatile int32_t *g = &global;
global = ATOMIC_VAR_INIT(0);
atomic_int *g = &global;

s = mach_absolute_time();
for (i = cnt; i; i--) {
uint32_t result;
__sync_and_and_fetch(g, 1);
atomic_fetch_and(g, 1);
result = *g;
if (result) {
abort();
Expand All @@ -587,57 +584,58 @@ __asm__ __volatile__ ("svc 0x80" : "+r" (_r0)
}

{
global = 0;
volatile int32_t *g = &global;
global = ATOMIC_VAR_INIT(0);
atomic_int *g = &global;

s = mach_absolute_time();
for (i = cnt; i; i--) {
uint32_t result;
result = __sync_and_and_fetch(g, 1);
result = atomic_fetch_and(g, 1);
if (result) {
abort();
}
}
print_result(s, "Atomic and-and-fetch, using result:");
}

global = 0;
global = ATOMIC_VAR_INIT(0);

s = mach_absolute_time();
for (i = cnt; i; i--) {
OSAtomicIncrement32Barrier(&global);
__c11_atomic_fetch_add(&global, 1, memory_order_seq_cst);
}
print_result(s, "OSAtomicIncrement32Barrier:");
print_result(s, "atomic_fetch_add with memory_order_seq_cst barrier:");

global = 0;
global = ATOMIC_VAR_INIT(0);

s = mach_absolute_time();
for (i = cnt; i; i--) {
OSAtomicIncrement32(&global);
__c11_atomic_fetch_add(&global, 1, memory_order_relaxed);
}
print_result(s, "OSAtomicIncrement32:");
print_result(s, "atomic_fetch_add with memory_order_relaxed barrier:");

w_global = 0;
w_global = ATOMIC_VAR_INIT(0);

s = mach_absolute_time();
for (i = cnt; i; i--) {
OSAtomicIncrement64Barrier(&w_global);
__c11_atomic_fetch_add(&wglobal, 1, memory_order_seq_cst);
}
print_result(s, "OSAtomicIncrement64Barrier:");
print_result(s, "64-bit atomic_fetch_add with memory_order_seq_cst barrier:");

w_global = 0;
w_global = ATOMIC_VAR_INIT(0);

s = mach_absolute_time();
for (i = cnt; i; i--) {
OSAtomicIncrement64(&w_global);
__c11_atomic_fetch_add(&wglobal, 1, memory_order_relaxed);
}
print_result(s, "OSAtomicIncrement64:");
print_result(s, "64-bit atomic_fetch_add with memory_order_seq_cst barrier:");

global = 0;
global = ATOMIC_VAR_INIT(0);

s = mach_absolute_time();
for (i = cnt; i; i--) {
while (!__sync_bool_compare_and_swap(&global, 0, 1)) {
atomic_int zero = ATOMIC_VAR_INIT(0);
while (!atomic_compare_exchange_weak(&global, &zero, 1)) {
do {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__ ("pause");
Expand All @@ -646,16 +644,16 @@ __asm__ __volatile__ ("svc 0x80" : "+r" (_r0)
#endif
} while (global);
}
global = 0;
global = ATOMIC_VAR_INIT(0);
}
print_result(s, "Inlined spin lock/unlock:");

s = mach_absolute_time();
for (i = cnt; i; i--) {
OSSpinLockLock(&slock);
OSSpinLockUnlock(&slock);
os_unfair_lock_lock(&slock);
os_unfair_lock_unlock(&slock);
}
print_result(s, "OSSpinLock/Unlock:");
print_result(s, "os_unfair_lock_lock/unlock:");

s = mach_absolute_time();
for (i = cnt; i; i--) {
Expand Down
11 changes: 5 additions & 6 deletions tests/Foundation/dispatch_apply_gc.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,25 @@
#else
const size_t final = 1000, desclen = 8892;
#endif
NSAutoreleasePool *pool = nil;

static void
work(void* ctxt __attribute__((unused)))
{
pool = [[NSAutoreleasePool alloc] init];
@autoreleasepool {
NSMutableArray *a = [NSMutableArray array];
OSSpinLock sl = OS_SPINLOCK_INIT, *l = &sl;
os_unfair_lock sl = OS_UNFAIR_LOCK_INIT, *l = &sl;

dispatch_apply(final, dispatch_get_global_queue(0, 0), ^(size_t i){
NSDecimalNumber *n = [NSDecimalNumber decimalNumberWithDecimal:
[[NSNumber numberWithInteger:i] decimalValue]];
OSSpinLockLock(l);
os_unfair_lock_lock(l);
[a addObject:n];
OSSpinLockUnlock(l);
os_unfair_lock_unlock(l);
});
test_long("count", [a count], final);
test_long("description length", [[a description] length], desclen);
a = nil;
[pool drain];
}
test_stop_after_delay((void*)(intptr_t)1);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/Foundation/nsoperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ - (void)main
{
dispatch_test_start("NSOperation");

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ autoreleasepool {

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
test_ptr_notnull("NSOperationQueue", queue);
Expand All @@ -67,7 +67,7 @@ - (void)main

[[NSRunLoop mainRunLoop] run];

[pool release];
}

return 0;
}
3 changes: 0 additions & 3 deletions tests/dispatch_after.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
#endif
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif

#include <bsdtests.h>
#include <Block.h>
Expand Down
21 changes: 10 additions & 11 deletions tests/dispatch_apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,13 @@
#endif
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
#include <stdatomic.h>
#include <sys/types.h>

#include <bsdtests.h>
#include "dispatch_test.h"

static volatile int32_t busy_threads_started, busy_threads_finished;
static atomic_int busy_threads_started, busy_threads_finished;

/*
* Keep a thread busy, spinning on the CPU.
Expand All @@ -57,7 +55,7 @@ static void busythread(void *ignored)
/* prevent i and j been optimized out */
volatile uint64_t i = 0, j = 0;

OSAtomicIncrement32(&busy_threads_started);
__c11_atomic_fetch_add(&busy_threads_started, 1, memory_order_relaxed);

while(!all_done)
{
Expand All @@ -67,7 +65,7 @@ static void busythread(void *ignored)
}
(void)j;

OSAtomicIncrement32(&busy_threads_finished);
__c11_atomic_fetch_add(&busy_threads_finished, 1, memory_order_relaxed);
}

/*
Expand Down Expand Up @@ -103,12 +101,13 @@ static void test_apply_contended(dispatch_queue_t dq)
usleep(1);
}

volatile __block int32_t count = 0;

__block atomic_int count = ATOMIC_VAR_INIT(0);
const int32_t final = 32;

int32_t before = busy_threads_started;
dispatch_apply(final, dq, ^(size_t i __attribute__((unused))) {
OSAtomicIncrement32(&count);
__c11_atomic_fetch_add(&count, 1, memory_order_relaxed);
});
int32_t after = busy_threads_finished;

Expand All @@ -129,22 +128,22 @@ main(void)
{
dispatch_test_start("Dispatch Apply");

volatile __block int32_t count = 0;
__block atomic_int count = ATOMIC_VAR_INIT(0);
const int32_t final = 32;

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
test_ptr_notnull("dispatch_get_global_queue", queue);

dispatch_apply(final, queue, ^(size_t i __attribute__((unused))) {
OSAtomicIncrement32(&count);
__c11_atomic_fetch_add(&count, 1, memory_order_relaxed);
});
test_long("count", count, final);

count = 0; // rdar://problem/9294578
dispatch_apply(final, queue, ^(size_t i __attribute__((unused))) {
dispatch_apply(final, queue, ^(size_t ii __attribute__((unused))) {
dispatch_apply(final, queue, ^(size_t iii __attribute__((unused))) {
OSAtomicIncrement32(&count);
__c11_atomic_fetch_add(&count, 1, memory_order_relaxed);
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion tests/dispatch_cascade.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ cascade(void* context)
dispatch_async_f(queues[idx], context, cascade);
}

if (__sync_sub_and_fetch(&iterations, 1) == 0) {
if (atomic_fetch_sub(&iterations, 1, memory_order_relaxed) - 1 == 0) {
done = 1;
histogram();
dispatch_async_f(dispatch_get_main_queue(), NULL, cleanup);
Expand Down
Loading

0 comments on commit 19c218b

Please sign in to comment.