ithewei 6 anni fa
parent
commit
d9f7572882
13 ha cambiato i file con 419 aggiunte e 32 eliminazioni
  1. 2 0
      Makefile.in
  2. 139 0
      base/array.h
  3. 50 1
      base/hdef.h
  4. 172 0
      base/heap.h
  5. 18 2
      base/hlog.cpp
  6. 9 0
      base/hlog.h
  7. 2 2
      base/hproc.h
  8. 6 6
      base/hsocket.h
  9. 2 2
      base/hsysinfo.h
  10. 1 1
      base/hthread.h
  11. 7 7
      base/htime.h
  12. 1 1
      base/hversion.h
  13. 10 10
      base/list.h

+ 2 - 0
Makefile.in

@@ -23,6 +23,7 @@ BUILD_TYPE=DEBUG
 TARGET_TYPE=EXECUTABLE
 
 # COMMANDS
+ifdef CROSS_COMPILE
 CC 	= $(CROSS_COMPILE)gcc
 CXX = $(CROSS_COMPILE)g++
 CPP = $(CC) -E
@@ -33,6 +34,7 @@ NM	= $(CROSS_COMPILE)nm
 STRIP 	= $(CROSS_COMPILE)strip
 OBJCOPY	= $(CROSS_COMPILE)objcopy
 OBJDUMP	= $(CROSS_COMPILE)objdump
+endif
 
 MKDIR = -mkdir -p
 CP = -cp -r

+ 139 - 0
base/array.h

@@ -0,0 +1,139 @@
+#ifndef HW_ARRAY_H_
+#define HW_ARRAY_H_
+
+#include <assert.h> // for assert
+#include <stdlib.h> // for malloc,realloc,free
+#include <string.h> // for memset,memmove
+
+// #include <vector>
+// typedef std::vector<type> atype;
+#define ARRAY_DECL(type, atype) \
+struct atype {      \
+    type*   ptr;    \
+    size_t  size;   \
+    size_t  maxsize;\
+};                  \
+typedef struct atype atype;\
+\
+static inline type* atype##_data(atype* p) {\
+    return p->ptr;\
+}\
+\
+static inline int atype##_size(atype* p) {\
+    return p->size;\
+}\
+\
+static inline int atype##_maxsize(atype* p) {\
+    return p->maxsize;\
+}\
+\
+static inline int atype##_empty(atype* p) {\
+    return p->size == 0;\
+}\
+\
+static inline type* atype##_at(atype* p, int pos) {\
+    if (pos < 0) {\
+        pos += p->size;\
+    }\
+    assert(pos >= 0 && pos < p->size);\
+    return p->ptr + pos;\
+}\
+\
+static inline type* atype##_front(atype* p) {\
+    return p->size == 0 ? NULL : p->ptr;\
+}\
+\
+static inline type* atype##_back(atype* p) {\
+    return p->size == 0 ? NULL : p->ptr+p->size-1;\
+}\
+\
+static inline void atype##_init(atype* p, int maxsize) {\
+    p->size = 0;\
+    p->maxsize = maxsize;\
+    size_t bytes = sizeof(type) * maxsize;\
+    p->ptr = (type*)malloc(bytes);\
+    memset(p->ptr, 0, bytes);\
+}\
+\
+static inline void atype##_cleanup(atype* p) {\
+    if (p->ptr) {\
+        free(p->ptr);\
+        p->ptr = NULL;\
+    }\
+    p->size = p->maxsize = 0;\
+}\
+\
+static inline void atype##_resize(atype* p, int maxsize) {\
+    p->maxsize = maxsize;\
+    int bytes = sizeof(type) * maxsize;\
+    p->ptr = (type*)realloc(p->ptr, bytes);\
+}\
+\
+static inline void atype##_double_resize(atype* p) {\
+    assert(p->maxsize != 0);\
+    return atype##_resize(p, p->maxsize*2);\
+}\
+\
+static inline void atype##_add(atype* p, type* elem, int pos) {\
+    if (pos < 0) {\
+        pos += p->size;\
+    }\
+    assert(pos >= 0 && pos <= p->size);\
+    if (p->size == p->maxsize) {\
+        atype##_double_resize(p);\
+    }\
+    if (pos < p->size) {\
+        memmove(p->ptr + pos+1, p->ptr + pos, sizeof(type)*(p->size-pos));\
+    }\
+    p->ptr[pos] = *elem;\
+    p->size++;\
+}\
+\
+static inline void atype##_del(atype* p, int pos) {\
+    if (pos < 0) {\
+        pos += p->size;\
+    }\
+    assert(pos >= 0 && pos < p->size);\
+    p->size--;\
+    if (pos < p->size) {\
+        memmove(p->ptr + pos, p->ptr + pos+1, sizeof(type)*(p->size-pos));\
+    }\
+}\
+\
+static inline void atype##_push_back(atype* p, type* elem) {\
+    if (p->size == p->maxsize) {\
+        atype##_double_resize(p);\
+    }\
+    p->ptr[p->size] = *elem;\
+    p->size++;\
+}\
+\
+static inline void atype##_pop_back(atype* p) {\
+    assert(p->size > 0);\
+    p->size--;\
+}\
+\
+static inline void atype##_swap(atype* p, int pos1, int pos2) {\
+    if (pos1 < 0) {\
+        pos1 += p->size;\
+    }\
+    if (pos2 < 0) {\
+        pos2 += p->size;\
+    }\
+    type tmp = p->ptr[pos1];\
+    p->ptr[pos1] = p->ptr[pos2];\
+    p->ptr[pos2] = tmp;\
+}\
+\
+static inline void atype##_del_nomove(atype* p, int pos) {\
+    if (pos < 0) {\
+        pos += p->size;\
+    }\
+    assert(pos >= 0 && pos < p->size);\
+    p->size--;\
+    if (pos < p->size) {\
+        p->ptr[pos] = p->ptr[p->size];\
+    }\
+}\
+
+#endif

