Skip to content

Commit 0216a83

Browse files
authored
N-API Support (#36)
* Initial commit * _Bool for Windows * _Bool for Windows, pt 2 * Windows link error * Update documentation * Add N-API v3 badge to README * Clarify licensing * Update appveyor.yml to use Node.js 14.2.0
1 parent 01b954b commit 0216a83

35 files changed

+1652
-366
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ coverage
2121
.lock-wscript
2222

2323
# Compiled binary addons (http://nodejs.org/api/addons.html)
24-
build/Release
24+
build-tmp-napi-v3/
2525

2626
# Dependency directory
2727
node_modules
@@ -42,3 +42,4 @@ lib/binding
4242

4343
yarn.lock
4444
package-lock.json
45+
.nyc_output

.travis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ branches:
77
- /^v[0-9]/
88
matrix:
99
include:
10+
- os: linux
11+
env: NODE_VERSION="14"
1012
- os: linux
1113
env: NODE_VERSION="12"
1214
- os: linux
1315
env: NODE_VERSION="10"
14-
- os: linux
15-
env: NODE_VERSION="8"
16+
- os: osx
17+
env: NODE_VERSION="14"
1618
- os: osx
1719
env: NODE_VERSION="12"
1820
- os: osx
1921
env: NODE_VERSION="10"
20-
- os: osx
21-
env: NODE_VERSION="8"
2222
env:
2323
global:
2424
- JOBS: '8'

HdrHistogram_c/src/CMakeLists.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FILE(GLOB histogram_files "*.c")
2+
FILE(GLOB HEADER "*.h")
3+
4+
option(HDR_HISTOGRAM_BUILD_STATIC "Build static library" ON)
5+
option(HDR_HISTOGRAM_BUILD_SHARED "Build shared library" ON)
6+
7+
if (HDR_HISTOGRAM_BUILD_SHARED)
8+
add_library(hdr_histogram SHARED ${histogram_files} ${HEADER})
9+
if (WIN32)
10+
set_target_properties(hdr_histogram PROPERTIES VERSION ${HDR_VERSION})
11+
target_link_libraries(hdr_histogram ws2_32)
12+
else ()
13+
target_link_libraries(hdr_histogram m)
14+
set_target_properties(hdr_histogram PROPERTIES VERSION ${HDR_VERSION} SOVERSION ${HDR_SOVERSION})
15+
endif ()
16+
target_link_libraries(hdr_histogram ${ZLIB_LIBRARIES})
17+
target_include_directories(hdr_histogram SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIRS})
18+
install(TARGETS hdr_histogram DESTINATION lib${LIB_SUFFIX})
19+
endif (HDR_HISTOGRAM_BUILD_SHARED)
20+
21+
if (HDR_HISTOGRAM_BUILD_STATIC)
22+
add_library(hdr_histogram_static STATIC ${histogram_files} ${HEADER})
23+
if (WIN32)
24+
target_link_libraries(hdr_histogram_static ws2_32)
25+
else ()
26+
target_link_libraries(hdr_histogram_static m)
27+
endif ()
28+
target_link_libraries(hdr_histogram_static ${ZLIB_LIBRARIES})
29+
target_include_directories(hdr_histogram_static SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIRS})
30+
install(TARGETS hdr_histogram_static DESTINATION lib${LIB_SUFFIX})
31+
endif (HDR_HISTOGRAM_BUILD_STATIC)
32+
33+
install(FILES hdr_histogram.h hdr_histogram_log.h hdr_time.h hdr_writer_reader_phaser.h hdr_interval_recorder.h hdr_thread.h DESTINATION include/hdr)
Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <stdint.h>
1414
#include <intrin.h>
15+
#include <stdbool.h>
1516

1617
static void __inline * hdr_atomic_load_pointer(void** pointer)
1718
{
@@ -37,14 +38,45 @@ static void __inline hdr_atomic_store_64(int64_t* field, int64_t value)
3738
*field = value;
3839
}
3940

40-
static int64_t __inline hdr_atomic_exchange_64(volatile int64_t* field, int64_t initial)
41+
static int64_t __inline hdr_atomic_exchange_64(volatile int64_t* field, int64_t value)
4142
{
42-
return _InterlockedExchange64(field, initial);
43+
#if defined(_WIN64)
44+
return _InterlockedExchange64(field, value);
45+
#else
46+
int64_t comparand;
47+
int64_t initial_value = *field;
48+
do
49+
{
50+
comparand = initial_value;
51+
initial_value = _InterlockedCompareExchange64(field, value, comparand);
52+
}
53+
while (comparand != initial_value);
54+
55+
return initial_value;
56+
#endif
4357
}
4458

