From e40a203a1d29d3c8662a644890c87588a2258d24 Mon Sep 17 00:00:00 2001 From: John Sully Date: Sun, 10 Feb 2019 20:24:11 -0500 Subject: [PATCH] move ae to C++ Former-commit-id: eb9070c8333ebe7d6e0d622f90e904c1b17e9710 --- src/Makefile | 6 +++--- src/{ae.c => ae.cpp} | 32 +++++++++++++++++--------------- src/ae.h | 11 ++++++++++- src/{ae_epoll.c => ae_epoll.cpp} | 18 +++++++++--------- src/fastlock.cpp | 21 +++++++++++++++++++++ src/fastlock.h | 19 +++++++++++++++++++ 6 files changed, 79 insertions(+), 28 deletions(-) rename src/{ae.c => ae.cpp} (93%) rename src/{ae_epoll.c => ae_epoll.cpp} (87%) create mode 100644 src/fastlock.cpp create mode 100644 src/fastlock.h diff --git a/src/Makefile b/src/Makefile index 8997fa81b..b2b5f5833 100644 --- a/src/Makefile +++ b/src/Makefile @@ -174,11 +174,11 @@ endif REDIS_SERVER_NAME=keydb-server REDIS_SENTINEL_NAME=keydb-sentinel -REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o storage.o rdb-s3.o +REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o storage.o rdb-s3.o fastlock.o REDIS_CLI_NAME=keydb-cli -REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage-lite.o +REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage-lite.o fastlock.o REDIS_BENCHMARK_NAME=keydb-benchmark -REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o storage-lite.o +REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o storage-lite.o fastlock.o REDIS_CHECK_RDB_NAME=keydb-check-rdb REDIS_CHECK_AOF_NAME=keydb-check-aof diff --git a/src/ae.c b/src/ae.cpp similarity index 93% rename from src/ae.c rename to src/ae.cpp index 80f1d8111..17408e316 100644 --- a/src/ae.c +++ b/src/ae.cpp @@ -41,8 +41,10 @@ #include #include "ae.h" +extern "C" { #include "zmalloc.h" #include "config.h" +} /* Include the best multiplexing layer supported by this system. * The following should be ordered by performances, descending. */ @@ -50,7 +52,7 @@ #include "ae_evport.c" #else #ifdef HAVE_EPOLL - #include "ae_epoll.c" + #include "ae_epoll.cpp" #else #ifdef HAVE_KQUEUE #include "ae_kqueue.c" @@ -64,9 +66,9 @@ aeEventLoop *aeCreateEventLoop(int setsize) { aeEventLoop *eventLoop; int i; - if ((eventLoop = zmalloc(sizeof(*eventLoop), MALLOC_LOCAL)) == NULL) goto err; - eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize, MALLOC_LOCAL); - eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize, MALLOC_LOCAL); + if ((eventLoop = (aeEventLoop*)zmalloc(sizeof(*eventLoop), MALLOC_LOCAL)) == NULL) goto err; + eventLoop->events = (aeFileEvent*)zmalloc(sizeof(aeFileEvent)*setsize, MALLOC_LOCAL); + eventLoop->fired = (aeFiredEvent*)zmalloc(sizeof(aeFiredEvent)*setsize, MALLOC_LOCAL); if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err; eventLoop->setsize = setsize; eventLoop->lastTime = time(NULL); @@ -111,8 +113,8 @@ int aeResizeSetSize(aeEventLoop *eventLoop, int setsize) { if (eventLoop->maxfd >= setsize) return AE_ERR; if (aeApiResize(eventLoop,setsize) == -1) return AE_ERR; - eventLoop->events = zrealloc(eventLoop->events,sizeof(aeFileEvent)*setsize, MALLOC_LOCAL); - eventLoop->fired = zrealloc(eventLoop->fired,sizeof(aeFiredEvent)*setsize, MALLOC_LOCAL); + eventLoop->events = (aeFileEvent*)zrealloc(eventLoop->events,sizeof(aeFileEvent)*setsize, MALLOC_LOCAL); + eventLoop->fired = (aeFiredEvent*)zrealloc(eventLoop->fired,sizeof(aeFiredEvent)*setsize, MALLOC_LOCAL); eventLoop->setsize = setsize; /* Make sure that if we created new slots, they are initialized with @@ -122,18 +124,18 @@ int aeResizeSetSize(aeEventLoop *eventLoop, int setsize) { return AE_OK; } -void aeDeleteEventLoop(aeEventLoop *eventLoop) { +extern "C" void aeDeleteEventLoop(aeEventLoop *eventLoop) { aeApiFree(eventLoop); zfree(eventLoop->events); zfree(eventLoop->fired); zfree(eventLoop); } -void aeStop(aeEventLoop *eventLoop) { +extern "C" void aeStop(aeEventLoop *eventLoop) { eventLoop->stop = 1; } -int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, +extern "C" int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) { if (fd >= eventLoop->setsize) { @@ -153,7 +155,7 @@ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, return AE_OK; } -void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) +extern "C" void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { if (fd >= eventLoop->setsize) return; aeFileEvent *fe = &eventLoop->events[fd]; @@ -175,7 +177,7 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) } } -int aeGetFileEvents(aeEventLoop *eventLoop, int fd) { +extern "C" int aeGetFileEvents(aeEventLoop *eventLoop, int fd) { if (fd >= eventLoop->setsize) return 0; aeFileEvent *fe = &eventLoop->events[fd]; @@ -205,14 +207,14 @@ static void aeAddMillisecondsToNow(long long milliseconds, long *sec, long *ms) *ms = when_ms; } -long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, +extern "C" long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc) { long long id = eventLoop->timeEventNextId++; aeTimeEvent *te; - te = zmalloc(sizeof(*te), MALLOC_LOCAL); + te = (aeTimeEvent*)zmalloc(sizeof(*te), MALLOC_LOCAL); if (te == NULL) return AE_ERR; te->id = id; aeAddMillisecondsToNow(milliseconds,&te->when_sec,&te->when_ms); @@ -227,7 +229,7 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, return id; } -int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) +extern "C" int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) { aeTimeEvent *te = eventLoop->timeEventHead; while(te) { @@ -502,7 +504,7 @@ void aeMain(aeEventLoop *eventLoop) { } } -char *aeGetApiName(void) { +const char *aeGetApiName(void) { return aeApiName(); } diff --git a/src/ae.h b/src/ae.h index 184fe3d1b..a6ee1d05b 100644 --- a/src/ae.h +++ b/src/ae.h @@ -35,6 +35,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + #define AE_OK 0 #define AE_ERR -1 @@ -46,6 +50,7 @@ loop iteration. Useful when you want to persist things to disk before sending replies, and want to do that in a group fashion. */ +#define AE_THREADSAFE 8 /* Ok to run concurrently */ #define AE_FILE_EVENTS 1 #define AE_TIME_EVENTS 2 @@ -123,10 +128,14 @@ int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id); int aeProcessEvents(aeEventLoop *eventLoop, int flags); int aeWait(int fd, int mask, long long milliseconds); void aeMain(aeEventLoop *eventLoop); -char *aeGetApiName(void); +const char *aeGetApiName(void); void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep); void aeSetAfterSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *aftersleep); int aeGetSetSize(aeEventLoop *eventLoop); int aeResizeSetSize(aeEventLoop *eventLoop, int setsize); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/ae_epoll.c b/src/ae_epoll.cpp similarity index 87% rename from src/ae_epoll.c rename to src/ae_epoll.cpp index d299c8c1b..cadcc3f51 100644 --- a/src/ae_epoll.c +++ b/src/ae_epoll.cpp @@ -37,10 +37,10 @@ typedef struct aeApiState { } aeApiState; static int aeApiCreate(aeEventLoop *eventLoop) { - aeApiState *state = zmalloc(sizeof(aeApiState), MALLOC_LOCAL); + aeApiState *state = (aeApiState*)zmalloc(sizeof(aeApiState), MALLOC_LOCAL); if (!state) return -1; - state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize, MALLOC_LOCAL); + state->events = (epoll_event*)zmalloc(sizeof(struct epoll_event)*eventLoop->setsize, MALLOC_LOCAL); if (!state->events) { zfree(state); return -1; @@ -56,14 +56,14 @@ static int aeApiCreate(aeEventLoop *eventLoop) { } static int aeApiResize(aeEventLoop *eventLoop, int setsize) { - aeApiState *state = eventLoop->apidata; + aeApiState *state = (aeApiState*)eventLoop->apidata; - state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize, MALLOC_LOCAL); + state->events = (epoll_event*)zrealloc(state->events, sizeof(struct epoll_event)*setsize, MALLOC_LOCAL); return 0; } static void aeApiFree(aeEventLoop *eventLoop) { - aeApiState *state = eventLoop->apidata; + aeApiState *state = (aeApiState*)eventLoop->apidata; close(state->epfd); zfree(state->events); @@ -71,7 +71,7 @@ static void aeApiFree(aeEventLoop *eventLoop) { } static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { - aeApiState *state = eventLoop->apidata; + aeApiState *state = (aeApiState*)eventLoop->apidata; struct epoll_event ee = {0}; /* avoid valgrind warning */ /* If the fd was already monitored for some event, we need a MOD * operation. Otherwise we need an ADD operation. */ @@ -88,7 +88,7 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { } static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { - aeApiState *state = eventLoop->apidata; + aeApiState *state = (aeApiState*)eventLoop->apidata; struct epoll_event ee = {0}; /* avoid valgrind warning */ int mask = eventLoop->events[fd].mask & (~delmask); @@ -106,7 +106,7 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { } static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { - aeApiState *state = eventLoop->apidata; + aeApiState *state = (aeApiState*)eventLoop->apidata; int retval, numevents = 0; retval = epoll_wait(state->epfd,state->events,eventLoop->setsize, @@ -130,6 +130,6 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { return numevents; } -static char *aeApiName(void) { +static const char *aeApiName(void) { return "epoll"; } diff --git a/src/fastlock.cpp b/src/fastlock.cpp new file mode 100644 index 000000000..6e8f8a286 --- /dev/null +++ b/src/fastlock.cpp @@ -0,0 +1,21 @@ +#include "fastlock.h" + +extern "C" void fastlock_init(struct fastlock *lock) +{ + lock->lock = 0; +} + +extern "C" void fastlock_lock(struct fastlock *lock) +{ + while (!__sync_bool_compare_and_swap(&lock->lock, 0, 1)); +} + +extern "C" void fastlock_unlock(struct fastlock *lock) +{ + lock->lock = 0; +} +extern "C" void fastlock_free(struct fastlock *lock) +{ + // NOP + (void)lock; +} \ No newline at end of file diff --git a/src/fastlock.h b/src/fastlock.h new file mode 100644 index 000000000..9ad2457cd --- /dev/null +++ b/src/fastlock.h @@ -0,0 +1,19 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +struct fastlock +{ + int lock; +}; + +void fastlock_init(struct fastlock *lock); +void fastlock_lock(struct fastlock *lock); +void fastlock_unlock(struct fastlock *lock); +void fastlock_free(struct fastlock *lock); + +#ifdef __cplusplus +} +#endif \ No newline at end of file