+ 50 - 1
base/hdef.h

@@ -48,7 +48,7 @@ typedef void (*procedure_t)(void* userdata);
 #endif
 
 #ifndef INFINITE
-#define INFINITE    0xFFFFFFFFU
+#define INFINITE    (uint32_t)-1
 #endif
 
 #ifndef CR
@@ -139,6 +139,19 @@ typedef void (*procedure_t)(void* userdata);
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
 #endif
 
+#ifndef ARRAY_INIT
+#define ARRAY_INIT(type, p, size)\
+    do {\
+        size_t bytes = sizeof(*(p)) * size;\
+        p = (type*)malloc(bytes);\
+        memset(p, 0, bytes);\
+    } while (0)
+#endif
+
+#ifndef ARRAY_RESIZE
+#define ARRAY_RESIZE(type, p, newsize) do {p = (type*)realloc(p, sizeof(*(p)) * newsize);} while(0)
+#endif
+
 #ifndef SAFE_FREE
 #define SAFE_FREE(p)    do {if (p) {free(p); (p) = NULL;}} while(0)
 #endif
@@ -222,6 +235,14 @@ typedef void (*procedure_t)(void* userdata);
 ((type*)((char*)(ptr) - offsetof(type, member)))
 #endif
 
+#ifndef prefetch
+#ifdef __GNUC__
+#define prefetch(x) __builtin_prefetch(x)
+#else
+#define prefetch(x)
+#endif
+#endif
+
 // __cplusplus
 #ifdef __cplusplus
 
@@ -249,6 +270,18 @@ typedef std::map<std::string, std::string> keyval_t;
 #define END_EXTERN_C        } // extern "C"
 #endif
 
+#ifndef ENUM
+#define ENUM(e)     enum e
+#endif
+
+#ifndef STRUCT
+#define STRUCT(s)   struct s
+#endif
+
+#ifndef DEFAULT
+#define DEFAULT(x)  = x
+#endif
+
 #else
 
 #define BEGIN_NAMESPACE(ns)
@@ -258,6 +291,22 @@ typedef std::map<std::string, std::string> keyval_t;
 #define BEGIN_EXTERN_C
 #define END_EXTERN_C
 
+#ifndef ENUM
+#define ENUM(e)\
+typedef enum e e;\
+enum e
+#endif
+
+#ifndef STRUCT
+#define STRUCT(s)\
+typedef struct s s;\
+struct s
+#endif
+
+#ifndef DEFAULT
+#define DEFAULT(x)
+#endif
+
 #endif // __cplusplus
 
 #endif  // HW_DEF_H_

+ 172 - 0
base/heap.h

@@ -0,0 +1,172 @@
+#ifndef HW_HEAP_H_
+#define HW_HEAP_H_
+
+#include <assert.h>
+
+#include "hdef.h"
+
+struct heap_node {
+    struct heap_node* parent;
+    struct heap_node* left;
+    struct heap_node* right;
+};
+
+typedef int (*heap_compare_fn)(const struct heap_node* lhs, const struct heap_node* rhs);
+struct heap {
+    struct heap_node* root;
+    int nelts; // if compare is less_than, root is min of heap
+    // if compare is larger_than, root is max of heap
+    heap_compare_fn compare;
+};
+
+static inline void heap_init(struct heap* heap, heap_compare_fn fn) {
+    heap->root = NULL;
+    heap->nelts = 0;
+    heap->compare = fn;
+}
+
+// replace s with r
+static inline void heap_replace(struct heap* heap, struct heap_node* s, struct heap_node* r) {
+    // s->parent->child, s->left->parent, s->right->parent
+    if (s->parent == NULL) heap->root = r;
+    else if (s->parent->left == s) s->parent->left = r;
+    else if (s->parent->right == s) s->parent->right = r;
+
+    if (s->left) s->left->parent = r;
+    if (s->right) s->right->parent = r;
+    if (r) {
+        //*r = *s;
+        r->parent = s->parent;
+        r->left = s->left;
+        r->right = s->right;
+    }
+}
+
+static inline void heap_swap(struct heap* heap, struct heap_node* parent, struct heap_node* child) {
+    assert(child->parent == parent && (parent->left == child || parent->right == child));
+    struct heap_node* pparent = parent->parent;
+    struct heap_node* lchild = child->left;
+    struct heap_node* rchild = child->right;
+    struct heap_node* sibling = NULL;
+
+    if (pparent == NULL) heap->root = child;
+    else if (pparent->left == parent) pparent->left = child;
+    else if (pparent->right == parent) pparent->right = child;
+
+    if (lchild) lchild->parent = parent;
+    if (rchild) rchild->parent = parent;
+
+    child->parent  = pparent;
+    if (parent->left == child) {
+        sibling = parent->right;
+        child->left = parent;
+        child->right = sibling;
+    } else {
+        sibling = parent->left;
+        child->left = sibling;
+        child->right = parent;
+    }
+    if (sibling) sibling->parent = child;
+
+    parent->parent = child;
+    parent->left   = lchild;
+    parent->right  = rchild;
+}
+
+static inline void heap_insert(struct heap* heap, struct heap_node* node) {
+    // get last => insert node => sift up
+    // 0: left, 1: right
+    int path = 0;
+    int n,d;
+    ++heap->nelts;
+    // traverse from bottom to up, get path of last node
+    for (d = 0, n = heap->nelts; n >= 2; ++d, n>>=1) {
+        path = (path << 1) | (n & 1);
+    }
+
+    // get last->parent by path
+    struct heap_node* parent = heap->root;
+    while(d > 1) {
+        parent = (path & 1) ? parent->right : parent->left;
+        --d;
+        path >>= 1;
+    }
+
+    // insert node
+    node->parent = parent;
+    if (parent == NULL) heap->root = node;
+    else if (path & 1) parent->right = node;
+    else parent->left = node;
+
+    // sift up
+    if (heap->compare) {
+        while (node->parent && heap->compare(node, node->parent)) {
+            heap_swap(heap, node->parent, node);
+        }
+    }
+}
+
+static inline void heap_remove(struct heap* heap, struct heap_node* node) {
+    if (heap->nelts == 0)   return;
+    // get last => replace node with last => sift down and sift up
+    // 0: left, 1: right
+    int path = 0;
+    int n,d;
+    // traverse from bottom to up, get path of last node
+    for (d = 0, n = heap->nelts; n >= 2; ++d, n>>=1) {
+        path = (path << 1) | (n & 1);
+    }
+    --heap->nelts;
+
+    // get last->parent by path
+    struct heap_node* parent = heap->root;
+    while(d > 1) {
+        parent = (path & 1) ? parent->right : parent->left;
+        --d;
+        path >>= 1;
+    }
+
+    // replace node with last
+    struct heap_node* last = NULL;
+    if (parent == NULL) {
+        return;
+    }
+    else if (path & 1) {
+        last = parent->right;
+        parent->right = NULL;
+    }
+    else {
+        last = parent->left;
+        parent->left = NULL;
+    }
+    if (last == NULL) {
+        if (heap->root == node) {
+            heap->root = NULL;
+        }
+        return;
+    }
+    heap_replace(heap, node, last);
+    node->parent = node->left = node->right = NULL;
+
+    if (!heap->compare) return;
+    struct heap_node* v = last;
+    struct heap_node* est = NULL;
+    // sift down
+    while (1) {
+        est = v;
+        if (v->left) est = heap->compare(est, v->left) ? est : v->left;
+        if (v->right) est = heap->compare(est, v->right) ? est : v->right;
+        if (est == v) break;
+        heap_swap(heap, v, est);
+    }
+    // sift up
+    while (v->parent && heap->compare(v, v->parent)) {
+        heap_swap(heap, v->parent, v);
+    }
+}
+
+static inline void heap_dequeue(struct heap* heap) {
+    heap_remove(heap, heap->root);
+}
+
+#endif // HW_HEAP_H_

