Compare commits

...

4 Commits

Author SHA1 Message Date
marv7000 4c781f31ad replace stdatomic.h with zinnia/atomic.h 2026-10-14 00:05:32 +02:00
marv7000 f9a456b09d x86 stuff 2026-10-14 00:02:13 +02:00
marv7000 deec8099cb expose cmdline for /dev/cmdline later 2026-10-13 23:59:28 +02:00
marv7000 c5c3acc520 move fbcon to dev/video 2026-10-13 23:54:38 +02:00
26 changed files with 145 additions and 193 deletions
+1
View File
@@ -240,6 +240,7 @@ static struct idt_entry idt[256] = {};
void idt_init() { void idt_init() {
REPEAT_256(INTERRUPT_SETUP) REPEAT_256(INTERRUPT_SETUP)
idt[IDT_BP].attrib |= CPL_USER << 5;
} }
void idt_load() { void idt_load() {
+6
View File
@@ -37,6 +37,7 @@ struct arch_context {
}; };
#define ARCH_CTX_NUM rax #define ARCH_CTX_NUM rax
#define ARCH_CTX_SP rsp
#define ARCH_CTX_A0 rdi #define ARCH_CTX_A0 rdi
#define ARCH_CTX_A1 rsi #define ARCH_CTX_A1 rsi
#define ARCH_CTX_A2 rdx #define ARCH_CTX_A2 rdx
@@ -45,3 +46,8 @@ struct arch_context {
#define ARCH_CTX_A5 r9 #define ARCH_CTX_A5 r9
#define ARCH_CTX_RET0 rax #define ARCH_CTX_RET0 rax
#define ARCH_CTX_RET1 rdx #define ARCH_CTX_RET1 rdx
struct arch_syscall_restart {
uint64_t rax;
uint64_t rdx;
};
+6
View File
@@ -40,6 +40,12 @@ static inline void asm_wrxcr(uint32_t reg, uint64_t val) {
asm volatile("xsetbv" ::"a"(eax), "d"(edx), "c"(reg) : "memory"); asm volatile("xsetbv" ::"a"(eax), "d"(edx), "c"(reg) : "memory");
} }
static inline uint64_t asm_rdxcr(uint32_t reg) {
uint32_t eax, edx;
asm volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(reg));
return ((uint64_t)edx << 32) | eax;
}
// Saves the FPU state to a 512-byte region of memory using FXSAVE. // Saves the FPU state to a 512-byte region of memory using FXSAVE.
// Pointer must be 16-byte aligned. // Pointer must be 16-byte aligned.
static inline void asm_fxsave(void* mem) { static inline void asm_fxsave(void* mem) {
+14
View File
@@ -206,6 +206,20 @@
#define CPL_USER (0x3) #define CPL_USER (0x3)
#define CPL_KERNEL (0x0) #define CPL_KERNEL (0x0)
#define IDT_DE (0x0)
#define IDT_DB (0x1)
#define IDT_BP (0x3)
#define IDT_OF (0x4)
#define IDT_BR (0x5)
#define IDT_UD (0x6)
#define IDT_NM (0x7)
#define IDT_SS (0xC)
#define IDT_GP (0xD)
#define IDT_PF (0xE) #define IDT_PF (0xE)
#define IDT_MF (0x10)
#define IDT_AC (0x11)
#define IDT_XM (0x13)
#define IDT_IPI_SHOOTDOWN (0xFC)
#define IDT_TIMER (0xFD)
#define IDT_SPURIOUS (0xFE) #define IDT_SPURIOUS (0xFE)
#define IDT_IPI_RESCHED (0xFF) #define IDT_IPI_RESCHED (0xFF)
+1 -1
View File
@@ -1,8 +1,8 @@
#pragma once #pragma once
#include <zinnia/atomic.h>
#include <zinnia/compiler.h> #include <zinnia/compiler.h>
#include <zinnia/utils.h> #include <zinnia/utils.h>
#include <stdatomic.h>
#include <stdint.h> #include <stdint.h>
#include <x86_64/gdt.h> #include <x86_64/gdt.h>
+3 -3
View File
@@ -2,6 +2,7 @@
#include <zinnia/alloc.h> #include <zinnia/alloc.h>
#include <zinnia/assert.h> #include <zinnia/assert.h>
#include <zinnia/atomic.h>
#include <zinnia/clock.h> #include <zinnia/clock.h>
#include <zinnia/compiler.h> #include <zinnia/compiler.h>
#include <zinnia/irq.h> #include <zinnia/irq.h>
@@ -12,7 +13,6 @@
#include <zinnia/types.h> #include <zinnia/types.h>
#include <zinnia/utils.h> #include <zinnia/utils.h>
#include <zinnia/vma.h> #include <zinnia/vma.h>
#include <stdatomic.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -172,7 +172,7 @@ static void ap_entry(phys_t info_addr) {
// Let the BSP know that we're alive. // Let the BSP know that we're alive.
// `info` must not be touched after this point. // `info` must not be touched after this point.
atomic_store_explicit(&info->booted, 1, memory_order_release); atomic_store(&info->booted, 1, ATOMIC_RELEASE);
log("CPU %zu online\n", cpu->id); log("CPU %zu online\n", cpu->id);
@@ -231,7 +231,7 @@ static bool start_ap(phys_t trampoline, uint32_t temp_cr3, uint32_t lapic_id) {
); );
clock_spin_ns(10'000'000); clock_spin_ns(10'000'000);
for (uint64_t waited = 0; !atomic_load_explicit(&info->booted, memory_order_acquire); waited += 1'000'000) { for (uint64_t waited = 0; !atomic_load(&info->booted, ATOMIC_ACQUIRE); waited += 1'000'000) {
if (waited >= AP_BOOT_TIMEOUT_NS) { if (waited >= AP_BOOT_TIMEOUT_NS) {
// The per-CPU data and boot stack are leaked on purpose, in case the AP still comes up. // The per-CPU data and boot stack are leaked on purpose, in case the AP still comes up.
log_err("CPU %zu (LAPIC %u) did not respond\n", cpu->id, lapic_id); log_err("CPU %zu (LAPIC %u) did not respond\n", cpu->id, lapic_id);
+6
View File
@@ -9,6 +9,11 @@ extern const struct cmdline_option* __ld_cmdline_start[];
extern const struct cmdline_option* __ld_cmdline_end[]; extern const struct cmdline_option* __ld_cmdline_end[];
static char cmdline_buf[0x1000]; static char cmdline_buf[0x1000];
static char cmdline_raw[0x1000];
const char* cmdline_get() {
return cmdline_raw;
}
void cmdline_parse_buf( void cmdline_parse_buf(
char* cmdline_buf, char* cmdline_buf,
@@ -112,5 +117,6 @@ void cmdline_parse(const char* cmdline) {
const size_t len = strnlen(cmdline, sizeof(cmdline_buf) - 1); const size_t len = strnlen(cmdline, sizeof(cmdline_buf) - 1);
memcpy(cmdline_buf, cmdline, len); memcpy(cmdline_buf, cmdline, len);
memcpy(cmdline_raw, cmdline, len);
cmdline_parse_buf(cmdline_buf, len, __ld_cmdline_start, __ld_cmdline_end); cmdline_parse_buf(cmdline_buf, len, __ld_cmdline_start, __ld_cmdline_end);
} }
+2 -3
View File
@@ -1,7 +1,7 @@
#include <zinnia/alloc.h> #include <zinnia/alloc.h>
#include <zinnia/atomic.h>
#include <zinnia/utils.h> #include <zinnia/utils.h>
#include <zinnia/virt.h> #include <zinnia/virt.h>
#include <stdatomic.h>
#include <stddef.h> #include <stddef.h>
struct page* vm_pfndb = nullptr; struct page* vm_pfndb = nullptr;
@@ -12,8 +12,7 @@ static _Atomic(size_t) mapping_offset = 0;
uintptr_t vm_alloc(size_t length) { uintptr_t vm_alloc(size_t length) {
uintptr_t base = arch_mem_mapping_addr(); uintptr_t base = arch_mem_mapping_addr();
size_t offset = size_t offset = atomic_fetch_add(&mapping_offset, ALIGN_UP(length, arch_mem_page_size()), ATOMIC_ACQUIRE);
atomic_fetch_add_explicit(&mapping_offset, ALIGN_UP(length, arch_mem_page_size()), memory_order_acquire);
return base + offset; return base + offset;
} }
-1
View File
@@ -1,7 +1,6 @@
kernel_sources += files( kernel_sources += files(
'clock.c', 'clock.c',
'console.c', 'console.c',
'fbcon.c',
'initgraph.c', 'initgraph.c',
'irq.c', 'irq.c',
'ksyms.c', 'ksyms.c',
+2 -2
View File
@@ -1,10 +1,10 @@
#include <zinnia/alloc.h> #include <zinnia/alloc.h>
#include <zinnia/atomic.h>
#include <zinnia/cmdline.h> #include <zinnia/cmdline.h>
#include <zinnia/compiler.h> #include <zinnia/compiler.h>
#include <zinnia/percpu.h> #include <zinnia/percpu.h>
#include <zinnia/utils.h> #include <zinnia/utils.h>
#include <arch/percpu.h> #include <arch/percpu.h>
#include <stdatomic.h>
extern uint8_t __ld_percpu_start[]; extern uint8_t __ld_percpu_start[];
extern uint8_t __ld_percpu_end[]; extern uint8_t __ld_percpu_end[];
@@ -37,7 +37,7 @@ struct percpu* percpu_new() {
struct percpu* cpu = HHDM_PTR(mem); struct percpu* cpu = HHDM_PTR(mem);
cpu->self = cpu; cpu->self = cpu;
cpu->id = atomic_fetch_add_explicit(&num_cpus, 1, memory_order_relaxed); cpu->id = atomic_fetch_add(&num_cpus, 1, ATOMIC_RELAXED);
cpu->online = false; cpu->online = false;
return cpu; return cpu;
} }
+4 -4
View File
@@ -1,5 +1,6 @@
#include <zinnia/alloc.h> #include <zinnia/alloc.h>
#include <zinnia/assert.h> #include <zinnia/assert.h>
#include <zinnia/atomic.h>
#include <zinnia/errno.h> #include <zinnia/errno.h>
#include <zinnia/irq.h> #include <zinnia/irq.h>
#include <zinnia/list.h> #include <zinnia/list.h>
@@ -12,7 +13,6 @@
#include <zinnia/tailq.h> #include <zinnia/tailq.h>
#include <zinnia/vma.h> #include <zinnia/vma.h>
#include <arch/sched.h> #include <arch/sched.h>
#include <stdatomic.h>
#include <stdint.h> #include <stdint.h>
static void idle_func(uintptr_t) { static void idle_func(uintptr_t) {
@@ -113,7 +113,7 @@ void sched_yield(struct scheduler* sched) {
void sched_block(struct scheduler* sched) { void sched_block(struct scheduler* sched) {
irq_lock(); irq_lock();
if (atomic_exchange_explicit(&sched->current->wake_pending, false, memory_order_acq_rel)) { if (atomic_exchange(&sched->current->wake_pending, false, ATOMIC_ACQ_REL)) {
irq_unlock(); irq_unlock();
return; return;
} }
@@ -126,7 +126,7 @@ void sched_wake(struct task* task) {
if (task->state == TASK_STATE_BLOCKED) if (task->state == TASK_STATE_BLOCKED)
sched_add_task(&percpu_get()->sched, task); sched_add_task(&percpu_get()->sched, task);
else else
atomic_store_explicit(&task->wake_pending, true, memory_order_release); atomic_store(&task->wake_pending, true, ATOMIC_RELEASE);
irq_unlock(); irq_unlock();
} }
@@ -139,7 +139,7 @@ errno_t task_create(const char* name, struct vma* space, task_fn_t entry, uintpt
return ENOMEM; return ENOMEM;
static atomic_size_t last_tid = 0; static atomic_size_t last_tid = 0;
new_task->id = atomic_fetch_add_explicit(&last_tid, 1, memory_order_acquire); new_task->id = atomic_fetch_add(&last_tid, 1, ATOMIC_ACQUIRE);
new_task->space = space; new_task->space = space;
strncpy(new_task->name, name, sizeof(new_task->name)); strncpy(new_task->name, name, sizeof(new_task->name));
+5 -5
View File
@@ -1,6 +1,6 @@
#include <zinnia/atomic.h>
#include <zinnia/irq.h> #include <zinnia/irq.h>
#include <zinnia/spin.h> #include <zinnia/spin.h>
#include <stdatomic.h>
void spin_init(struct spinlock* spin) { void spin_init(struct spinlock* spin) {
spin->next = 0; spin->next = 0;
@@ -9,15 +9,15 @@ void spin_init(struct spinlock* spin) {
void spin_lock(struct spinlock* spin) { void spin_lock(struct spinlock* spin) {
irq_lock(); irq_lock();
uint32_t my = atomic_fetch_add_explicit(&spin->next, 1, memory_order_relaxed); uint32_t my = atomic_fetch_add(&spin->next, 1, ATOMIC_RELAXED);
while (atomic_load_explicit(&spin->owner, memory_order_acquire) != my) { while (atomic_load(&spin->owner, ATOMIC_ACQUIRE) != my) {
asm volatile("pause"); asm volatile("pause");
} }
} }
void spin_unlock(struct spinlock* spin) { void spin_unlock(struct spinlock* spin) {
uint32_t val = atomic_load_explicit(&spin->owner, memory_order_relaxed); uint32_t val = atomic_load(&spin->owner, ATOMIC_RELAXED);
atomic_store_explicit(&spin->owner, val + 1, memory_order_release); atomic_store(&spin->owner, val + 1, ATOMIC_RELEASE);
irq_unlock(); irq_unlock();
} }
+1
View File
@@ -14,5 +14,6 @@ config ACPI
source "dev/block/Kconfig" source "dev/block/Kconfig"
source "dev/pci/Kconfig" source "dev/pci/Kconfig"
source "dev/video/Kconfig"
endmenu endmenu
+1
View File
@@ -1,6 +1,7 @@
subdir('common') subdir('common')
subdir('block') subdir('block')
subdir('dt') subdir('dt')
subdir('video')
if kconfig.get('CONFIG_PCI', 'n') == 'y' if kconfig.get('CONFIG_PCI', 'n') == 'y'
subdir('pci') subdir('pci')
+9
View File
@@ -0,0 +1,9 @@
menu "Video Drivers"
config FBCON
bool "Framebuffer console"
default y
help
Adds a basic console that can draw on a framebuffer passed by firmware.
endmenu
+1
View File
@@ -0,0 +1 @@
kernel_sources += files('fbcon.c')
+3
View File
@@ -0,0 +1,3 @@
if kconfig.get('CONFIG_FBCON', 'n') == 'y'
subdir('fbcon')
endif
-163
View File
@@ -1,163 +0,0 @@
// SPDX-License-Identifier: ISC
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST,
} memory_order;
#define atomic_thread_fence(order) __atomic_thread_fence(order)
#define atomic_signal_fence(order) __atomic_signal_fence(order)
#ifdef __clang__
#define atomic_init(obj, value) __c11_atomic_init(obj, value)
#define atomic_store_explicit(obj, val, order) __c11_atomic_store(obj, val, order)
#define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order)
#define atomic_exchange_explicit(obj, val, order) __c11_atomic_exchange(obj, val, order)
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
__c11_atomic_compare_exchange_strong(obj, expected, desired, succ, fail)
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
__c11_atomic_compare_exchange_weak(obj, expected, desired, succ, fail)
#define atomic_fetch_add_explicit(obj, arg, order) __c11_atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub_explicit(obj, arg, order) __c11_atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_or_explicit(obj, arg, order) __c11_atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor_explicit(obj, arg, order) __c11_atomic_fetch_xor(obj, arg, order)
#define atomic_fetch_and_explicit(obj, arg, order) __c11_atomic_fetch_and(obj, arg, order)
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
#else /* GCC */
#define atomic_init(obj, value) \
do { \
*(obj) = (value); \
} while (0)
#define atomic_store_explicit(obj, val, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __av = (val); \
__atomic_store(__ao, &__av, order); \
})
#define atomic_load_explicit(obj, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __ar; \
__atomic_load(__ao, &__ar, order); \
__ar; \
})
#define atomic_exchange_explicit(obj, val, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __av = (val); \
typeof(*__ao) __ar; \
__atomic_exchange(__ao, &__av, &__ar, order); \
__ar; \
})
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
({ \
auto __ao = (obj); \
auto __ae = (expected); \
typeof(*__ao) __ad = (desired); \
__atomic_compare_exchange(__ao, __ae, &__ad, 0, succ, fail); \
})
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
({ \
auto __ao = (obj); \
auto __ae = (expected); \
typeof(*__ao) __ad = (desired); \
__atomic_compare_exchange(__ao, __ae, &__ad, 1, succ, fail); \
})
#define atomic_fetch_add_explicit(obj, arg, order) __atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub_explicit(obj, arg, order) __atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_or_explicit(obj, arg, order) __atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor_explicit(obj, arg, order) __atomic_fetch_xor(obj, arg, order)
#define atomic_fetch_and_explicit(obj, arg, order) __atomic_fetch_and(obj, arg, order)
#define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof(*(obj)), (obj))
#endif
#define atomic_store(obj, val) atomic_store_explicit(obj, val, memory_order_seq_cst)
#define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst)
#define atomic_exchange(obj, val) atomic_exchange_explicit(obj, val, memory_order_seq_cst)
#define atomic_compare_exchange_strong(obj, expected, desired) \
atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_compare_exchange_weak(obj, expected, desired) \
atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_fetch_add(obj, arg) atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_sub(obj, arg) atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_or(obj, arg) atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_xor(obj, arg) atomic_fetch_xor_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_and(obj, arg) atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst)
// atomic_flag
typedef struct atomic_flag {
_Atomic(bool) __val;
} atomic_flag;
#define ATOMIC_FLAG_INIT {0}
#define atomic_flag_test_and_set_explicit(obj, order) atomic_exchange_explicit(&(obj)->__val, 1, order)
#define atomic_flag_test_and_set(obj) atomic_flag_test_and_set_explicit(obj, memory_order_seq_cst)
#define atomic_flag_clear_explicit(obj, order) atomic_store_explicit(&(obj)->__val, 0, order)
#define atomic_flag_clear(obj) atomic_flag_clear_explicit(obj, memory_order_seq_cst)
typedef _Atomic(bool) atomic_bool;
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
typedef _Atomic(__CHAR16_TYPE__) atomic_char16_t;
typedef _Atomic(__CHAR32_TYPE__) atomic_char32_t;
typedef _Atomic(__WCHAR_TYPE__) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
+67
View File
@@ -0,0 +1,67 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
enum atomic_order {
ATOMIC_RELAXED = __ATOMIC_RELAXED,
ATOMIC_ACQUIRE = __ATOMIC_ACQUIRE,
ATOMIC_RELEASE = __ATOMIC_RELEASE,
ATOMIC_ACQ_REL = __ATOMIC_ACQ_REL,
ATOMIC_SEQ_CST = __ATOMIC_SEQ_CST,
};
typedef _Atomic(bool) atomic_bool;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
#ifdef __clang__
#define atomic_init(obj, value) __c11_atomic_init(obj, value)
#define atomic_load(obj, order) __c11_atomic_load(obj, order)
#define atomic_store(obj, val, order) __c11_atomic_store(obj, val, order)
#define atomic_exchange(obj, val, order) __c11_atomic_exchange(obj, val, order)
#define atomic_compare_exchange(obj, expected, desired, success, failure) \
__c11_atomic_compare_exchange_strong(obj, expected, desired, success, failure)
#define atomic_compare_exchange_weak(obj, expected, desired, success, failure) \
__c11_atomic_compare_exchange_weak(obj, expected, desired, success, failure)
#define atomic_fetch_add(obj, arg, order) __c11_atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub(obj, arg, order) __c11_atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_and(obj, arg, order) __c11_atomic_fetch_and(obj, arg, order)
#define atomic_fetch_or(obj, arg, order) __c11_atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor(obj, arg, order) __c11_atomic_fetch_xor(obj, arg, order)
#else
#define atomic_init(obj, value) \
do { \
*(obj) = (value); \
} while (0)
#define atomic_load(obj, order) __atomic_load_n(obj, order)
#define atomic_store(obj, val, order) __atomic_store_n(obj, val, order)
#define atomic_exchange(obj, val, order) __atomic_exchange_n(obj, val, order)
#define atomic_compare_exchange(obj, expected, desired, success, failure) \
__atomic_compare_exchange_n(obj, expected, desired, false, success, failure)
#define atomic_compare_exchange_weak(obj, expected, desired, success, failure) \
__atomic_compare_exchange_n(obj, expected, desired, true, success, failure)
#define atomic_fetch_add(obj, arg, order) __atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub(obj, arg, order) __atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_and(obj, arg, order) __atomic_fetch_and(obj, arg, order)
#define atomic_fetch_or(obj, arg, order) __atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor(obj, arg, order) __atomic_fetch_xor(obj, arg, order)
#endif
#define atomic_fence(order) __atomic_thread_fence(order)
#define atomic_compiler_fence(order) __atomic_signal_fence(order)
+2
View File
@@ -50,6 +50,8 @@ struct cmdline_option {
// Parses the command line and invokes all options. // Parses the command line and invokes all options.
void cmdline_parse(const char* cmdline); void cmdline_parse(const char* cmdline);
const char* cmdline_get();
void cmdline_parse_buf( void cmdline_parse_buf(
char* buf, char* buf,
size_t len, size_t len,
+1 -1
View File
@@ -1,8 +1,8 @@
#pragma once #pragma once
#include <zinnia/atomic.h>
#include <zinnia/list.h> #include <zinnia/list.h>
#include <zinnia/percpu.h> #include <zinnia/percpu.h>
#include <stdatomic.h>
struct dpc { struct dpc {
void (*callback)(struct dpc* dpc, void* data); void (*callback)(struct dpc* dpc, void* data);
+5 -5
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <zinnia/atomic.h>
#include <zinnia/utils.h> #include <zinnia/utils.h>
#include <stdatomic.h>
#include <stddef.h> #include <stddef.h>
struct refcount { struct refcount {
@@ -9,16 +9,16 @@ struct refcount {
}; };
static inline void refcount_init(struct refcount* rc) { static inline void refcount_init(struct refcount* rc) {
atomic_store_explicit(&rc->count, 1, memory_order_relaxed); atomic_store(&rc->count, 1, ATOMIC_RELAXED);
} }
static inline void refcount_inc(struct refcount* rc) { static inline void refcount_inc(struct refcount* rc) {
atomic_fetch_add_explicit(&rc->count, 1, memory_order_relaxed); atomic_fetch_add(&rc->count, 1, ATOMIC_RELAXED);
} }
static inline bool refcount_dec(struct refcount* rc) { static inline bool refcount_dec(struct refcount* rc) {
if (atomic_fetch_sub_explicit(&rc->count, 1, memory_order_release) != 1) if (atomic_fetch_sub(&rc->count, 1, ATOMIC_RELEASE) != 1)
return false; return false;
atomic_thread_fence(memory_order_acquire); atomic_fence(ATOMIC_ACQUIRE);
return true; return true;
} }
+1 -1
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <zinnia/atomic.h>
#include <zinnia/errno.h> #include <zinnia/errno.h>
#include <zinnia/init.h> #include <zinnia/init.h>
#include <zinnia/initgraph.h> #include <zinnia/initgraph.h>
@@ -7,7 +8,6 @@
#include <zinnia/tailq.h> #include <zinnia/tailq.h>
#include <zinnia/types.h> #include <zinnia/types.h>
#include <bits/sched.h> #include <bits/sched.h>
#include <stdatomic.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
+1 -1
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <zinnia/atomic.h>
#include <zinnia/sched.h> #include <zinnia/sched.h>
#include <zinnia/spin.h> #include <zinnia/spin.h>
#include <zinnia/tailq.h> #include <zinnia/tailq.h>
#include <stdatomic.h>
// A queue of tasks waiting for an event. // A queue of tasks waiting for an event.
struct waitq { struct waitq {