Merge branch 'master' of https://sdal.tech/gitea/noselasd/libucore into cmake
This commit is contained in:
+11
-13
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user