Skip to content

Commit

Permalink
Change static initializer of initial_heap_ptr and spin_dummy to zero
Browse files Browse the repository at this point in the history
(refactoring)

* src/atomic_ops.c (spin_dummy): Define as volatile; initialize to 0
(instead of 1).
* src/atomic_ops.c (AO_spin): Change the code to expect spin_dummy
variable to be 0 instead of 1; update comment.
* src/atomic_ops.c (AO_pause): Reformat code.
* src/atomic_ops_malloc.c (initial_heap_ptr): Initialize to 0 (instead
of (AO_uintptr_t)AO_initial_heap); add comment.
* src/atomic_ops_malloc.c (get_chunk): If initial_ptr variable is 0
then treat its value as (AO_uintptr_t)AO_initial_heap; add assertion
that my_chunk_ptr is non-zero when storing it to initial_heap_ptr.
  • Loading branch information
ivmai committed Oct 20, 2023
1 parent c56149c commit 400a88b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 25 deletions.
45 changes: 22 additions & 23 deletions src/atomic_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ AO_API void AO_store_full_emulation(volatile AO_t *addr, AO_t val)

#endif

static AO_t spin_dummy = 1;
static volatile AO_t spin_dummy = 0;

/* Spin for 2**n units. */
static void AO_spin(int n)
Expand All @@ -267,35 +267,34 @@ static void AO_spin(int n)
int i = 2 << n;

while (i-- > 0)
j += (j - 1) << 2;
/* Given 'spin_dummy' is initialized to 1, j is 1 after the loop. */
j += j << 2;
/* Given spin_dummy is initialized to 0, j is 0 after the loop. */
AO_store(&spin_dummy, j);
}

AO_API void AO_pause(int n)
{
if (n < 12)
if (n < 12) {
AO_spin(n);
else
{
# ifdef AO_USE_NANOSLEEP
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = n > 28 ? 100000L * 1000 : 1L << (n - 2);
nanosleep(&ts, 0);
# elif defined(AO_USE_WIN32_PTHREADS)
Sleep(n > 28 ? 100 /* millis */
: n < 22 ? 1 : (DWORD)1 << (n - 22));
# else
struct timeval tv;
/* Short async-signal-safe sleep. */
int usec = n > 28 ? 100000 : 1 << (n - 12);
} else {
# ifdef AO_USE_NANOSLEEP
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = n > 28 ? 100000L * 1000 : 1L << (n - 2);
nanosleep(&ts, 0);
# elif defined(AO_USE_WIN32_PTHREADS)
Sleep(n > 28 ? 100 /* millis */
: n < 22 ? 1 : (DWORD)1 << (n - 22));
# else
struct timeval tv;
/* Short async-signal-safe sleep. */
int usec = n > 28 ? 100000 : 1 << (n - 12);
/* Use an intermediate variable (of int type) to avoid */
/* "shift followed by widening conversion" warning. */

tv.tv_sec = 0;
tv.tv_usec = usec;
(void)select(0, 0, 0, 0, &tv);
# endif
}
tv.tv_sec = 0;
tv.tv_usec = usec;
(void)select(0, 0, 0, 0, &tv);
# endif
}
}
11 changes: 9 additions & 2 deletions src/atomic_ops_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@

static char AO_initial_heap[AO_INITIAL_HEAP_SIZE]; /* ~2MB by default */

static volatile AO_uintptr_t initial_heap_ptr = (AO_uintptr_t)AO_initial_heap;
static volatile AO_uintptr_t initial_heap_ptr = 0;
/* Note: the real initialization of this variable is */
/* deferred to get_chunk() - it is workaround for an */
/* E2K compiler complaining about the cast of a pointer */
/* to uintptr_t type in a static initializer. */

#if defined(HAVE_MMAP)

Expand Down Expand Up @@ -236,9 +240,12 @@ get_chunk(void)
for (;;) {
AO_uintptr_t initial_ptr = AO_uintptr_load(&initial_heap_ptr);

my_chunk_ptr = (initial_ptr + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
my_chunk_ptr = ((AO_EXPECT_FALSE(0 == initial_ptr) ?
(AO_uintptr_t)AO_initial_heap : initial_ptr)
+ ALIGNMENT - 1) & ~(ALIGNMENT - 1);
if (initial_ptr != my_chunk_ptr) {
/* Align correctly. If this fails, someone else did it for us. */
assert(my_chunk_ptr != 0);
(void)AO_uintptr_compare_and_swap_acquire(&initial_heap_ptr,
initial_ptr, my_chunk_ptr);
}
Expand Down

0 comments on commit 400a88b

Please sign in to comment.