4559
static int64_t __inline hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value)
4660
{
61+
#if defined(_WIN64)
4762
return _InterlockedExchangeAdd64(field, value) + value;
63+
#else
64+
int64_t comparand;
65+
int64_t initial_value = *field;
66+
do
67+
{
68+
comparand = initial_value;
69+
initial_value = _InterlockedCompareExchange64(field, comparand + value, comparand);
70+
}
71+
while (comparand != initial_value);
72+
73+
return initial_value + value;
74+
#endif
75+
}
76+
77+
static bool __inline hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired)
78+
{
79+
return *expected == _InterlockedCompareExchange64(field, desired, *expected);
4880
}
4981

5082
#elif defined(__ATOMIC_SEQ_CST)
@@ -55,10 +87,12 @@ static int64_t __inline hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t
5587
#define hdr_atomic_store_64(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST)
5688
#define hdr_atomic_exchange_64(f,i) __atomic_exchange_n(f,i, __ATOMIC_SEQ_CST)
5789
#define hdr_atomic_add_fetch_64(field, value) __atomic_add_fetch(field, value, __ATOMIC_SEQ_CST)
90+
#define hdr_atomic_compare_exchange_64(field, expected, desired) __atomic_compare_exchange_n(field, expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
5891

5992
#elif defined(__x86_64__)
6093

6194
#include <stdint.h>
95+
#include <stdbool.h>
6296

6397
static inline void* hdr_atomic_load_pointer(void** pointer)
6498
{
@@ -96,6 +130,13 @@ static inline int64_t hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t v
96130
return __sync_add_and_fetch(field, value);
97131
}
98132

133+
static inline bool hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired)
134+
{
135+
int64_t original;
136+
asm volatile( "lock; cmpxchgq %2, %1" : "=a"(original), "+m"(*field) : "q"(desired), "0"(*expected));
137+
return original == *expected;
138+
}
139+
99140
#else
100141

101142
#error "Unable to determine atomic operations for your platform"
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int zig_zag_encode_i64(uint8_t* buffer, int64_t signed_value)
9595
return bytesWritten;
9696
}
9797

98-
int zig_zag_decode_i64(const uint8_t* buffer, int64_t* retVal)
98+
int zig_zag_decode_i64(const uint8_t* buffer, int64_t* signed_value)
9999
{
100100
uint64_t v = buffer[0];
101101
uint64_t value = v & 0x7F;
@@ -149,8 +149,15 @@ int zig_zag_decode_i64(const uint8_t* buffer, int64_t* retVal)
149149
}
150150
}
151151

152+
#if defined(_MSC_VER)
153+
#pragma warning(push)
154+
#pragma warning(disable: 4146) // C4146: unary minus operator applied to unsigned type, result still unsigned
155+
#endif
152156
value = (value >> 1) ^ (-(value & 1));
153-
*retVal = (int64_t) value;
157+
#if defined(_MSC_VER)
158+
#pragma warning(pop)
159+
#endif
160+
*signed_value = (int64_t) value;
154161

155162
return bytesRead;
156163
}
Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "hdr_histogram.h"
1818
#include "hdr_tests.h"
19+
#include "hdr_atomic.h"
1920

2021
/* ###### ####### ## ## ## ## ######## ###### */
2122
/* ## ## ## ## ## ## ### ## ## ## ## */
@@ -66,12 +67,49 @@ static void counts_inc_normalised(
6667
h->total_count += value;
6768
}
6869

70+
static void counts_inc_normalised_atomic(
71+
struct hdr_histogram* h, int32_t index, int64_t value)
72+
{
73+
int32_t normalised_index = normalize_index(h, index);
74+
75+
hdr_atomic_add_fetch_64(&h->counts[normalised_index], value);
76+
hdr_atomic_add_fetch_64(&h->total_count, value);
77+
}
78+
6979
static void update_min_max(struct hdr_histogram* h, int64_t value)
7080
{
7181
h->min_value = (value < h->min_value && value != 0) ? value : h->min_value;
7282
h->max_value = (value > h->max_value) ? value : h->max_value;
7383
}
7484

