Compare commits
4 commits
29fbcca987
...
33d55b2cd2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33d55b2cd2 | ||
|
|
080928d3fd | ||
|
|
f3522129a3 | ||
|
|
d0aa85f62e |
8 changed files with 256 additions and 10 deletions
59
bump.c
Normal file
59
bump.c
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFSIZE (1024)
|
||||||
|
static uint8_t some_large_buf[BUFSIZE] = {0};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t buflen;
|
||||||
|
size_t bufptr;
|
||||||
|
} fast_alloc_t;
|
||||||
|
|
||||||
|
void *fast_alloc(fast_alloc_t *fa, size_t s) {
|
||||||
|
if (fa->bufptr + s > fa->buflen) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void *p = fa->buf + fa->bufptr;
|
||||||
|
fa->bufptr += s;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fast_alloc_init(fast_alloc_t *fa, uint8_t *buf, size_t buflen) {
|
||||||
|
fa->buf = buf;
|
||||||
|
fa->buflen = buflen;
|
||||||
|
fa->bufptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fast_alloc_wipe(fast_alloc_t *fa) {
|
||||||
|
fa->bufptr = 0;
|
||||||
|
memset(fa->buf, 0, fa->buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
fast_alloc_t fa = {0};
|
||||||
|
fast_alloc_init(&fa, some_large_buf, BUFSIZE);
|
||||||
|
|
||||||
|
int *a = fast_alloc(&fa, sizeof(int));
|
||||||
|
*a = 10;
|
||||||
|
|
||||||
|
int *b = fast_alloc(&fa, sizeof(int));
|
||||||
|
*b = INT_MAX;
|
||||||
|
|
||||||
|
printf("Number: %d\n", *a);
|
||||||
|
printf("Number: %d\n", *b);
|
||||||
|
assert(*a == 10);
|
||||||
|
assert(*b == INT_MAX);
|
||||||
|
|
||||||
|
fast_alloc_wipe(&fa);
|
||||||
|
|
||||||
|
printf("Number: %d\n", *a);
|
||||||
|
printf("Number: %d\n", *b);
|
||||||
|
assert(*a != 10);
|
||||||
|
assert(*b != INT_MAX);
|
||||||
|
|
||||||
|
printf("All ok!\n");
|
||||||
|
}
|
||||||
32
prand.c
32
prand.c
|
|
@ -2,14 +2,13 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define BUILD_SEED \
|
#define PRAND_BUILD_SEED \
|
||||||
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
|
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
|
||||||
(uint64_t)(__TIME__[6]) * (uint64_t)(__TIME__[7]))
|
(uint64_t)(__TIME__[6]) * (uint64_t)(__TIME__[7]))
|
||||||
|
|
||||||
#define PRNG_SAVE_INTERVAL 50 // Save every 1000 calls to prand()
|
static uint64_t seed = PRAND_BUILD_SEED * 6364136223846793005ULL + 1;
|
||||||
|
|
||||||
static uint64_t seed = BUILD_SEED;
|
|
||||||
|
|
||||||
uint64_t prand() {
|
uint64_t prand() {
|
||||||
seed = seed * 6364136223846793005ULL + 1;
|
seed = seed * 6364136223846793005ULL + 1;
|
||||||
|
|
@ -17,31 +16,44 @@ uint64_t prand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t prand_range(uint64_t min, uint64_t max) {
|
inline uint64_t prand_range(uint64_t min, uint64_t max) {
|
||||||
return min + (prand() % (max - min + 1));
|
uint64_t range = max - min + 1;
|
||||||
|
uint64_t x;
|
||||||
|
uint64_t limit = UINT64_MAX - (UINT64_MAX % range);
|
||||||
|
|
||||||
|
do {
|
||||||
|
x = prand();
|
||||||
|
} while (x > limit);
|
||||||
|
|
||||||
|
return min + (x % range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprand(uint64_t s) {
|
void sprand(uint64_t s) {
|
||||||
if (s) {
|
if (s) {
|
||||||
seed = s;
|
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
|
||||||
} else {
|
} else {
|
||||||
rand_reseed();
|
seed ^= PRAND_BUILD_SEED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rand_reseed() {
|
#undef PRAND_BUILD_SEED
|
||||||
seed = BUILD_SEED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PRAND_MAIN
|
#define PRAND_MAIN
|
||||||
#ifdef PRAND_MAIN
|
#ifdef PRAND_MAIN
|
||||||
int main() {
|
int main() {
|
||||||
// time(NULL) provides a somewhat unique seed at runtime
|
// time(NULL) provides a somewhat unique seed at runtime
|
||||||
sprand(time(NULL));
|
sprand(time(NULL));
|
||||||
|
sprand(getpid());
|
||||||
|
sprand(0);
|
||||||
|
|
||||||
uint64_t rn1 = prand();
|
uint64_t rn1 = prand();
|
||||||
uint64_t rn2 = prand();
|
uint64_t rn2 = prand();
|
||||||
|
|
||||||
printf("rn1 = %lu\n", rn1);
|
printf("rn1 = %lu\n", rn1);
|
||||||
printf("rn2 = %lu\n", rn2);
|
printf("rn2 = %lu\n", rn2);
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; i++) {
|
||||||
|
uint64_t random = prand_range(0, 1000);
|
||||||
|
printf("random = %lu\n", random);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
24
signals/Makefile
Normal file
24
signals/Makefile
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
CC ?= gcc
|
||||||
|
CFLAGS ?= -Wall -O2
|
||||||
|
|
||||||
|
# This is not how makefiles should be written.
|
||||||
|
# Pretend you did not see this
|
||||||
|
|
||||||
|
all: main.elf main_sigaction.elf
|
||||||
|
|
||||||
|
TARGET = main.elf
|
||||||
|
SRC = main.c
|
||||||
|
|
||||||
|
TARGET2 = main_sigaction.elf
|
||||||
|
SRC2 = main_sigaction.c
|
||||||
|
|
||||||
|
$(TARGET): $(SRC)
|
||||||
|
@echo CC $@
|
||||||
|
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
$(TARGET2): $(SRC2)
|
||||||
|
@echo CC $@
|
||||||
|
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.elf
|
||||||
17
signals/main.c
Normal file
17
signals/main.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void handler(int sig) {
|
||||||
|
printf("Caught signal %d\n", sig);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
signal(SIGINT, handler); // Handle Ctrl+C
|
||||||
|
while (1) {
|
||||||
|
printf("Running...\n");
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
signals/main_sigaction.c
Normal file
23
signals/main_sigaction.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void handler(int sig) {
|
||||||
|
write(1, "Caught SIGINT\n", 14); // Async-signal-safe output
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
struct sigaction sa;
|
||||||
|
sa.sa_handler = handler;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
|
||||||
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
printf("Running...\n");
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
spinlocks/Makefile
Normal file
14
spinlocks/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -O2
|
||||||
|
|
||||||
|
TARGET = main.elf
|
||||||
|
SRC = main.c
|
||||||
|
|
||||||
|
#LDFLAGS =
|
||||||
|
|
||||||
|
$(TARGET): $(SRC)
|
||||||
|
@echo CC $@
|
||||||
|
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET)
|
||||||
31
spinlocks/main.c
Normal file
31
spinlocks/main.c
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "spinlock.h"
|
||||||
|
|
||||||
|
spinlock_t lock;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
void *worker(void *arg) {
|
||||||
|
printf("Hello from %s!\n", (char *)arg);
|
||||||
|
for (int i = 0; i < 100000; i++) {
|
||||||
|
acquire(&lock);
|
||||||
|
counter++;
|
||||||
|
release(&lock);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
pthread_t thread1, thread2;
|
||||||
|
|
||||||
|
initlock(&lock);
|
||||||
|
|
||||||
|
pthread_create(&thread1, NULL, worker, "Thread1");
|
||||||
|
pthread_create(&thread2, NULL, worker, "Thread2");
|
||||||
|
|
||||||
|
pthread_join(thread1, NULL);
|
||||||
|
pthread_join(thread2, NULL);
|
||||||
|
|
||||||
|
printf("Counter value: %d\n", counter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
66
spinlocks/spinlock.h
Normal file
66
spinlocks/spinlock.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int locked; // 0 = unlocked, 1 = locked
|
||||||
|
} spinlock_t;
|
||||||
|
|
||||||
|
static inline void initlock(spinlock_t *lk) {
|
||||||
|
lk->locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void acquire(spinlock_t *lk) {
|
||||||
|
while (__sync_lock_test_and_set(&lk->locked, 1) != 0); // spin
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void release(spinlock_t *lk) {
|
||||||
|
__sync_lock_release(&lk->locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ATOMIC_MUTEX
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
atomic_int flag;
|
||||||
|
} mutex_t;
|
||||||
|
|
||||||
|
void mutex_init(mutex_t *m) {
|
||||||
|
atomic_store(&m->flag, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m) {
|
||||||
|
int expected;
|
||||||
|
do {
|
||||||
|
expected = 0;
|
||||||
|
} while (!atomic_compare_exchange_weak(&m->flag, &expected, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_unlock(mutex_t *m) {
|
||||||
|
atomic_store(&m->flag, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef ATOMIC_MUTEX_RISCV
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile int locked;
|
||||||
|
} spinlock_t;
|
||||||
|
|
||||||
|
void spinlock_init(spinlock_t *lk) {
|
||||||
|
lk->locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinlock_acquire(spinlock_t *lk) {
|
||||||
|
int tmp;
|
||||||
|
do {
|
||||||
|
__asm__ volatile("amoswap.w %0, %1, (%2)"
|
||||||
|
: "=r"(tmp) // old value in tmp
|
||||||
|
: "r"(1), "r"(&lk->locked) // store 1 into memory
|
||||||
|
: "memory");
|
||||||
|
} while (tmp != 0); // spin until old value was 0
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinlock_release(spinlock_t *lk) {
|
||||||
|
__asm__ volatile("amoswap.w zero, %1, (%0)" : : "r"(&lk->locked), "r"(0) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue