This commit is contained in:
Nils O. Selåsdal
2025-07-16 00:10:44 +02:00
39 changed files with 773 additions and 91 deletions
+11 -13
View File
@@ -18,22 +18,21 @@ static inline int bit_index(int b)
}
static inline int bit_offset(int b)
{
{
return b % (sizeof(uc_bv_integer) * CHAR_BIT);
}
struct UCBitVec *uc_bv_new(size_t nbits)
{
struct UCBitVec *v = malloc(sizeof *v);
size_t vec_len = UC_BV_LEN(nbits);
struct UCBitVec *v;
void *mem = malloc(sizeof *v + vec_len * sizeof(uc_bv_integer));
v = mem;
if (v == NULL)
return NULL;
v->vec_len = UC_BV_LEN(nbits);
v->vec = malloc(v->vec_len * sizeof(uc_bv_integer));
if (v->vec == NULL) {
free(v);
return NULL;
}
v->vec_len = vec_len;
v->vec = mem + sizeof *v;
uc_bv_clr_all(v);
@@ -43,24 +42,23 @@ struct UCBitVec *uc_bv_new(size_t nbits)
void uc_bv_free(struct UCBitVec *v)
{
if (v) {
free(v->vec);
free(v);
}
}
void uc_bv_clr_bit(struct UCBitVec *v,int b)
{
{
v->vec[bit_index(b)] &= ~(1UL << (bit_offset(b)));
}
int uc_bv_get_bit(const struct UCBitVec *v,int b)
{
{
return !!(v->vec[bit_index(b)] & (1UL << bit_offset(b)));
}
void uc_bv_set_bit(struct UCBitVec *v,int b)
{
v->vec[bit_index(b)] |= 1UL << (bit_offset(b));
{
v->vec[bit_index(b)] |= 1UL << (bit_offset(b));
}
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len)
+5
View File
@@ -7,6 +7,11 @@
#include <sys/types.h>
#include "ucore/fd_utils.h"
/* bsd variants use TCP_KEEPALIVE */
#if defined(TCP_KEEPALIVE) && !defined(TCP_KEEPIDLE)
#define TCP_KEEPIDLE TCP_KEEPALIVE
#endif
int uc_set_nonblocking(int fd)
{
int flags = fcntl(fd,F_GETFL,NULL);
+23 -13
View File
@@ -1,12 +1,13 @@
#ifdef __linux__
#include <sys/epoll.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "iomux_impl.h"
//epoll (linux specific) IO mux.
//epoll (linux specific) IO mux.
//We stuff the struct IOMuxFD pointer in the event.data.ptr slot
//for the kernel to keep track of, so we don't have to.
///we do not use edge triggered mode
@@ -29,10 +30,10 @@ static inline uint32_t mux_2_epoll_events(unsigned int events)
{
uint32_t epoll_events = 0;
if (events & MUX_EV_READ)
if (events & MUX_EV_READ)
epoll_events |= EPOLLIN;
if (events & MUX_EV_WRITE)
if (events & MUX_EV_WRITE)
epoll_events |= EPOLLOUT;
return epoll_events;
@@ -47,7 +48,7 @@ static inline unsigned int epoll_2_mux_events(uint32_t events)
if (events & (EPOLLIN | EPOLLHUP | EPOLLERR))
mux_events |= MUX_EV_READ;
if (events & EPOLLOUT)
if (events & EPOLLOUT)
mux_events |= MUX_EV_WRITE;
return mux_events;
@@ -58,10 +59,10 @@ static int iomux_epoll_update_events(struct IOMux *mux_, struct IOMuxFD *fd)
struct IOMuxEpoll *mux = mux_->instance;
struct epoll_event e_event = {0, {0}};
int rc;
e_event.events = mux_2_epoll_events(fd->what);
e_event.data.ptr = fd;
rc = epoll_ctl(mux->epoll_fd, EPOLL_CTL_MOD, fd->fd, &e_event);
assert(rc == 0);
if (rc != 0)
@@ -117,7 +118,7 @@ static int iomux_epoll_unregister_fd(struct IOMux *mux_, struct IOMuxFD *fd)
break;
}
}
mux->num_descriptors--;
return rc;
@@ -145,10 +146,10 @@ static int iomux_epoll_run(struct IOMux *mux_, struct timeval *timeout)
//epoll takes the timeout in miliseconds
if (timeout)
timeout_ms = timeval_to_ms(timeout);
else
else
timeout_ms = -1;
do {
do {
rc = epoll_wait(mux->epoll_fd, mux->pending_events, EPOLL_WAIT_EVENTS, timeout_ms);
@@ -173,14 +174,14 @@ static int iomux_epoll_run(struct IOMux *mux_, struct timeval *timeout)
//we want to deliver only one event at a time to simplify
//application programming.
if (events & MUX_EV_READ && fd != NULL) {
if (events & MUX_EV_READ && fd != NULL) {
assert(fd->callback != NULL);
fd->callback(mux_, fd, MUX_EV_READ);
}
//now re-check, in case the IOMuxFD was removed
fd = mux->pending_events[i].data.ptr;
if (events & MUX_EV_WRITE && fd != NULL) {
if (events & MUX_EV_WRITE && fd != NULL) {
assert(fd->callback != NULL);
fd->callback(mux_, fd, MUX_EV_WRITE);
}
@@ -211,7 +212,7 @@ static const struct IOMuxOps epoll_ops = {
.unregister_fd_impl = iomux_epoll_unregister_fd,
.update_events_impl = iomux_epoll_update_events,
};
int iomux_epoll_init(struct IOMux *mux)
{
struct IOMuxEpoll *mux_epoll = calloc(1, sizeof *mux_epoll);
@@ -230,3 +231,12 @@ int iomux_epoll_init(struct IOMux *mux)
return 0;
}
#else
#include <errno.h>
#include "iomux_impl.h"
int iomux_epoll_init(struct IOMux *mux)
{
return ENOSYS;
}
#endif
+7 -7
View File
@@ -54,8 +54,8 @@ void iomux_delete(struct IOMux *mux)
}
//convert the difference between future and now
static inline void future_to_interval(const struct timeval *future,
const struct timeval *now,
static inline void future_to_interval(const struct timeval *future,
const struct timeval *now,
struct timeval *result)
{
if (timercmp(future, now, >)) {
@@ -66,7 +66,7 @@ static inline void future_to_interval(const struct timeval *future,
}
}
static int iomux_run_timers(struct IOMux *mux, struct timeval *timeout)
static int iomux_next_timer_timeout(struct IOMux *mux, struct timeval *timeout)
{
struct timeval first_timer;
@@ -78,12 +78,12 @@ static int iomux_run_timers(struct IOMux *mux, struct timeval *timeout)
first_timer.tv_sec, first_timer.tv_usec,
timeout->tv_sec, timeout->tv_usec);
*/
assert(timeout->tv_sec >= 0);
assert(timeout->tv_usec >= 0);
return 1;
}
}
return 0;
}
@@ -95,7 +95,7 @@ int iomux_run(struct IOMux *mux)
struct timeval timeout;
struct timeval *timeoutp;
if (iomux_run_timers(mux, &timeout)) {
if (iomux_next_timer_timeout(mux, &timeout)) {
timeoutp = &timeout;
} else {
timeoutp = NULL;
@@ -147,7 +147,7 @@ int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd, unsigned int what
assert(fd != NULL);
assert(fd->callback != NULL);
assert(fd->fd >= 0);
if (fd->what != what) {
fd->what = what;
rc = mux->ops.update_events_impl(mux, fd);
+93
View File
@@ -0,0 +1,93 @@
#ifdef __linux
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "ucore/ringbuf.h"
int uc_ringbuf_init(UCRingBuf *rb, uint32_t sz)
{
uint32_t pagesz = getpagesize();
// Round up to page size
sz = ((sz + pagesz - 1) / pagesz) * pagesz;
/* Reserve contiguous address space*/
void *base = mmap(NULL, sz * 2, PROT_NONE, MAP_POPULATE|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (base == NULL) {
return -errno;
}
/* MAP_PRIVATE doesn't work */
base = mmap(base, sz * 1, PROT_READ|PROT_WRITE, MAP_POPULATE|MAP_ANONYMOUS|MAP_FIXED|MAP_SHARED, -1, 0);
if (base == MAP_FAILED) {
return -errno;
}
void *mbase = mremap(base, sz * 1, sz, MREMAP_FIXED|MREMAP_MAYMOVE|MREMAP_DONTUNMAP, base + sz);
if (mbase == MAP_FAILED) {
munmap(base, sz);
return -errno;
}
rb->base = base;
rb->sz = sz;
rb->read_idx = 0;
rb->write_idx = 0;
return 0;
}
int uc_ringbuf_destroy(UCRingBuf *rb)
{
int rc = munmap(rb->base, rb->sz);
if (rc != 0) {
return -errno;
}
rc = munmap(rb->base + rb->sz, rb->sz);
if (rc != 0) {
return -errno;
}
rb->base = NULL;
return 0;
}
uint32_t uc_ringbuf_available(const UCRingBuf *rb)
{
return rb->sz - rb->write_idx + rb->read_idx;
}
int uc_ringbuf_write(UCRingBuf *rb, const void *restrict data, uint32_t len)
{
if (rb->write_idx - rb->read_idx + len > rb->sz) {
return -ENOMEM;
}
memcpy(&rb->base[rb->write_idx], data, len);
rb->write_idx += len;
return 0;
}
int uc_ringbuf_read(UCRingBuf *rb, void *restrict data, uint32_t len)
{
if (uc_ringbuf_len(rb) < len) {
return -ENOMEM;
}
memcpy(data, &rb->base[rb->read_idx], len);
rb->read_idx += len;
if (rb->read_idx == rb->write_idx) {
rb->read_idx = rb->write_idx = 0;
} else if (rb->read_idx > rb->sz) {
rb->read_idx -= rb->sz;
rb->write_idx -= rb->sz;
}
return 0;
}
#endif
+39 -35
View File
@@ -21,27 +21,32 @@ struct Chunk {
struct SAlloc {
size_t chunksz; //data size of each chunk
Chunk *first; //head of the chunk list
Chunk *current;
Chunk *current;
};
static Chunk *
add_chunk(SAlloc *p)
static inline Chunk *
alloc_chunk(size_t sz)
{
Chunk *newchunk;
newchunk = malloc(sizeof *newchunk + p->chunksz - (sizeof *newchunk - offsetof(Chunk, data.data)));
if (newchunk == NULL)
return NULL;
if (p->current != NULL)
p->current->next = newchunk;
newchunk->next = NULL;
newchunk->firstfree = 0;
newchunk = malloc(sizeof *newchunk + sz - (sizeof *newchunk - offsetof(Chunk, data.data)));
return newchunk;
}
static Chunk *
add_chunk(SAlloc *p, Chunk *c)
{
if (c == NULL)
return c;
p->current->next = c;
c->next = NULL;
c->firstfree = 0;
return c;
}
static Chunk *
next_chunk(SAlloc *p)
{
@@ -50,8 +55,10 @@ next_chunk(SAlloc *p)
if (p->current->next) {
newchunk = p->current->next;
newchunk->firstfree = 0;
} else
newchunk = add_chunk(p);
} else {
Chunk *c = alloc_chunk(p->chunksz);
newchunk = add_chunk(p, c);
}
if (newchunk)
p->current = newchunk;
@@ -63,19 +70,16 @@ SAlloc *
uc_new_salloc(size_t chunksz)
{
SAlloc *p;
Chunk *first;
p = malloc(sizeof *p);
if (p == NULL)
return NULL;
p->chunksz = chunksz;
p->current = NULL;
if ((first = add_chunk(p)) == NULL) {
free(p);
Chunk *first;
first = alloc_chunk(sizeof *p + chunksz);
if (first == NULL) {
return NULL;
}
first->next = NULL;
first->firstfree = sizeof *p;
p = (SAlloc *)&first->data.data[0];
p->chunksz = chunksz;
p->first = p->current = first;
return p;
@@ -86,7 +90,9 @@ uc_reset_salloc(SAlloc *p)
{
Chunk *tmp;
for(tmp = p->first; tmp; tmp = tmp->next)
tmp = p->first;
tmp->firstfree = sizeof *p;
for(tmp = tmp->next; tmp; tmp = tmp->next)
tmp->firstfree = 0;
p->current = p->first;
@@ -97,9 +103,9 @@ uc_s_alloc(SAlloc *p,size_t sz)
{
Chunk *chunk;
void *newmem;
chunk = p->current;
if (chunk->firstfree + sz > p->chunksz) {
if (chunk->firstfree + sz > p->chunksz) {
if (sz > p->chunksz)
return NULL;
@@ -107,7 +113,7 @@ uc_s_alloc(SAlloc *p,size_t sz)
if (chunk == NULL)
return NULL;
}
newmem = &chunk->data.data[chunk->firstfree];
chunk->firstfree += sz;
@@ -119,17 +125,17 @@ uc_s_allocz(SAlloc *p,size_t sz)
{
void *newmem = uc_s_alloc(p, sz);
if (newmem != NULL)
if (newmem != NULL)
memset(newmem, 0, sz);
return newmem;
}
static void
static void
free_chunks(Chunk *chunk)
{
Chunk *next;
for (next = NULL; chunk != NULL; chunk = next) {
next = chunk->next;
free(chunk);
@@ -140,7 +146,5 @@ void
uc_free_salloc(SAlloc *p)
{
free_chunks(p->first);
free(p);
}