85+
static void update_min_max_atomic(struct hdr_histogram* h, int64_t value)
86+
{
87+
int64_t current_min_value;
88+
int64_t current_max_value;
89+
do
90+
{
91+
current_min_value = hdr_atomic_load_64(&h->min_value);
92+
93+
if (0 == value || current_min_value <= value)
94+
{
95+
break;
96+
}
97+
}
98+
while (!hdr_atomic_compare_exchange_64(&h->min_value, &current_min_value, value));
99+
100+
do
101+
{
102+
current_max_value = hdr_atomic_load_64(&h->max_value);
103+
104+
if (value <= current_max_value)
105+
{
106+
break;
107+
}
108+
}
109+
while (!hdr_atomic_compare_exchange_64(&h->max_value, &current_max_value, value));
110+
}
111+
112+
75113
/* ## ## ######## #### ## #### ######## ## ## */
76114
/* ## ## ## ## ## ## ## ## ## */
77115
/* ## ## ## ## ## ## ## #### */
@@ -359,13 +397,13 @@ int hdr_init(
359397
return r;
360398
}
361399

362-
counts = calloc((size_t) cfg.counts_len, sizeof(int64_t));
400+
counts = (int64_t*) calloc((size_t) cfg.counts_len, sizeof(int64_t));
363401
if (!counts)
364402
{
365403
return ENOMEM;
366404
}
367405

368-
histogram = calloc(1, sizeof(struct hdr_histogram));
406+
histogram = (struct hdr_histogram*) calloc(1, sizeof(struct hdr_histogram));
369407
if (!histogram)
370408
{
371409
return ENOMEM;
@@ -381,8 +419,10 @@ int hdr_init(
381419

382420
void hdr_close(struct hdr_histogram* h)
383421
{
384-
free(h->counts);
385-
free(h);
422+
if (h) {
423+
free(h->counts);
424+
free(h);
425+
}
386426
}
387427

388428
int hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result)
@@ -418,6 +458,11 @@ bool hdr_record_value(struct hdr_histogram* h, int64_t value)
418458
return hdr_record_values(h, value, 1);
419459
}
420460

461+
bool hdr_record_value_atomic(struct hdr_histogram* h, int64_t value)
462+
{
463+
return hdr_record_values_atomic(h, value, 1);
464+
}
465+
421466
bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count)
422467
{
423468
int32_t counts_index;
@@ -440,11 +485,37 @@ bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count)
440485
return true;
441486
}
442487

488+
bool hdr_record_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count)
489+
{
490+
int32_t counts_index;
491+
492+
if (value < 0)
493+
{
494+
return false;
495+
}
496+
497+
counts_index = counts_index_for(h, value);
498+
499+
if (counts_index < 0 || h->counts_len <= counts_index)
500+
{
501+
return false;
502+
}
503+
504+
counts_inc_normalised_atomic(h, counts_index, count);
505+
update_min_max_atomic(h, value);
506+
507+
return true;
508+
}
509+
443510
bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expected_interval)
444511
{
445512
return hdr_record_corrected_values(h, value, 1, expected_interval);
446513
}
447514

515+
bool hdr_record_corrected_value_atomic(struct hdr_histogram* h, int64_t value, int64_t expected_interval)
516+
{
517+
return hdr_record_corrected_values_atomic(h, value, 1, expected_interval);
518+
}
448519

449520
bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval)
450521
{
@@ -472,6 +543,32 @@ bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t
472543
return true;
473544
}
474545

546+
bool hdr_record_corrected_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval)
547+
{
548+
int64_t missing_value;
549+
550+
if (!hdr_record_values_atomic(h, value, count))
551+
{
552+
return false;
553+
}
554+
555+
if (expected_interval <= 0 || value <= expected_interval)
556+
{
557+
return true;
558+
}
559+
560+
missing_value = value - expected_interval;
561+
for (; missing_value >= expected_interval; missing_value -= expected_interval)
562+
{
563+
if (!hdr_record_values_atomic(h, missing_value, count))
564+
{
565+
return false;
566+
}
567+
}
568+
569+
return true;
570+
}
571+
475572
int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from)
476573
{
477574
struct hdr_iter iter;

0 commit comments

Comments
 (0)