stuff2
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
#include <common/compiler.h>
|
||||
#include <kernel/panic.h>
|
||||
|
||||
#define ASSERT(expr, msg, ...) \
|
||||
// Like the standard C assert, but also active in debug builds.
|
||||
#define assert(expr, msg, ...) \
|
||||
({ \
|
||||
if (__unlikely(!(expr))) { \
|
||||
panic( \
|
||||
@@ -19,7 +20,7 @@
|
||||
})
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define DEBUG_ASSERT(...) ASSERT(__VA_ARGS__)
|
||||
#define debug_assert(...) assert(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_ASSERT(...) ((void)0)
|
||||
#define debug_assert(...) ((void)0)
|
||||
#endif
|
||||
@@ -13,13 +13,13 @@ struct channel_msg {
|
||||
size_t num_bytes;
|
||||
struct namespace_desc* descs;
|
||||
size_t num_handles;
|
||||
TAILQ_LINK(struct channel_msg) next;
|
||||
tailq_link(struct channel_msg) next;
|
||||
};
|
||||
|
||||
struct channel {
|
||||
struct channel* peer;
|
||||
struct spinlock lock;
|
||||
TAILQ_HEAD(struct channel_msg) messages;
|
||||
tailq_head(struct channel_msg) messages;
|
||||
struct wait_queue waiters;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
// Ensure a hash is never zero (zero is the empty sentinel).
|
||||
#define _HASHMAP_FIXHASH(h) ((h) == 0 ? (uint64_t)1 : (h))
|
||||
|
||||
#define HASHMAP(K, V) \
|
||||
#define hashmap(K, V) \
|
||||
struct { \
|
||||
K* keys; \
|
||||
V* values; \
|
||||
@@ -34,7 +34,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
size_t count; \
|
||||
}
|
||||
|
||||
#define HASHMAP_INIT(map) \
|
||||
#define hashmap_init(map) \
|
||||
do { \
|
||||
(map)->keys = nullptr; \
|
||||
(map)->values = nullptr; \
|
||||
@@ -43,7 +43,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
(map)->count = 0; \
|
||||
} while (0)
|
||||
|
||||
#define HASHMAP_DESTROY(map) \
|
||||
#define hashmap_destroy(map) \
|
||||
do { \
|
||||
mem_free((map)->keys); \
|
||||
mem_free((map)->values); \
|
||||
@@ -55,7 +55,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
(map)->count = 0; \
|
||||
} while (0)
|
||||
|
||||
#define HASHMAP_COUNT(map) ((map)->count)
|
||||
#define hashmap_count(map) ((map)->count)
|
||||
|
||||
// Internal: probe distance from ideal position.
|
||||
#define _HASHMAP_PROBE_DIST(hash, pos, cap) (((pos) - ((hash) & ((cap) - 1))) & ((cap) - 1))
|
||||
@@ -116,10 +116,10 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Insert or update a key-value pair. Returns ZN_OK or ZN_ERR_NO_MEMORY.
|
||||
#define HASHMAP_INSERT(map, key, val, hash_fn, eq_fn) \
|
||||
// Insert or update a key-value pair. Returns 0 or ZN_ERR_NO_MEMORY.
|
||||
#define hashmap_insert(map, key, val, hash_fn, eq_fn) \
|
||||
({ \
|
||||
zn_status_t _status = ZN_OK; \
|
||||
zn_status_t _status = 0; \
|
||||
typeof(*(map)->keys) _k = (key); \
|
||||
uint64_t _h = _HASHMAP_FIXHASH((hash_fn)(&_k, sizeof(_k))); \
|
||||
/* Check for existing key first. */ \
|
||||
@@ -147,7 +147,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
_status = ZN_ERR_NO_MEMORY; \
|
||||
} \
|
||||
} \
|
||||
if (_status == ZN_OK) { \
|
||||
if (_status == 0) { \
|
||||
_HASHMAP_INSERT_INNER(map, _k, (val), _h); \
|
||||
} \
|
||||
} \
|
||||
@@ -155,7 +155,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
})
|
||||
|
||||
// Look up a key. Returns a pointer to the value, or nullptr if not found.
|
||||
#define HASHMAP_GET(map, key, hash_fn, eq_fn) \
|
||||
#define hashmap_get(map, key, hash_fn, eq_fn) \
|
||||
({ \
|
||||
typeof(*(map)->values)* _result = nullptr; \
|
||||
if ((map)->capacity > 0) { \
|
||||
@@ -180,7 +180,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
|
||||
// Remove a key. Returns true if the key was found and removed.
|
||||
// Uses backward-shift deletion to avoid tombstones.
|
||||
#define HASHMAP_REMOVE(map, key, hash_fn, eq_fn) \
|
||||
#define hashmap_remove(map, key, hash_fn, eq_fn) \
|
||||
({ \
|
||||
bool _removed = false; \
|
||||
if ((map)->capacity > 0) { \
|
||||
@@ -218,6 +218,6 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
|
||||
|
||||
// Iterate over all occupied entries. `idx` is a size_t loop variable.
|
||||
// Access keys and values via (map)->keys[idx] and (map)->values[idx].
|
||||
#define HASHMAP_FOREACH(map, idx) \
|
||||
#define hashmap_foreach(map, idx) \
|
||||
for (size_t idx = 0; idx < (map)->capacity; idx++) \
|
||||
if ((map)->hashes[idx] != 0)
|
||||
|
||||
@@ -22,7 +22,7 @@ enum irq_trigger_mode : uint8_t {
|
||||
|
||||
struct irq_handler {
|
||||
enum irq_status (*handler)(void* self);
|
||||
SLIST_LINK(struct irq_handler*) next;
|
||||
list_link(struct irq_handler*) next;
|
||||
};
|
||||
|
||||
struct irq_line {
|
||||
@@ -31,7 +31,7 @@ struct irq_line {
|
||||
void (*unmask)(struct irq_line* self);
|
||||
void (*eoi)(struct irq_line* self);
|
||||
|
||||
SLIST_HEAD(struct irq_handler*) handlers;
|
||||
list_head(struct irq_handler*) handlers;
|
||||
bool is_busy;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#define SLIST_HEAD(type) \
|
||||
#define list_head(type) \
|
||||
struct { \
|
||||
type sl_head; \
|
||||
type _sl_head; \
|
||||
}
|
||||
|
||||
#define SLIST_LINK(type) \
|
||||
#define list_link(type) \
|
||||
struct { \
|
||||
type sl_link; \
|
||||
type _sl_link; \
|
||||
}
|
||||
|
||||
#define SLIST_EMPTY(head) ((head)->sl_head == NULL)
|
||||
#define SLIST_FIRST(head) ((head)->sl_head)
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sl_link)
|
||||
#define list_is_empty(head) ((head)->_sl_head == NULL)
|
||||
#define list_first(head) ((head)->_sl_head)
|
||||
#define list_next(elm, field) ((elm)->field._sl_link)
|
||||
|
||||
#define SLIST_INSERT_END(slistelm, elm, field) \
|
||||
#define list_insert_end(slistelm, elm, field) \
|
||||
do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
list_next((elm), field) = list_next((slistelm), field); \
|
||||
list_next((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) \
|
||||
#define list_insert_head(head, elm, field) \
|
||||
do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
list_next((elm), field) = list_first((head)); \
|
||||
list_first((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) for ((var) = SLIST_FIRST((head)); (var); (var) = SLIST_NEXT((var), field))
|
||||
#define list_foreach(var, head, field) for ((var) = list_first((head)); (var); (var) = list_next((var), field))
|
||||
|
||||
@@ -32,7 +32,7 @@ struct namespace_desc {
|
||||
struct namespace {
|
||||
zn_handle_t next_handle;
|
||||
struct mutex mutex;
|
||||
HASHMAP(zn_handle_t, struct namespace_desc) descriptors;
|
||||
hashmap(zn_handle_t, struct namespace_desc) descriptors;
|
||||
};
|
||||
|
||||
// Creates a new namespace with no contents.
|
||||
|
||||
@@ -38,7 +38,7 @@ struct task {
|
||||
size_t time_slice;
|
||||
int8_t priority;
|
||||
|
||||
TAILQ_LINK(struct task) next;
|
||||
tailq_link(struct task) next;
|
||||
};
|
||||
|
||||
// Per-CPU data for scheduling.
|
||||
@@ -46,7 +46,7 @@ struct sched_percpu {
|
||||
struct task* current;
|
||||
struct task* idle_task;
|
||||
size_t preempt_level;
|
||||
TAILQ_HEAD(struct task) run_queue;
|
||||
tailq_head(struct task) run_queue;
|
||||
};
|
||||
|
||||
// Blocks the current task on the given wait queue.
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Busy-waits in a loop until the lock is freed.
|
||||
// Does not put the CPU to sleep.
|
||||
struct spinlock {
|
||||
bool locked;
|
||||
uint32_t owner;
|
||||
uint32_t next;
|
||||
};
|
||||
|
||||
// Attempts to lock a spinlock. If it's already locked, waits until it's freed.
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#define TAILQ_HEAD(type) \
|
||||
#define tailq_head(type) \
|
||||
struct { \
|
||||
type* tqh_first; \
|
||||
type** tqh_last; \
|
||||
}
|
||||
|
||||
#define TAILQ_LINK(type) \
|
||||
#define tailq_link(type) \
|
||||
struct { \
|
||||
type* tqe_next; \
|
||||
type** tqe_prev; \
|
||||
}
|
||||
|
||||
#define TAILQ_INIT(head) \
|
||||
#define tailq_init(head) \
|
||||
do { \
|
||||
(head)->tqh_first = nullptr; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define tailq_first(head) ((head)->tqh_first)
|
||||
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define tailq_next(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_EMPTY(head) (TAILQ_FIRST(head) == nullptr)
|
||||
#define tailq_empty(head) (tailq_first(head) == nullptr)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
#define tailq_insert_tail(head, elm, field) \
|
||||
do { \
|
||||
(elm)->field.tqe_next = nullptr; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
@@ -32,7 +32,7 @@
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
#define tailq_insert_head(head, elm, field) \
|
||||
do { \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != nullptr) \
|
||||
(head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
@@ -42,7 +42,7 @@
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) \
|
||||
#define tailq_remove(head, elm, field) \
|
||||
do { \
|
||||
if (((elm)->field.tqe_next) != nullptr) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||
|
||||
+25
-26
@@ -1,25 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <zinnia/status.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h> // IWYU pragma: keep
|
||||
#include <string.h> // IWYU pragma: keep
|
||||
|
||||
#define VEC(T) \
|
||||
#define vec(T) \
|
||||
struct { \
|
||||
T* data; \
|
||||
size_t length; \
|
||||
size_t capacity; \
|
||||
}
|
||||
|
||||
#define VEC_INIT(vec) \
|
||||
#define vec_init(vec) \
|
||||
do { \
|
||||
(vec)->data = nullptr; \
|
||||
(vec)->length = 0; \
|
||||
(vec)->capacity = 0; \
|
||||
} while (0)
|
||||
|
||||
#define VEC_DESTROY(vec) \
|
||||
#define vec_destroy(vec) \
|
||||
do { \
|
||||
mem_free((vec)->data); \
|
||||
(vec)->data = nullptr; \
|
||||
@@ -27,13 +26,13 @@
|
||||
(vec)->capacity = 0; \
|
||||
} while (0)
|
||||
|
||||
#define VEC_LENGTH(vec) ((vec)->length)
|
||||
#define VEC_CAPACITY(vec) ((vec)->capacity)
|
||||
#define VEC_EMPTY(vec) ((vec)->length == 0)
|
||||
#define VEC_AT(vec, i) ((vec)->data[i])
|
||||
#define vec_length(vec) ((vec)->length)
|
||||
#define vec_capacity(vec) ((vec)->capacity)
|
||||
#define vec_empty(vec) ((vec)->length == 0)
|
||||
#define vec_at(vec, i) ((vec)->data[i])
|
||||
|
||||
// Internal: grow to at least `needed` capacity.
|
||||
#define _VEC_GROW(vec, needed) \
|
||||
#define _vec_grow(vec, needed) \
|
||||
do { \
|
||||
size_t _new_cap = (vec)->capacity == 0 ? 8 : (vec)->capacity; \
|
||||
while (_new_cap < (needed)) \
|
||||
@@ -46,34 +45,34 @@
|
||||
(vec)->capacity = _new_cap; \
|
||||
} while (0)
|
||||
|
||||
// Append an element. Returns ZN_OK or ZN_ERR_NO_MEMORY.
|
||||
#define VEC_PUSH(vec, val) \
|
||||
// Append an element. Returns 0 or ZN_ERR_NO_MEMORY.
|
||||
#define vec_push(vec, val) \
|
||||
({ \
|
||||
zn_status_t _status = ZN_OK; \
|
||||
zn_status_t _status = 0; \
|
||||
if ((vec)->length >= (vec)->capacity) { \
|
||||
_VEC_GROW(vec, (vec)->length + 1); \
|
||||
_vec_grow(vec, (vec)->length + 1); \
|
||||
if ((vec)->data == nullptr) \
|
||||
_status = ZN_ERR_NO_MEMORY; \
|
||||
} \
|
||||
if (_status == ZN_OK) \
|
||||
if (_status == 0) \
|
||||
(vec)->data[(vec)->length++] = (val); \
|
||||
_status; \
|
||||
})
|
||||
|
||||
// Remove and return the last element. Undefined if empty.
|
||||
#define VEC_POP(vec) ((vec)->data[--(vec)->length])
|
||||
#define vec_pop(vec) ((vec)->data[--(vec)->length])
|
||||
|
||||
// Insert at index, shifting subsequent elements right. Returns ZN_OK or ZN_ERR_NO_MEMORY.
|
||||
#define VEC_INSERT(vec, i, val) \
|
||||
// Insert at index, shifting subsequent elements right. Returns 0 or ZN_ERR_NO_MEMORY.
|
||||
#define vec_insert(vec, i, val) \
|
||||
({ \
|
||||
zn_status_t _status = ZN_OK; \
|
||||
zn_status_t _status = 0; \
|
||||
size_t _idx = (i); \
|
||||
if ((vec)->length >= (vec)->capacity) { \
|
||||
_VEC_GROW(vec, (vec)->length + 1); \
|
||||
_vec_grow(vec, (vec)->length + 1); \
|
||||
if ((vec)->data == nullptr) \
|
||||
_status = ZN_ERR_NO_MEMORY; \
|
||||
} \
|
||||
if (_status == ZN_OK) { \
|
||||
if (_status == 0) { \
|
||||
memmove(&(vec)->data[_idx + 1], &(vec)->data[_idx], ((vec)->length - _idx) * sizeof(*(vec)->data)); \
|
||||
(vec)->data[_idx] = (val); \
|
||||
(vec)->length++; \
|
||||
@@ -82,7 +81,7 @@
|
||||
})
|
||||
|
||||
// Remove element at index, shifting subsequent elements left.
|
||||
#define VEC_REMOVE(vec, i) \
|
||||
#define vec_remove(vec, i) \
|
||||
do { \
|
||||
size_t _idx = (i); \
|
||||
(vec)->length--; \
|
||||
@@ -91,7 +90,7 @@
|
||||
} while (0)
|
||||
|
||||
// Remove element at index by swapping with the last element (O(1), unordered).
|
||||
#define VEC_SWAP_REMOVE(vec, i) \
|
||||
#define vec_swap_remove(vec, i) \
|
||||
do { \
|
||||
size_t _idx = (i); \
|
||||
(vec)->length--; \
|
||||
@@ -100,6 +99,6 @@
|
||||
} while (0)
|
||||
|
||||
// Clear all elements without freeing memory.
|
||||
#define VEC_CLEAR(vec) ((vec)->length = 0)
|
||||
#define vec_clear(vec) ((vec)->length = 0)
|
||||
|
||||
#define VEC_FOREACH(vec, idx) for (size_t idx = 0; idx < (vec)->length; idx++)
|
||||
#define vec_foreach(vec, idx) for (size_t idx = 0; idx < (vec)->length; idx++)
|
||||
|
||||
@@ -30,13 +30,13 @@ struct pager_ops {
|
||||
struct page_list {
|
||||
uintptr_t offset;
|
||||
struct page* value;
|
||||
SLIST_LINK(struct page_list*) next;
|
||||
list_link(struct page_list*) next;
|
||||
};
|
||||
|
||||
struct paged_vmo {
|
||||
struct vmo object;
|
||||
struct pager_ops source;
|
||||
SLIST_HEAD(struct page_list*) cache;
|
||||
list_head(struct page_list*) cache;
|
||||
struct spinlock lock;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ struct task;
|
||||
|
||||
// A queue of tasks waiting for an event.
|
||||
struct wait_queue {
|
||||
TAILQ_HEAD(struct task) waiters;
|
||||
tailq_head(struct task) waiters;
|
||||
struct spinlock lock;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#ifndef ZINNIA_STDARG_H
|
||||
#define ZINNIA_STDARG_H
|
||||
#pragma once
|
||||
|
||||
typedef __builtin_va_list va_list;
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, T) __builtin_va_arg(v, T)
|
||||
#define va_copy(d, s) __builtin_va_copy(d, s)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef ZINNIA_STDATOMIC_H
|
||||
#define ZINNIA_STDATOMIC_H
|
||||
#pragma once
|
||||
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
@@ -35,5 +34,3 @@ typedef enum memory_order {
|
||||
#define atomic_fetch_and(ptr, op) atomic_fetch_and_explicit(ptr, op, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_thread_fence(ord) __atomic_thread_fence(ord)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#ifndef ZINNIA_STDDEF_H
|
||||
#define ZINNIA_STDDEF_H
|
||||
#pragma once
|
||||
|
||||
typedef unsigned long size_t;
|
||||
typedef signed long ssize_t;
|
||||
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
|
||||
#endif
|
||||
#define unreachable() __builtin_unreachable()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef ZINNIA_STDINT_H
|
||||
#define ZINNIA_STDINT_H
|
||||
#pragma once
|
||||
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
@@ -25,5 +24,3 @@ typedef __INTPTR_TYPE__ intptr_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
#define INTPTR_MAX __INTPTR_MAX__
|
||||
#define UINTPTR_MAX __UINTPTR_MAX__
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#ifndef ZINNIA_STDLIB_H
|
||||
#define ZINNIA_STDLIB_H
|
||||
#pragma once
|
||||
|
||||
long atol(const char* str, int base);
|
||||
unsigned long atolu(const char* str, int base);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef ZINNIA_STRING_H
|
||||
#define ZINNIA_STRING_H
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -13,5 +12,3 @@ char* strncpy(char* restrict dst, const char* restrict src, size_t len);
|
||||
int strcmp(const char* str1, const char* str2);
|
||||
int strncmp(const char* str1, const char* str2, size_t len);
|
||||
char* strchr(const char* c, int s);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user