소스 검색

add hatomic.h

ithewei 5 년 전
부모
커밋
8ea2b670a3
11개의 변경된 파일122개의 추가작업 그리고 7개의 파일을 삭제
  1. 1 0
      CMake/vars.cmake
  2. 1 0
      CMakeLists.txt
  3. 1 0
      Makefile.vars
  4. 88 0
      base/hatomic.h
  5. 10 7
      base/hbase.c
  6. 1 0
      configure
  7. 10 0
      docs/apis.md
  8. 4 0
      hconfig.h
  9. 4 0
      hconfig.h.in
  10. 1 0
      hv.h
  11. 1 0
      readme_cn.md

+ 1 - 0
CMake/vars.cmake

@@ -3,6 +3,7 @@
 set(BASE_HEADERS
     base/hplatform.h
     base/hdef.h
+    base/hatomic.h
     base/hversion.h
     base/hbase.h
     base/hsysinfo.h

+ 1 - 0
CMakeLists.txt

@@ -32,6 +32,7 @@ include(vars)
 # Checks for header files
 check_header("stdbool.h")
 check_header("stdint.h")
+check_header("stdatomic.h")
 check_header("sys/types.h")
 check_header("sys/stat.h")
 check_header("sys/time.h")

+ 1 - 0
Makefile.vars

@@ -8,6 +8,7 @@ INSTALL_LIBDIR=/usr/local/lib
 BASE_HEADERS =  base/hplatform.h\
 				\
 				base/hdef.h\
+				base/hatomic.h\
 				base/hversion.h\
 				base/hbase.h\
 				base/hsysinfo.h\

+ 88 - 0
base/hatomic.h

@@ -0,0 +1,88 @@
+#ifndef HV_ATOMIC_H_
+#define HV_ATOMIC_H_
+
+#ifdef __cplusplus
+
+// c++11
+#include <atomic>
+
+#else
+
+#include "hconfig.h"    // for HAVE_STDATOMIC_H
+#if HAVE_STDATOMIC_H
+
+// c11
+#include <stdatomic.h>
+
+#else
+
+#include "hplatform.h"  // for bool, size_t
+
+typedef volatile bool               atomic_bool;
+typedef volatile char               atomic_char;
+typedef volatile unsigned char      atomic_uchar;
+typedef volatile short              atomic_short;
+typedef volatile unsigned short     atomic_ushort;
+typedef volatile int                atomic_int;
+typedef volatile unsigned int       atomic_uint;
+typedef volatile long               atomic_long;
+typedef volatile unsigned long      atomic_ulong;
+typedef volatile long long          atomic_llong;
+typedef volatile unsigned long long atomic_ullong;
+typedef volatile size_t             atomic_size_t;
+
+typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
+
+#define ATOMIC_FLAG_INIT        { 0 }
+#define ATOMIC_VAR_INIT(value)  (value)
+
+#ifdef __GNUC__
+
+static inline bool atomic_flag_test_and_set(atomic_flag* p) {
+    return !__sync_bool_compare_and_swap(&p->_Value, 0, 1);
+}
+
+static inline void atomic_flag_clear(atomic_flag* p) {
+    p->_Value = 0;
+}
+
+#define atomic_fetch_add    __sync_fetch_and_add
+#define atomic_fetch_sub    __sync_fetch_add_sub
+
+#else
+
+static inline bool atomic_flag_test_and_set(atomic_flag* p) {
+    bool ret = p->_Value;
+    p->_Value = 1;
+    return ret;
+}
+
+static inline void atomic_flag_clear(atomic_flag* p) {
+    p->_Value = 0;
+}
+
+#define atomic_fetch_add(p, n)  *(p); *(p) += (n)
+#define atomic_fetch_sub(p, n)  *(p); *(p) -= (n)
+
+#endif // __GNUC__
+#endif // HAVE_STDATOMIC_H
+
+#ifndef ATOMIC_ADD
+#define ATOMIC_ADD      atomic_fetch_add
+#endif
+
+#ifndef ATOMIC_SUB
+#define ATOMIC_SUB      atomic_fetch_sub
+#endif
+
+#ifndef ATOMIC_INC
+#define ATOMIC_INC(p)   ATOMIC_ADD(p, 1)
+#endif
+
+#ifndef ATOMIC_DEC
+#define ATOMIC_DEC(p)   ATOMIC_SUB(p, 1)
+#endif
+
+#endif // __cplusplus
+
+#endif // HV_ATOMIC_H_

+ 10 - 7
base/hbase.c

@@ -4,8 +4,10 @@
 #include <mach-o/dyld.h> // for _NSGetExecutablePath
 #endif
 
-static unsigned int s_alloc_cnt = 0;
-static unsigned int s_free_cnt = 0;
+#include "hatomic.h"
+
+static atomic_uint s_alloc_cnt = 0;
+static atomic_uint s_free_cnt = 0;
 
 unsigned int hv_alloc_cnt() {
     return s_alloc_cnt;
@@ -16,6 +18,7 @@ unsigned int hv_free_cnt() {
 }
 
 void* safe_malloc(size_t size) {
+    ATOMIC_INC(&s_alloc_cnt);
     ++s_alloc_cnt;
     void* ptr = malloc(size);
     if (!ptr) {
@@ -26,8 +29,8 @@ void* safe_malloc(size_t size) {
 }
 
 void* safe_realloc(void* oldptr, size_t newsize, size_t oldsize) {
-    ++s_alloc_cnt;
-    ++s_free_cnt;
+    ATOMIC_INC(&s_alloc_cnt);
+    ATOMIC_INC(&s_free_cnt);
     void* ptr = realloc(oldptr, newsize);
     if (!ptr) {
         fprintf(stderr, "realloc failed!\n");
@@ -40,7 +43,7 @@ void* safe_realloc(void* oldptr, size_t newsize, size_t oldsize) {
 }
 
 void* safe_calloc(size_t nmemb, size_t size) {
-    ++s_alloc_cnt;
+    ATOMIC_INC(&s_alloc_cnt);
     void* ptr =  calloc(nmemb, size);
     if (!ptr) {
         fprintf(stderr, "calloc failed!\n");
@@ -50,7 +53,7 @@ void* safe_calloc(size_t nmemb, size_t size) {
 }
 
 void* safe_zalloc(size_t size) {
-    ++s_alloc_cnt;
+    ATOMIC_INC(&s_alloc_cnt);
     void* ptr = malloc(size);
     if (!ptr) {
         fprintf(stderr, "malloc failed!\n");
@@ -64,7 +67,7 @@ void safe_free(void* ptr) {
     if (ptr) {
         free(ptr);
         ptr = NULL;
-        ++s_free_cnt;
+        ATOMIC_INC(&s_free_cnt);
     }
 }
 

+ 1 - 0
configure

@@ -112,6 +112,7 @@ echo "TARGET_ARCH     = $TARGET_ARCH"
 # Checks for header files
 header=stdbool.h && check_header
 header=stdint.h && check_header
+header=stdatomic.h && check_header
 header=sys/types.h && check_header
 header=sys/stat.h && check_header
 header=sys/time.h && check_header

+ 10 - 0
docs/apis.md

@@ -53,6 +53,16 @@
 - prefetch
 - printd, printe
 
+### hatomic.h
+- atomic_bool, atomic_char, atomic_short, atomic_int, atomic_long ...
+- atomic_flag
+- atomic_flag_test_and_set
+- atomic_flag_clear
+- atomic_fetch_add
+- atomic_fetch_sub
+- ATOMIC_ADD, ATOMIC_SUB
+- ATOMIC_INC, ATOMIC_DEC
+
 ### herr.h
 - hv_strerror
 

+ 4 - 0
hconfig.h

@@ -9,6 +9,10 @@
 #define HAVE_STDINT_H 1
 #endif
 
+#ifndef HAVE_STDATOMIC_H
+#define HAVE_STDATOMIC_H 1
+#endif
+
 #ifndef HAVE_SYS_TYPES_H
 #define HAVE_SYS_TYPES_H 1
 #endif

+ 4 - 0
hconfig.h.in

@@ -9,6 +9,10 @@
 #define HAVE_STDINT_H @HAVE_STDINT_H@
 #endif
 
+#ifndef HAVE_STDATOMIC_H
+#define HAVE_STDATOMIC_H @HAVE_STDATOMIC_H@
+#endif
+
 #ifndef HAVE_SYS_TYPES_H
 #define HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
 #endif

+ 1 - 0
hv.h

@@ -12,6 +12,7 @@
 
 // c
 #include "hdef.h"   // <stddef.h>
+#include "hatomic.h"// <stdatomic.h>
 #include "herr.h"   // <errno.h>
 #include "htime.h"  // <time.h>
 #include "hmath.h"  // <math.h>

+ 1 - 0
readme_cn.md

@@ -256,6 +256,7 @@ sudo echo-servers/benchmark.sh
 ### base
 - hplatform.h:   平台相关宏
 - hdef.h:        宏定义
+- hatomic.h:     原子操作
 - hversion.h:    版本
 - hbase.h:       基本接口
 - hsysinfo.h:    系统信息