Serene Runtime 1.0.0
C runtime for the Serene programming language
Loading...
Searching...
No Matches
utils.h File Reference
#include <stdatomic.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
Include dependency graph for utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  srn_spinlock_t
 

Macros

#define SERENE_DEBUG   0
 
#define UNUSED(x)
 
#define PANIC(msg)
 
#define TODO(msg)
 
#define PANIC_WITH_CTX(ctx, msg)
 
#define PANIC_IF(cond, msg)
 
#define PANIC_IF_NULL(ptr)
 
#define SNPRINTF(buf, s, f, ...)
 
#define SHOULD_NOT_HAPPEN   PANIC("This should not happen")
 
#define PANIC_ON_ERR(interr)
 
#define SRN_ATTR_COLD
 
#define SRN_ATTR_FMT(a, b)
 
#define DBG(...)
 
#define DBG_HEX(...)
 
#define DBG_ASSERT(x)
 

Typedefs

typedef struct srn_spinlock_t srn_spinlock_t
 

Functions

void srn_panic (const char *msg, const char *file, size_t line, const char *fn)
 TODO(lxsameer): unwind the stack.
 
static uint32_t srn_popcnt32 (uint32_t x)
 
static uint64_t srn_popcnt64 (uint64_t x)
 
static void cpu_relax (void)
 A portable way to use pasue instructions.
 
static void srn_spinlock_unlock (srn_spinlock_t *lock)
 
static void srn_spinlock_init (srn_spinlock_t *lock)
 
static void srn_spinlock_lock (srn_spinlock_t *lock)
 
char * srn_copy_bytes (srn_context_t *ctx, const char *src, size_t len, size_t alignment)
 
char * srn_dup_str (srn_mm_t *mm, const char *s)
 Copy a null terminated C string into a fresh allocation made through mm.
 

Macro Definition Documentation

◆ DBG

#define DBG ( ...)
Value:
do { \
} while (0)

Definition at line 177 of file utils.h.

177# define DBG(...) \
178 do { \
179 } while (0)

◆ DBG_ASSERT

#define DBG_ASSERT ( x)
Value:
do { \
(void)sizeof(x); \
} while (0)

Definition at line 183 of file utils.h.

183# define DBG_ASSERT(x) \
184 do { \
185 (void)sizeof(x); \
186 } while (0)

◆ DBG_HEX

#define DBG_HEX ( ...)
Value:
do { \
} while (0)

Definition at line 180 of file utils.h.

180# define DBG_HEX(...) \
181 do { \
182 } while (0)

◆ PANIC

#define PANIC ( msg)
Value:
srn_panic(msg, __FILE__, __LINE__, __func__)
void srn_panic(const char *msg, const char *file, size_t line, const char *fn)
TODO(lxsameer): unwind the stack.
Definition utils.c:31

Definition at line 51 of file utils.h.

◆ PANIC_IF

#define PANIC_IF ( cond,
msg )
Value:
do { \
if (cond) { \
PANIC(msg); \
} \
} while (0)

Definition at line 57 of file utils.h.

57#define PANIC_IF(cond, msg) \
58 do { \
59 if (cond) { \
60 PANIC(msg); \
61 } \
62 } while (0)

◆ PANIC_IF_NULL

#define PANIC_IF_NULL ( ptr)
Value:
PANIC_IF((ptr) == nullptr, "Null pointer")
#define PANIC_IF(cond, msg)
Definition utils.h:57

Definition at line 64 of file utils.h.

◆ PANIC_ON_ERR

#define PANIC_ON_ERR ( interr)
Value:
if ((interr) < 0) { \
}
#define SHOULD_NOT_HAPPEN
Definition utils.h:77

Definition at line 78 of file utils.h.

78#define PANIC_ON_ERR(interr) \
79 if ((interr) < 0) { \
80 SHOULD_NOT_HAPPEN; \
81 }

◆ PANIC_WITH_CTX

#define PANIC_WITH_CTX ( ctx,
msg )
Value:
PANIC(msg)
int srn_context_release(srn_context_t *ctx)
Definition context.c:63