+ 18 - 2
base/hlog.cpp

@@ -12,9 +12,10 @@
 static char     s_logfile[256] = DEFAULT_LOG_FILE;
 static int      s_loglevel = DEFAULT_LOG_LEVEL;
 static bool     s_logcolor = false;
+static bool     s_fflush   = true;
 static int      s_remain_days = DEFAULT_LOG_REMAIN_DAYS;
 static char     s_logbuf[LOG_BUFSIZE];
-static std::mutex s_mutex;
+static std::mutex s_mutex; // for thread-safe
 
 static void ts_logfile(time_t ts, char* buf, int len) {
     struct tm* tm = localtime(&ts);
@@ -137,7 +138,22 @@ int hlog_printf(int level, const char* fmt, ...) {
     else {
         fprintf(fp, "%s\n", s_logbuf);
     }
-    fflush(fp); // note: fflush cache page => disk, slow
+    if (s_fflush) {
+        fflush(fp);
+    }
 
     return len;
 }
+
+void hlog_set_fflush(int on) {
+    s_fflush = on;
+}
+
+void hlog_fflush() {
+    std::lock_guard<std::mutex> locker(s_mutex);
+
+    FILE* fp = shift_logfile();
+    if (fp) {
+        fflush(fp);
+    }
+}

+ 9 - 0
base/hlog.h

@@ -1,6 +1,10 @@
 #ifndef HW_LOG_H_
 #define HW_LOG_H_
 
+/*
+ * hlog is thread-safe
+ */
+
 #define CL_CLR      "\033[0m"       /* 恢复颜色 */
 #define CL_BLACK    "\033[30m"      /* 黑色字 */
 #define CL_RED      "\e[1;31m"      /* 红色字 */
@@ -48,6 +52,11 @@ void    hlog_set_remain_days(int days);
 void    hlog_enable_color(int on);
 int     hlog_printf(int level, const char* fmt, ...);
 
+// NOTE: fflush cache page => disk, slow
+// fflush, default enable
+void    hlog_set_fflush(int on);
+void    hlog_fflush();
+
 #define hlogd(fmt, ...) hlog_printf(LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
 #define hlogi(fmt, ...) hlog_printf(LOG_LEVEL_INFO,  fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
 #define hlogw(fmt, ...) hlog_printf(LOG_LEVEL_WARN,  fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)

+ 2 - 2
base/hproc.h

@@ -16,7 +16,7 @@ typedef struct proc_ctx_s {
 
 #ifdef OS_UNIX
 // unix use multi-processes
-inline int spawn_proc(proc_ctx_t* ctx) {
+static inline int spawn_proc(proc_ctx_t* ctx) {
     pid_t pid = fork();
     if (pid < 0) {
         perror("fork");
@@ -54,7 +54,7 @@ static void win_thread(void* userdata) {
         ctx->exit(ctx->exit_userdata);
     }
 }
-inline int spawn_proc(proc_ctx_t* ctx) {
+static inline int spawn_proc(proc_ctx_t* ctx) {
     HANDLE h = (HANDLE)_beginthread(win_thread, 0, ctx);
     if (h == NULL) {
         return -1;

+ 6 - 6
base/hsocket.h

@@ -13,11 +13,11 @@ int Connect(const char* host, int port, int nonblock = 0);
 
 #ifdef OS_WIN
 typedef int socklen_t;
-inline int blocking(int sockfd) {
+static inline int blocking(int sockfd) {
     unsigned long nb = 0;
     return ioctlsocket(sockfd, FIONBIO, &nb);
 }
-inline int nonblocking(int sockfd) {
+static inline int nonblocking(int sockfd) {
     unsigned long nb = 1;
     return ioctlsocket(sockfd, FIONBIO, &nb);
 }
@@ -32,11 +32,11 @@ inline int nonblocking(int sockfd) {
 #define NIO_EAGAIN  EAGAIN
 #endif
 
-inline int tcp_nodelay(int sockfd, int on = 1) {
+static inline int tcp_nodelay(int sockfd, int on = 1) {
     return setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(int));
 }
 
-inline int tcp_nopush(int sockfd, int on = 1) {
+static inline int tcp_nopush(int sockfd, int on = 1) {
 #ifdef TCP_NOPUSH
     return setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, (const char*)&on, sizeof(int));
 #elif defined(TCP_CORK)
@@ -46,7 +46,7 @@ inline int tcp_nopush(int sockfd, int on = 1) {
 #endif
 }
 
-inline int tcp_keepalive(int sockfd, int on = 1, int delay = 60) {
+static inline int tcp_keepalive(int sockfd, int on = 1, int delay = 60) {
     if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(int)) != 0) {
         return sockerrno;
     }
@@ -61,7 +61,7 @@ inline int tcp_keepalive(int sockfd, int on = 1, int delay = 60) {
 #endif
 }
 
-inline int udp_broadcast(int sockfd, int on = 1) {
+static inline int udp_broadcast(int sockfd, int on = 1) {
     return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int));
 }
 

+ 2 - 2
base/hsysinfo.h

@@ -7,7 +7,7 @@
 #include <sys/sysinfo.h>
 #endif
 
-inline int get_ncpu() {
+static inline int get_ncpu() {
 #ifdef OS_WIN
     SYSTEM_INFO si;
     GetSystemInfo(&si);
@@ -25,7 +25,7 @@ typedef struct meminfo_s {
     unsigned long free; // KB
 } meminfo_t;
 
-inline int get_meminfo(meminfo_t* mem) {
+static inline int get_meminfo(meminfo_t* mem) {
 #ifdef OS_WIN
     MEMORYSTATUSEX memstat;
     memset(&memstat, 0, sizeof(memstat));

+ 1 - 1
base/hthread.h

@@ -14,7 +14,7 @@
 #define gettid  gettid
 #elif defined(OS_LINUX)
 #include <sys/syscall.h>
-inline int gettid() {
+static inline int gettid() {
     return syscall(SYS_gettid);
 }
 #else

+ 7 - 7
base/htime.h

@@ -1,6 +1,10 @@
 #ifndef HW_TIME_H_
 #define HW_TIME_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "hplatform.h"
 
 typedef struct datetime_s {
@@ -14,12 +18,12 @@ typedef struct datetime_s {
 } datetime_t;
 
 #ifdef OS_WIN
-inline void sleep(unsigned int s) {
+static inline void sleep(unsigned int s) {
     Sleep(s*1000);
 }
 #endif
 
-inline void msleep(unsigned int ms) {
+static inline void msleep(unsigned int ms) {
 #ifdef OS_WIN
     Sleep(ms);
 #else
@@ -28,7 +32,7 @@ inline void msleep(unsigned int ms) {
 }
 
 // ms
-inline unsigned int gettick() {
+static inline unsigned int gettick() {
 #ifdef OS_WIN
     return GetTickCount();
 #else
@@ -36,10 +40,6 @@ inline unsigned int gettick() {
 #endif
 }
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 // us
 unsigned long long gethrtime();
 

+ 1 - 1
base/hversion.h

@@ -15,7 +15,7 @@
 
 #define H_VERSION_NUMBER    (H_VERSION_MAJOR << 24) | (H_VERSION_MINOR << 16) | (H_VERSION_MICRO << 8) | H_VERSION_PATCH
 
-inline const char* get_static_version() {
+static inline const char* get_static_version() {
     return H_VERSION_STRING;
 }
 

+ 10 - 10
base/list.h

@@ -16,6 +16,7 @@
 struct list_head {
 	struct list_head *next, *prev;
 };
+#define list_node   list_head
 
 struct hlist_head {
 	struct hlist_node *first;
@@ -26,11 +27,9 @@ struct hlist_node {
 };
 
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-	struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
+#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
+#define INIT_LIST_HEAD  list_init
+static inline void list_init(struct list_head *list)
 {
 	list->next = list;
 	list->prev = list;
@@ -106,8 +105,8 @@ static inline void __list_del_entry(struct list_head *entry)
 static inline void list_del(struct list_head *entry)
 {
 	__list_del(entry->prev, entry->next);
-	entry->next = NULL;
-	entry->prev = NULL;
+	//entry->next = NULL;
+	//entry->prev = NULL;
 }
 
 /**
@@ -569,7 +568,8 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define HLIST_HEAD_INIT { .first = NULL }
 #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-static inline void INIT_HLIST_NODE(struct hlist_node *h)
+#define INIT_HLIST_NODE hlist_init
+static inline void hlist_init(struct hlist_node *h)
 {
 	h->next = NULL;
 	h->pprev = NULL;
@@ -597,8 +597,8 @@ static inline void __hlist_del(struct hlist_node *n)
 static inline void hlist_del(struct hlist_node *n)
 {
 	__hlist_del(n);
-	n->next = NULL;
-	n->pprev = NULL;
+	//n->next = NULL;
+	//n->pprev = NULL;
 }
 
 static inline void hlist_del_init(struct hlist_node *n)