Definition at line 53 of file utils.h.

53#define PANIC_WITH_CTX(ctx, msg) \
54 srn_context_release(ctx); \
55 PANIC(msg)

◆ SERENE_DEBUG

#define SERENE_DEBUG   0

Definition at line 26 of file utils.h.

◆ SHOULD_NOT_HAPPEN

#define SHOULD_NOT_HAPPEN   PANIC("This should not happen")

Definition at line 77 of file utils.h.

◆ SNPRINTF

#define SNPRINTF ( buf,
s,
f,
... )
Value:
do { \
int i = snprintf(buf, (s) + 1, f, __VA_ARGS__); \
if (i < 0) { \
PANIC("[snprintf] A negative return value"); \
} \
if (i >= (int)(s)) { \
PANIC("[snprintf] Written bytes are more than expected"); \
} \
} while (0)

Definition at line 66 of file utils.h.

66#define SNPRINTF(buf, s, f, ...) \
67 do { \
68 int i = snprintf(buf, (s) + 1, f, __VA_ARGS__); \
69 if (i < 0) { \
70 PANIC("[snprintf] A negative return value"); \
71 } \
72 if (i >= (int)(s)) { \
73 PANIC("[snprintf] Written bytes are more than expected"); \
74 } \
75 } while (0)

◆ SRN_ATTR_COLD

#define SRN_ATTR_COLD

Definition at line 103 of file utils.h.

◆ SRN_ATTR_FMT

#define SRN_ATTR_FMT ( a,
b )

Definition at line 104 of file utils.h.

◆ TODO

#define TODO ( msg)
Value:
PANIC(msg)
#define PANIC(msg)
Definition utils.h:51

Definition at line 52 of file utils.h.

◆ UNUSED

#define UNUSED ( x)
Value:
(void)(x)

Definition at line 43 of file utils.h.

Typedef Documentation

◆ srn_spinlock_t

typedef struct srn_spinlock_t srn_spinlock_t

Function Documentation

◆ cpu_relax()

static void cpu_relax ( void )
inlinestatic

A portable way to use pasue instructions.

The long list of preprocessors is there thanks to: https://github.com/goodcleanfun/cpu_relax

Definition at line 221 of file utils.h.

221 {
222#if defined(_M_IX86) || defined(__I86__) || defined(i686) || \
223 defined(__i686) || defined(__i686__) || defined(i586) || \
224 defined(__i586) || defined(__i586__) || defined(i486) || \
225 defined(__i486) || defined(__i486__) || defined(i386) || \
226 defined(__i386) || defined(__i386__) || defined(_X86_) || \
227 defined(__X86__) || defined(__THW_INTEL__)
228# if defined(__SSE2__)
229 _mm_pause();
230# elif defined(_MSC_VER)
231 __asm pause;
232# else
233 __asm__ __volatile__("pause");
234# endif
235#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
236 defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
237# if defined(__SSE2__)
238 _mm_pause();
239# endif
240#elif defined(__aarch64__) || defined(_M_ARM64)
241# if defined(_MSC_VER)
242 __isb(_ARM64_BARRIER_SY);
243# else
244 __asm__ __volatile__("isb\n");
245# endif
246#elif defined(__ARM_ARCH) || defined(_M_ARM) || defined(__arm__) || \
247 defined(__thumb__) || defined(__TARGET_ARCH_ARM) || defined(_ARM)
248# if defined(_MSC_VER)
249 __yield();
250# else
251 __asm__ __volatile__("yield");
252# endif
253#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || \
254 defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC) || \
255 defined(__ppc)
256 __asm__ __volatile__("or 27,27,27" ::: "memory");
257#elif defined(__riscv) || defined(__riscv__)
258# if defined(__riscv_pause)
259 __builtin_riscv_pause();
260# else
261 __asm__ __volatile__("nop");
262# endif
263#elif defined(__loongarch32) || defined(__loongarch64)
264 __asm__ __volatile__("nop");
265#elif defined(__wasm__)
266 __asm__ __volatile__("nop");
267#endif
268}
Here is the caller graph for this function:

◆ srn_copy_bytes()

char * srn_copy_bytes ( srn_context_t * ctx,
const char * src,
size_t len,
size_t alignment )

Definition at line 42 of file utils.c.

42 {
43 PANIC_IF_NULL(ctx);
44
45 char *dst = srn_allocate(ctx, len, alignment);
46
47 // It will panic earlier anyway.
48 if (dst == nullptr) {
49 return nullptr;
50 }
51
52 memcpy(dst, src, len);
53 return dst;
54}
void * srn_allocate(const srn_context_t *ctx, size_t size, size_t alignment)
Definition context.c:72
#define PANIC_IF_NULL(ptr)
Definition utils.h:64
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_dup_str()

char * srn_dup_str ( srn_mm_t * mm,
const char * s )

Copy a null terminated C string into a fresh allocation made through mm.

Returns nullptr on allocation failure.

Definition at line 56 of file utils.c.

56 {
57 PANIC_IF_NULL(mm);
59 size_t n = strlen(s);
60 char *copy = srn_mm_allocate(mm, n + 1);
61 if (copy == nullptr) {
62 return nullptr;
63 }
64 memcpy(copy, s, n + 1);
65 return copy;
66}
int n
Definition acutest.h:538
void * srn_mm_allocate(srn_mm_t *mm, size_t size)
Generic allocations that do not participate in the block based pools.
Definition default.c:141
Here is the call graph for this function:

◆ srn_panic()

void srn_panic ( const char * msg,
const char * file,
size_t line,
const char * fn )

TODO(lxsameer): unwind the stack.

Definition at line 31 of file utils.c.

31 {
32 (void)fprintf(stderr, "PANIC: %s %s:%zu (%s)\n", msg, file, line, fn);
33 (void)fflush(nullptr);
34#if SERENE_DEBUG
35 __builtin_debugtrap();
36 __builtin_unreachable();
37#else
38 abort();
39#endif
40}
int const char * file
Definition acutest.h:788
void int line
Definition acutest.h:743

◆ srn_popcnt32()

static uint32_t srn_popcnt32 ( uint32_t x)
inlinestatic

Definition at line 192 of file utils.h.

192 {
193#if defined(__clang__) || defined(__GNUC__)
194 return (uint32_t)__builtin_popcount(x);
195#else
196 x = x - ((x >> 1) & 0x55555555u);
197 x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u);
198 return (((x + (x >> 4)) & 0x0F0F0F0Fu) * 0x01010101u) >> 24;
199#endif
200}
Here is the caller graph for this function:

◆ srn_popcnt64()

static uint64_t srn_popcnt64 ( uint64_t x)
inlinestatic

Definition at line 202 of file utils.h.

202 {
203#if defined(__GNUC__) || defined(__clang__)
204 return (uint64_t)__builtin_popcountll(x);
205#else
206 unsigned c = 0;
207 while (x) {
208 x &= x - 1;
209 ++c;
210 }
211 return c;
212#endif
213}

◆ srn_spinlock_init()

static void srn_spinlock_init ( srn_spinlock_t * lock)
inlinestatic

Definition at line 281 of file utils.h.

281 {
282 lock->flag = (atomic_flag)ATOMIC_FLAG_INIT;
284}
atomic_flag flag
Definition utils.h:274
static void srn_spinlock_unlock(srn_spinlock_t *lock)
Definition utils.h:277
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_spinlock_lock()

static void srn_spinlock_lock ( srn_spinlock_t * lock)
inlinestatic

Definition at line 286 of file utils.h.

286 {
287 while (atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire)) {
288 // Keep busy for the lock to get unlocked
289 cpu_relax();
290 }
291}
static void cpu_relax(void)
A portable way to use pasue instructions.
Definition utils.h:221
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_spinlock_unlock()

static void srn_spinlock_unlock ( srn_spinlock_t * lock)
inlinestatic

Definition at line 277 of file utils.h.

277 {
278 atomic_flag_clear_explicit(&lock->flag, memory_order_release);
279}
Here is the caller graph for this function: