iodine 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +4 -4
- data/SPEC-Websocket-Draft.md +3 -6
- data/bin/mustache.rb +128 -0
- data/examples/test_template.mustache +16 -0
- data/ext/iodine/fio.c +9397 -0
- data/ext/iodine/fio.h +4723 -0
- data/ext/iodine/fio_ary.h +353 -54
- data/ext/iodine/fio_cli.c +351 -361
- data/ext/iodine/fio_cli.h +84 -105
- data/ext/iodine/fio_hashmap.h +70 -16
- data/ext/iodine/fio_json_parser.h +35 -24
- data/ext/iodine/fio_siphash.c +104 -4
- data/ext/iodine/fio_siphash.h +18 -2
- data/ext/iodine/fio_str.h +1218 -0
- data/ext/iodine/fio_tmpfile.h +1 -1
- data/ext/iodine/fiobj.h +13 -8
- data/ext/iodine/fiobj4sock.h +6 -8
- data/ext/iodine/fiobj_ary.c +107 -17
- data/ext/iodine/fiobj_ary.h +36 -4
- data/ext/iodine/fiobj_data.c +146 -127
- data/ext/iodine/fiobj_data.h +25 -23
- data/ext/iodine/fiobj_hash.c +7 -7
- data/ext/iodine/fiobj_hash.h +6 -5
- data/ext/iodine/fiobj_json.c +20 -17
- data/ext/iodine/fiobj_json.h +5 -5
- data/ext/iodine/fiobj_mem.h +71 -0
- data/ext/iodine/fiobj_mustache.c +310 -0
- data/ext/iodine/fiobj_mustache.h +40 -0
- data/ext/iodine/fiobj_numbers.c +199 -94
- data/ext/iodine/fiobj_numbers.h +7 -7
- data/ext/iodine/fiobj_str.c +142 -333
- data/ext/iodine/fiobj_str.h +65 -55
- data/ext/iodine/fiobject.c +49 -11
- data/ext/iodine/fiobject.h +40 -39
- data/ext/iodine/http.c +382 -190
- data/ext/iodine/http.h +124 -80
- data/ext/iodine/http1.c +99 -127
- data/ext/iodine/http1.h +5 -5
- data/ext/iodine/http1_parser.c +3 -2
- data/ext/iodine/http1_parser.h +2 -2
- data/ext/iodine/http_internal.c +14 -12
- data/ext/iodine/http_internal.h +25 -19
- data/ext/iodine/iodine.c +37 -18
- data/ext/iodine/iodine.h +4 -0
- data/ext/iodine/iodine_caller.c +9 -2
- data/ext/iodine/iodine_caller.h +2 -0
- data/ext/iodine/iodine_connection.c +82 -117
- data/ext/iodine/iodine_defer.c +57 -50
- data/ext/iodine/iodine_defer.h +0 -1
- data/ext/iodine/iodine_fiobj2rb.h +4 -2
- data/ext/iodine/iodine_helpers.c +4 -4
- data/ext/iodine/iodine_http.c +25 -32
- data/ext/iodine/iodine_json.c +2 -1
- data/ext/iodine/iodine_mustache.c +423 -0
- data/ext/iodine/iodine_mustache.h +6 -0
- data/ext/iodine/iodine_pubsub.c +48 -153
- data/ext/iodine/iodine_pubsub.h +5 -4
- data/ext/iodine/iodine_rack_io.c +7 -5
- data/ext/iodine/iodine_store.c +16 -13
- data/ext/iodine/iodine_tcp.c +26 -34
- data/ext/iodine/mustache_parser.h +1085 -0
- data/ext/iodine/redis_engine.c +740 -646
- data/ext/iodine/redis_engine.h +13 -15
- data/ext/iodine/resp_parser.h +11 -5
- data/ext/iodine/websocket_parser.h +13 -13
- data/ext/iodine/websockets.c +240 -393
- data/ext/iodine/websockets.h +52 -113
- data/lib/iodine.rb +1 -1
- data/lib/iodine/mustache.rb +140 -0
- data/lib/iodine/version.rb +1 -1
- metadata +15 -28
- data/ext/iodine/defer.c +0 -566
- data/ext/iodine/defer.h +0 -148
- data/ext/iodine/evio.c +0 -26
- data/ext/iodine/evio.h +0 -161
- data/ext/iodine/evio_callbacks.c +0 -26
- data/ext/iodine/evio_epoll.c +0 -251
- data/ext/iodine/evio_kqueue.c +0 -194
- data/ext/iodine/facil.c +0 -2325
- data/ext/iodine/facil.h +0 -616
- data/ext/iodine/fio_base64.c +0 -277
- data/ext/iodine/fio_base64.h +0 -71
- data/ext/iodine/fio_llist.h +0 -257
- data/ext/iodine/fio_mem.c +0 -675
- data/ext/iodine/fio_mem.h +0 -143
- data/ext/iodine/fio_random.c +0 -248
- data/ext/iodine/fio_random.h +0 -45
- data/ext/iodine/fio_sha1.c +0 -362
- data/ext/iodine/fio_sha1.h +0 -107
- data/ext/iodine/fio_sha2.c +0 -842
- data/ext/iodine/fio_sha2.h +0 -169
- data/ext/iodine/pubsub.c +0 -867
- data/ext/iodine/pubsub.h +0 -221
- data/ext/iodine/sock.c +0 -1366
- data/ext/iodine/sock.h +0 -566
- data/ext/iodine/spnlock.inc +0 -111
data/ext/iodine/fio_mem.h
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz Segev, 2018
|
3
|
-
License: MIT
|
4
|
-
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
6
|
-
*/
|
7
|
-
#ifndef H_FIO_MEM_H
|
8
|
-
|
9
|
-
/**
|
10
|
-
* This is a custom memory allocator the utilizes memory pools to allow for
|
11
|
-
* concurrent memory allocations across threads.
|
12
|
-
*
|
13
|
-
* Allocated memory is always zeroed out and aligned on a 16 byte boundary.
|
14
|
-
*
|
15
|
-
* Reallocated memory is always aligned on a 16 byte boundary but it might be
|
16
|
-
* filled with junk data after the valid data (this is true also for
|
17
|
-
* `fio_realloc2`).
|
18
|
-
*
|
19
|
-
* The memory allocator assumes multiple concurrent allocation/deallocation,
|
20
|
-
* short life spans (memory is freed shortly, but not immediately, after it was
|
21
|
-
* allocated) and we small allocations (realloc almost always copies data).
|
22
|
-
*
|
23
|
-
* These assumptions allow the allocator to avoid lock contention by ignoring
|
24
|
-
* fragmentation within a memory "block" and waiting for the whole "block" to be
|
25
|
-
* freed before it's memory is recycled (no "free list").
|
26
|
-
*
|
27
|
-
* This allocator should NOT be used for objects with a long life-span, because
|
28
|
-
* even a single persistent object will prevent the re-use of the whole memory
|
29
|
-
* block (128Kb by default) from which it was allocated.
|
30
|
-
*
|
31
|
-
* A memory "block" can include any number of memory pages that are a multiple
|
32
|
-
* of 2 (up to 1Mb of memory). However, the default value, set by
|
33
|
-
* MEMORY_BLOCK_SIZE, is either 128Kb (set at th end of this header).
|
34
|
-
*
|
35
|
-
* Each block includes a header that uses reference counters and position
|
36
|
-
* markers.
|
37
|
-
*
|
38
|
-
* The position marker (`pos`) marks the next available byte (counted in
|
39
|
-
* multiples of 16).
|
40
|
-
*
|
41
|
-
* The reference counter (`ref`) counts how many pointers reference memory in
|
42
|
-
* the block (including the "arena" that "owns" the block).
|
43
|
-
*
|
44
|
-
* Except for the position marker (`pos`) that acts the same as `sbrk`, there's
|
45
|
-
* no way to know which "slices" are allocated and which "slices" are available.
|
46
|
-
*
|
47
|
-
* Small allocations are differentiated by their memory alignment. If a memory
|
48
|
-
* allocation is placed 8 bytes after whole block alignment, the memory was
|
49
|
-
* allocated directly using `mmap` (and it might be using a whole page more than
|
50
|
-
* request, just because it needed that extra header space!).
|
51
|
-
*
|
52
|
-
* The allocator uses `mmap` when requesting memory from the system and for
|
53
|
-
* allocations bigger than MEMORY_BLOCK_ALLOC_LIMIT (37.5% of the block).
|
54
|
-
*
|
55
|
-
* To replace the system's `malloc` function family compile with the
|
56
|
-
* `FIO_OVERRIDE_MALLOC` defined (`-DFIO_OVERRIDE_MALLOC`).
|
57
|
-
*
|
58
|
-
* When using tcmalloc or jemalloc, define `FIO_FORCE_MALLOC` to prevent
|
59
|
-
* `fio_mem` from compiling (`-DFIO_FORCE_MALLOC`). Function wrappers will be
|
60
|
-
* compiled just in case, so calls to `fio_malloc` will be routed to `malloc`.
|
61
|
-
*
|
62
|
-
*/
|
63
|
-
#define H_FIO_MEM_H
|
64
|
-
|
65
|
-
#include <stdlib.h>
|
66
|
-
|
67
|
-
/** Allocates memory using a per-CPU core block memory pool. */
|
68
|
-
void *fio_malloc(size_t size);
|
69
|
-
|
70
|
-
/** Allocates memory using a per-CPU core block memory pool. memory is zeroed
|
71
|
-
* out. */
|
72
|
-
void *fio_calloc(size_t size, size_t count);
|
73
|
-
|
74
|
-
/** Frees memory that was allocated using this library. */
|
75
|
-
void fio_free(void *ptr);
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Re-allocates memory. An attept to avoid copying the data is made only for
|
79
|
-
* memory allocations larger than 64Kb.
|
80
|
-
*/
|
81
|
-
void *fio_realloc(void *ptr, size_t new_size);
|
82
|
-
|
83
|
-
/**
|
84
|
-
* Re-allocates memory. An attept to avoid copying the data is made only for
|
85
|
-
* memory allocations larger than 64Kb.
|
86
|
-
*
|
87
|
-
* This variation is slightly faster as it might copy less data.
|
88
|
-
*/
|
89
|
-
void *fio_realloc2(void *ptr, size_t new_size, size_t copy_length);
|
90
|
-
|
91
|
-
/** Clears any memory locks, in case of a system call to `fork`. */
|
92
|
-
void fio_malloc_after_fork(void);
|
93
|
-
|
94
|
-
/** Tests the facil.io memory allocator. */
|
95
|
-
void fio_malloc_test(void);
|
96
|
-
|
97
|
-
/** If defined, `malloc` will be used instead of the fio_malloc functions */
|
98
|
-
#if FIO_FORCE_MALLOC
|
99
|
-
#define fio_malloc malloc
|
100
|
-
#define fio_calloc calloc
|
101
|
-
#define fio_free free
|
102
|
-
#define fio_realloc realloc
|
103
|
-
#define fio_realloc2(ptr, new_size, old_data_len) realloc((ptr), (new_size))
|
104
|
-
#define fio_malloc_test()
|
105
|
-
#define fio_malloc_after_fork
|
106
|
-
|
107
|
-
/* allows local override as well as global override */
|
108
|
-
#elif FIO_OVERRIDE_MALLOC
|
109
|
-
#define malloc fio_malloc
|
110
|
-
#define free fio_free
|
111
|
-
#define realloc fio_realloc
|
112
|
-
#define calloc fio_calloc
|
113
|
-
|
114
|
-
#endif
|
115
|
-
|
116
|
-
#ifndef FIO_MEM_MAX_BLOCKS_PER_CORE
|
117
|
-
/**
|
118
|
-
* The maximum number of available memory blocks that will be pooled before
|
119
|
-
* memory is returned to the system.
|
120
|
-
*/
|
121
|
-
#define FIO_MEM_MAX_BLOCKS_PER_CORE 32 /* approx. 2Mb per CPU core */
|
122
|
-
#endif
|
123
|
-
|
124
|
-
/** Allocator default settings. */
|
125
|
-
#ifndef FIO_MEMORY_BLOCK_SIZE_LOG
|
126
|
-
#define FIO_MEMORY_BLOCK_SIZE_LOG (17) /* 17 == 128Kb */
|
127
|
-
#endif
|
128
|
-
#ifndef FIO_MEMORY_BLOCK_SIZE
|
129
|
-
#define FIO_MEMORY_BLOCK_SIZE ((uintptr_t)1 << FIO_MEMORY_BLOCK_SIZE_LOG)
|
130
|
-
#endif
|
131
|
-
#ifndef FIO_MEMORY_BLOCK_MASK
|
132
|
-
#define FIO_MEMORY_BLOCK_MASK (FIO_MEMORY_BLOCK_SIZE - 1) /* 0b111... */
|
133
|
-
#endif
|
134
|
-
#ifndef FIO_MEMORY_BLOCK_SLICES
|
135
|
-
#define FIO_MEMORY_BLOCK_SLICES (FIO_MEMORY_BLOCK_SIZE >> 4) /* 16B/slice */
|
136
|
-
#endif
|
137
|
-
#ifndef FIO_MEMORY_BLOCK_ALLOC_LIMIT
|
138
|
-
/* defaults to 37.5% of the block */
|
139
|
-
#define FIO_MEMORY_BLOCK_ALLOC_LIMIT \
|
140
|
-
((FIO_MEMORY_BLOCK_SIZE >> 2) + (FIO_MEMORY_BLOCK_SIZE >> 3))
|
141
|
-
#endif
|
142
|
-
|
143
|
-
#endif /* H_FIO_MEM_H */
|
data/ext/iodine/fio_random.c
DELETED
@@ -1,248 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz segev, 2016-2018
|
3
|
-
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
|
-
of), which might be subject to their own licenses.
|
5
|
-
|
6
|
-
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
-
*/
|
8
|
-
#ifndef _GNU_SOURCE
|
9
|
-
#define _GNU_SOURCE
|
10
|
-
#endif
|
11
|
-
#include "fio_random.h"
|
12
|
-
|
13
|
-
#include <errno.h>
|
14
|
-
#include <stdio.h>
|
15
|
-
|
16
|
-
#ifndef __has_include
|
17
|
-
#define __has_include(x) 0
|
18
|
-
#endif
|
19
|
-
|
20
|
-
/* include intrinsics if supported */
|
21
|
-
#if __has_include(<x86intrin.h>)
|
22
|
-
#include <x86intrin.h>
|
23
|
-
#define HAVE_X86Intrin
|
24
|
-
/*
|
25
|
-
see: https://software.intel.com/en-us/node/513411
|
26
|
-
and: https://software.intel.com/sites/landingpage/IntrinsicsGuide/
|
27
|
-
*/
|
28
|
-
#endif /* __has_include(<x86intrin.h>) */
|
29
|
-
|
30
|
-
/* check for unix support */
|
31
|
-
#if defined(__unix__) || defined(__linux__) || defined(__APPLE__) || \
|
32
|
-
(__has_include(<unistd.h>) && __has_include(<pthread.h>))
|
33
|
-
#ifndef HAS_UNIX_FEATURES
|
34
|
-
#define HAS_UNIX_FEATURES
|
35
|
-
#endif
|
36
|
-
#endif
|
37
|
-
|
38
|
-
// clang-format off
|
39
|
-
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
40
|
-
# if defined(__has_include)
|
41
|
-
# if __has_include(<endian.h>)
|
42
|
-
# include <endian.h>
|
43
|
-
# elif __has_include(<sys/endian.h>)
|
44
|
-
# include <sys/endian.h>
|
45
|
-
# endif
|
46
|
-
# endif
|
47
|
-
# if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && \
|
48
|
-
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
49
|
-
# define __BIG_ENDIAN__
|
50
|
-
# endif
|
51
|
-
#endif
|
52
|
-
// clang-format on
|
53
|
-
|
54
|
-
#if defined(USE_ALT_RANDOM) || !defined(HAS_UNIX_FEATURES)
|
55
|
-
#include "fio_sha2.h"
|
56
|
-
#include <time.h>
|
57
|
-
#include <string.h>
|
58
|
-
|
59
|
-
static inline void fio_random_data(sha2_s *sha2) {
|
60
|
-
#ifdef RUSAGE_SELF
|
61
|
-
struct rusage rusage;
|
62
|
-
getrusage(RUSAGE_SELF, &rusage);
|
63
|
-
fio_sha2_write(sha2, &rusage, sizeof(rusage));
|
64
|
-
#elif defined CLOCKS_PER_SEC
|
65
|
-
size_t clk = (size_t)clock();
|
66
|
-
fio_sha2_write(&sha2, &clk, sizeof(clk));
|
67
|
-
time_t the_time;
|
68
|
-
time(&the_time);
|
69
|
-
fio_sha2_write(sha2, &the_time, sizeof(the_time));
|
70
|
-
fio_sha2_write(sha2, &fio_rand64, sizeof(void *));
|
71
|
-
fio_sha2_write(sha2, &fio_rand_bytes, sizeof(void *));
|
72
|
-
{
|
73
|
-
char junk_data[64];
|
74
|
-
fio_sha2_write(sha2, junk_data, 64);
|
75
|
-
}
|
76
|
-
#else
|
77
|
-
#error Random alternative failed to find access to the CPU clock state.
|
78
|
-
#endif
|
79
|
-
fio_sha2_write(sha2, sha2, sizeof(void *));
|
80
|
-
}
|
81
|
-
|
82
|
-
uint32_t fio_rand32(void) {
|
83
|
-
sha2_s sha2 = fio_sha2_init(SHA_512);
|
84
|
-
fio_random_data(&sha2);
|
85
|
-
fio_sha2_result(&sha2);
|
86
|
-
return *((uint32_t *)sha2.buffer);
|
87
|
-
}
|
88
|
-
|
89
|
-
uint64_t fio_rand64(void) {
|
90
|
-
sha2_s sha2 = fio_sha2_init(SHA_512);
|
91
|
-
fio_random_data(&sha2);
|
92
|
-
fio_sha2_result(&sha2);
|
93
|
-
return *((uint64_t *)sha2.buffer);
|
94
|
-
}
|
95
|
-
|
96
|
-
void fio_rand_bytes(void *target, size_t length) {
|
97
|
-
sha2_s sha2 = fio_sha2_init(SHA_512);
|
98
|
-
fio_random_data(&sha2);
|
99
|
-
fio_sha2_result(&sha2);
|
100
|
-
|
101
|
-
while (length >= 64) {
|
102
|
-
memcpy(target, sha2.digest.str, 64);
|
103
|
-
length -= 64;
|
104
|
-
target = (void *)((uintptr_t)target + 64);
|
105
|
-
fio_random_data(&sha2);
|
106
|
-
fio_sha2_result(&sha2);
|
107
|
-
}
|
108
|
-
if (length >= 32) {
|
109
|
-
memcpy(target, sha2.digest.str, 32);
|
110
|
-
length -= 32;
|
111
|
-
target = (void *)((uintptr_t)target + 32);
|
112
|
-
fio_random_data(&sha2);
|
113
|
-
fio_sha2_result(&sha2);
|
114
|
-
}
|
115
|
-
if (length >= 16) {
|
116
|
-
memcpy(target, sha2.digest.str, 16);
|
117
|
-
length -= 16;
|
118
|
-
target = (void *)((uintptr_t)target + 16);
|
119
|
-
fio_random_data(&sha2);
|
120
|
-
fio_sha2_result(&sha2);
|
121
|
-
}
|
122
|
-
if (length >= 8) {
|
123
|
-
memcpy(target, sha2.digest.str, 8);
|
124
|
-
length -= 8;
|
125
|
-
target = (void *)((uintptr_t)target + 8);
|
126
|
-
fio_random_data(&sha2);
|
127
|
-
fio_sha2_result(&sha2);
|
128
|
-
}
|
129
|
-
while (length) {
|
130
|
-
*((uint8_t *)target) = sha2.digest.str[length];
|
131
|
-
target = (void *)((uintptr_t)target + 1);
|
132
|
-
--length;
|
133
|
-
}
|
134
|
-
}
|
135
|
-
|
136
|
-
#else
|
137
|
-
/* ***************************************************************************
|
138
|
-
Unix Random Engine (use built in machine)
|
139
|
-
*/
|
140
|
-
#include <errno.h>
|
141
|
-
#include <fcntl.h>
|
142
|
-
#include <pthread.h>
|
143
|
-
#include <unistd.h>
|
144
|
-
|
145
|
-
/* ***************************************************************************
|
146
|
-
Machine specific changes
|
147
|
-
*/
|
148
|
-
// #ifdef __linux__
|
149
|
-
// #undef bswap16
|
150
|
-
// #undef bswap32
|
151
|
-
// #undef bswap64
|
152
|
-
// #include <machine/bswap.h>
|
153
|
-
// #endif
|
154
|
-
#ifdef HAVE_X86Intrin
|
155
|
-
// #undef bswap16
|
156
|
-
/*
|
157
|
-
#undef bswap32
|
158
|
-
#define bswap32(i) \
|
159
|
-
{ __asm__("bswap %k0" : "+r"(i) :); }
|
160
|
-
*/
|
161
|
-
#undef bswap64
|
162
|
-
#define bswap64(i) \
|
163
|
-
{ __asm__("bswapq %0" : "+r"(i) :); }
|
164
|
-
|
165
|
-
// shadow sched_yield as _mm_pause for spinwait
|
166
|
-
#define sched_yield() _mm_pause()
|
167
|
-
#endif
|
168
|
-
|
169
|
-
/* ***************************************************************************
|
170
|
-
Random fd
|
171
|
-
***************************************************************************** */
|
172
|
-
|
173
|
-
/* rand generator management */
|
174
|
-
static int fio_rand_fd_ = -1;
|
175
|
-
static void close_rand_fd(void) {
|
176
|
-
if (fio_rand_fd_ >= 0)
|
177
|
-
close(fio_rand_fd_);
|
178
|
-
fio_rand_fd_ = -1;
|
179
|
-
}
|
180
|
-
static void init_rand_fd(void) {
|
181
|
-
if (fio_rand_fd_ < 0) {
|
182
|
-
while ((fio_rand_fd_ = open("/dev/urandom", O_RDONLY)) == -1) {
|
183
|
-
if (errno == ENXIO) {
|
184
|
-
perror("FATAL ERROR: caanot initiate random generator");
|
185
|
-
exit(-1);
|
186
|
-
}
|
187
|
-
sched_yield();
|
188
|
-
}
|
189
|
-
}
|
190
|
-
atexit(close_rand_fd);
|
191
|
-
}
|
192
|
-
|
193
|
-
/* ***************************************************************************
|
194
|
-
Random API ... (why is this not a system call?)
|
195
|
-
***************************************************************************** */
|
196
|
-
|
197
|
-
/* rand function template */
|
198
|
-
#define MAKE_RAND_FUNC(type, func_name) \
|
199
|
-
type func_name(void) { \
|
200
|
-
if (fio_rand_fd_ < 0) \
|
201
|
-
init_rand_fd(); \
|
202
|
-
type ret; \
|
203
|
-
while (read(fio_rand_fd_, &ret, sizeof(type)) < 0) \
|
204
|
-
sched_yield(); \
|
205
|
-
return ret; \
|
206
|
-
}
|
207
|
-
/* rand functions */
|
208
|
-
MAKE_RAND_FUNC(uint32_t, fio_rand32)
|
209
|
-
MAKE_RAND_FUNC(uint64_t, fio_rand64)
|
210
|
-
/* clear template */
|
211
|
-
#undef MAKE_RAND_FUNC
|
212
|
-
|
213
|
-
void fio_rand_bytes(void *target, size_t length) {
|
214
|
-
if (fio_rand_fd_ < 0)
|
215
|
-
init_rand_fd();
|
216
|
-
while (read(fio_rand_fd_, target, length) < 0)
|
217
|
-
sched_yield();
|
218
|
-
}
|
219
|
-
#endif /* Unix Random */
|
220
|
-
|
221
|
-
/*******************************************************************************
|
222
|
-
Random Testing
|
223
|
-
***************************************************************************** */
|
224
|
-
#if DEBUG
|
225
|
-
void fio_random_test(void) {
|
226
|
-
uint64_t buffer[8];
|
227
|
-
clock_t start, end;
|
228
|
-
fio_rand64();
|
229
|
-
start = clock();
|
230
|
-
for (size_t i = 0; i < 100000; i++) {
|
231
|
-
buffer[i & 7] = fio_rand64();
|
232
|
-
}
|
233
|
-
end = clock();
|
234
|
-
fprintf(stderr,
|
235
|
-
"+ Random generator available\n+ created 100K X 64bits "
|
236
|
-
"Random %lu CPU clock count\n",
|
237
|
-
end - start);
|
238
|
-
start = clock();
|
239
|
-
for (size_t i = 0; i < 100000; i++) {
|
240
|
-
fio_rand_bytes(buffer, 64);
|
241
|
-
}
|
242
|
-
end = clock();
|
243
|
-
fprintf(stderr,
|
244
|
-
"+ created 100K X 512bits "
|
245
|
-
"Random %lu CPU clock count\n",
|
246
|
-
end - start);
|
247
|
-
}
|
248
|
-
#endif
|
data/ext/iodine/fio_random.h
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz segev, 2016-2017
|
3
|
-
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
|
-
of), which might be subject to their own licenses.
|
5
|
-
|
6
|
-
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
-
*/
|
8
|
-
#ifndef fio_RANDOM_H
|
9
|
-
#define fio_RANDOM_H
|
10
|
-
/* *****************************************************************************
|
11
|
-
C++ extern
|
12
|
-
*/
|
13
|
-
|
14
|
-
#include <stdint.h>
|
15
|
-
#include <stdlib.h>
|
16
|
-
|
17
|
-
#if defined(__cplusplus)
|
18
|
-
extern "C" {
|
19
|
-
#endif
|
20
|
-
|
21
|
-
/* ***************************************************************************
|
22
|
-
Random stuff... (why is this not a system call?)
|
23
|
-
*/
|
24
|
-
|
25
|
-
/** returns 32 random bits. */
|
26
|
-
uint32_t fio_rand32(void);
|
27
|
-
|
28
|
-
/** returns 64 random bits. */
|
29
|
-
uint64_t fio_rand64(void);
|
30
|
-
|
31
|
-
/** returns a variable length string of random bytes. */
|
32
|
-
void fio_rand_bytes(void *target, size_t length);
|
33
|
-
|
34
|
-
#if DEBUG
|
35
|
-
void fio_random_test(void);
|
36
|
-
#endif
|
37
|
-
|
38
|
-
/* *****************************************************************************
|
39
|
-
C++ extern finish
|
40
|
-
*/
|
41
|
-
#if defined(__cplusplus)
|
42
|
-
}
|
43
|
-
#endif
|
44
|
-
|
45
|
-
#endif
|
data/ext/iodine/fio_sha1.c
DELETED
@@ -1,362 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz segev, 2016-2017
|
3
|
-
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
|
-
of), which might be subject to their own licenses.
|
5
|
-
|
6
|
-
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
-
*/
|
8
|
-
#ifndef _GNU_SOURCE
|
9
|
-
#define _GNU_SOURCE
|
10
|
-
#endif
|
11
|
-
#include "fio_sha1.h"
|
12
|
-
|
13
|
-
#include <string.h>
|
14
|
-
|
15
|
-
/*****************************************************************************
|
16
|
-
Useful Macros - Not all of them are used here, but it's a copy-paste convenience
|
17
|
-
*/
|
18
|
-
|
19
|
-
/** 32Bit left rotation, inlined. */
|
20
|
-
#define left_rotate32(i, bits) \
|
21
|
-
(((uint32_t)(i) << (bits)) | ((uint32_t)(i) >> (32 - (bits))))
|
22
|
-
/** 32Bit right rotation, inlined. */
|
23
|
-
#define right_rotate32(i, bits) \
|
24
|
-
(((uint32_t)(i) >> (bits)) | ((uint32_t)(i) << (32 - (bits))))
|
25
|
-
/** 64Bit left rotation, inlined. */
|
26
|
-
#define left_rotate64(i, bits) \
|
27
|
-
(((uint64_t)(i) << (bits)) | ((uint64_t)(i) >> (64 - (bits))))
|
28
|
-
/** 64Bit right rotation, inlined. */
|
29
|
-
#define right_rotate64(i, bits) \
|
30
|
-
(((uint64_t)(i) >> (bits)) | ((uint64_t)(i) << (64 - (bits))))
|
31
|
-
/** unknown size element - left rotation, inlined. */
|
32
|
-
#define left_rotate(i, bits) (((i) << (bits)) | ((i) >> (sizeof((i)) - (bits))))
|
33
|
-
/** unknown size element - right rotation, inlined. */
|
34
|
-
#define right_rotate(i, bits) \
|
35
|
-
(((i) >> (bits)) | ((i) << (sizeof((i)) - (bits))))
|
36
|
-
/** inplace byte swap 16 bit integer */
|
37
|
-
#define bswap16(i) \
|
38
|
-
do { \
|
39
|
-
(i) = (((i)&0xFFU) << 8) | (((i)&0xFF00U) >> 8); \
|
40
|
-
} while (0);
|
41
|
-
/** inplace byte swap 32 bit integer */
|
42
|
-
#define bswap32(i) \
|
43
|
-
do { \
|
44
|
-
(i) = (((i)&0xFFUL) << 24) | (((i)&0xFF00UL) << 8) | \
|
45
|
-
(((i)&0xFF0000UL) >> 8) | (((i)&0xFF000000UL) >> 24); \
|
46
|
-
} while (0);
|
47
|
-
/** inplace byte swap 64 bit integer */
|
48
|
-
#define bswap64(i) \
|
49
|
-
do { \
|
50
|
-
(i) = (((i)&0xFFULL) << 56) | (((i)&0xFF00ULL) << 40) | \
|
51
|
-
(((i)&0xFF0000ULL) << 24) | (((i)&0xFF000000ULL) << 8) | \
|
52
|
-
(((i)&0xFF00000000ULL) >> 8) | (((i)&0xFF0000000000ULL) >> 24) | \
|
53
|
-
(((i)&0xFF000000000000ULL) >> 40) | \
|
54
|
-
(((i)&0xFF00000000000000ULL) >> 56); \
|
55
|
-
} while (0);
|
56
|
-
|
57
|
-
static const uint8_t sha1_padding[64] = {0x80, 0};
|
58
|
-
|
59
|
-
#ifdef __BIG_ENDIAN__
|
60
|
-
/** Converts a 4 byte string to a uint32_t word. careful with alignment! */
|
61
|
-
#define str2word(c) (*((uint32_t *)(c)))
|
62
|
-
#else
|
63
|
-
/**
|
64
|
-
Converts a 4 byte string to a Big Endian uint32_t word. (ignores alignment!)
|
65
|
-
*/
|
66
|
-
#define str2word(c) \
|
67
|
-
(((*((uint32_t *)(c))) & 0xFFUL) << 24) | \
|
68
|
-
(((*((uint32_t *)(c))) & 0xFF00UL) << 8) | \
|
69
|
-
(((*((uint32_t *)(c))) & 0xFF0000UL) >> 8) | \
|
70
|
-
(((*((uint32_t *)(c))) & 0xFF000000UL) >> 24)
|
71
|
-
#endif
|
72
|
-
/**
|
73
|
-
Process the buffer once full.
|
74
|
-
*/
|
75
|
-
static inline void perform_all_rounds(sha1_s *s, const uint8_t *buffer) {
|
76
|
-
/* collect data */
|
77
|
-
uint32_t a = s->digest.i[0];
|
78
|
-
uint32_t b = s->digest.i[1];
|
79
|
-
uint32_t c = s->digest.i[2];
|
80
|
-
uint32_t d = s->digest.i[3];
|
81
|
-
uint32_t e = s->digest.i[4];
|
82
|
-
uint32_t t, w[16];
|
83
|
-
/* copy data to words, performing byte swapping as needed */
|
84
|
-
w[0] = str2word(buffer);
|
85
|
-
w[1] = str2word(buffer + 4);
|
86
|
-
w[2] = str2word(buffer + 8);
|
87
|
-
w[3] = str2word(buffer + 12);
|
88
|
-
w[4] = str2word(buffer + 16);
|
89
|
-
w[5] = str2word(buffer + 20);
|
90
|
-
w[6] = str2word(buffer + 24);
|
91
|
-
w[7] = str2word(buffer + 28);
|
92
|
-
w[8] = str2word(buffer + 32);
|
93
|
-
w[9] = str2word(buffer + 36);
|
94
|
-
w[10] = str2word(buffer + 40);
|
95
|
-
w[11] = str2word(buffer + 44);
|
96
|
-
w[12] = str2word(buffer + 48);
|
97
|
-
w[13] = str2word(buffer + 52);
|
98
|
-
w[14] = str2word(buffer + 56);
|
99
|
-
w[15] = str2word(buffer + 60);
|
100
|
-
/* perform rounds */
|
101
|
-
#define perform_single_round(num) \
|
102
|
-
t = left_rotate32(a, 5) + e + w[num] + ((b & c) | ((~b) & d)) + 0x5A827999; \
|
103
|
-
e = d; \
|
104
|
-
d = c; \
|
105
|
-
c = left_rotate32(b, 30); \
|
106
|
-
b = a; \
|
107
|
-
a = t;
|
108
|
-
|
109
|
-
#define perform_four_rounds(i) \
|
110
|
-
perform_single_round(i); \
|
111
|
-
perform_single_round(i + 1); \
|
112
|
-
perform_single_round(i + 2); \
|
113
|
-
perform_single_round(i + 3);
|
114
|
-
|
115
|
-
perform_four_rounds(0);
|
116
|
-
perform_four_rounds(4);
|
117
|
-
perform_four_rounds(8);
|
118
|
-
perform_four_rounds(12);
|
119
|
-
|
120
|
-
#undef perform_single_round
|
121
|
-
#define perform_single_round(i) \
|
122
|
-
w[(i)&15] = left_rotate32((w[(i - 3) & 15] ^ w[(i - 8) & 15] ^ \
|
123
|
-
w[(i - 14) & 15] ^ w[(i - 16) & 15]), \
|
124
|
-
1); \
|
125
|
-
t = left_rotate32(a, 5) + e + w[(i)&15] + ((b & c) | ((~b) & d)) + \
|
126
|
-
0x5A827999; \
|
127
|
-
e = d; \
|
128
|
-
d = c; \
|
129
|
-
c = left_rotate32(b, 30); \
|
130
|
-
b = a; \
|
131
|
-
a = t;
|
132
|
-
|
133
|
-
perform_four_rounds(16);
|
134
|
-
|
135
|
-
#undef perform_single_round
|
136
|
-
#define perform_single_round(i) \
|
137
|
-
w[(i)&15] = left_rotate32((w[(i - 3) & 15] ^ w[(i - 8) & 15] ^ \
|
138
|
-
w[(i - 14) & 15] ^ w[(i - 16) & 15]), \
|
139
|
-
1); \
|
140
|
-
t = left_rotate32(a, 5) + e + w[(i)&15] + (b ^ c ^ d) + 0x6ED9EBA1; \
|
141
|
-
e = d; \
|
142
|
-
d = c; \
|
143
|
-
c = left_rotate32(b, 30); \
|
144
|
-
b = a; \
|
145
|
-
a = t;
|
146
|
-
|
147
|
-
perform_four_rounds(20);
|
148
|
-
perform_four_rounds(24);
|
149
|
-
perform_four_rounds(28);
|
150
|
-
perform_four_rounds(32);
|
151
|
-
perform_four_rounds(36);
|
152
|
-
|
153
|
-
#undef perform_single_round
|
154
|
-
#define perform_single_round(i) \
|
155
|
-
w[(i)&15] = left_rotate32((w[(i - 3) & 15] ^ w[(i - 8) & 15] ^ \
|
156
|
-
w[(i - 14) & 15] ^ w[(i - 16) & 15]), \
|
157
|
-
1); \
|
158
|
-
t = left_rotate32(a, 5) + e + w[(i)&15] + ((b & (c | d)) | (c & d)) + \
|
159
|
-
0x8F1BBCDC; \
|
160
|
-
e = d; \
|
161
|
-
d = c; \
|
162
|
-
c = left_rotate32(b, 30); \
|
163
|
-
b = a; \
|
164
|
-
a = t;
|
165
|
-
|
166
|
-
perform_four_rounds(40);
|
167
|
-
perform_four_rounds(44);
|
168
|
-
perform_four_rounds(48);
|
169
|
-
perform_four_rounds(52);
|
170
|
-
perform_four_rounds(56);
|
171
|
-
#undef perform_single_round
|
172
|
-
#define perform_single_round(i) \
|
173
|
-
w[(i)&15] = left_rotate32((w[(i - 3) & 15] ^ w[(i - 8) & 15] ^ \
|
174
|
-
w[(i - 14) & 15] ^ w[(i - 16) & 15]), \
|
175
|
-
1); \
|
176
|
-
t = left_rotate32(a, 5) + e + w[(i)&15] + (b ^ c ^ d) + 0xCA62C1D6; \
|
177
|
-
e = d; \
|
178
|
-
d = c; \
|
179
|
-
c = left_rotate32(b, 30); \
|
180
|
-
b = a; \
|
181
|
-
a = t;
|
182
|
-
perform_four_rounds(60);
|
183
|
-
perform_four_rounds(64);
|
184
|
-
perform_four_rounds(68);
|
185
|
-
perform_four_rounds(72);
|
186
|
-
perform_four_rounds(76);
|
187
|
-
|
188
|
-
/* store data */
|
189
|
-
s->digest.i[4] += e;
|
190
|
-
s->digest.i[3] += d;
|
191
|
-
s->digest.i[2] += c;
|
192
|
-
s->digest.i[1] += b;
|
193
|
-
s->digest.i[0] += a;
|
194
|
-
}
|
195
|
-
|
196
|
-
/* ***************************************************************************
|
197
|
-
SHA-1 hashing
|
198
|
-
*/
|
199
|
-
|
200
|
-
/**
|
201
|
-
Initialize or reset the `sha1` object. This must be performed before hashing
|
202
|
-
data using sha1.
|
203
|
-
*/
|
204
|
-
sha1_s fio_sha1_init(void) {
|
205
|
-
return (sha1_s){.digest.i[0] = 0x67452301,
|
206
|
-
.digest.i[1] = 0xefcdab89,
|
207
|
-
.digest.i[2] = 0x98badcfe,
|
208
|
-
.digest.i[3] = 0x10325476,
|
209
|
-
.digest.i[4] = 0xc3d2e1f0};
|
210
|
-
}
|
211
|
-
|
212
|
-
/**
|
213
|
-
Writes data to the sha1 buffer.
|
214
|
-
*/
|
215
|
-
void fio_sha1_write(sha1_s *s, const void *data, size_t len) {
|
216
|
-
size_t in_buffer = s->length & 63;
|
217
|
-
size_t partial = 64 - in_buffer;
|
218
|
-
s->length += len;
|
219
|
-
if (partial > len) {
|
220
|
-
memcpy(s->buffer + in_buffer, data, len);
|
221
|
-
return;
|
222
|
-
}
|
223
|
-
if (in_buffer) {
|
224
|
-
memcpy(s->buffer + in_buffer, data, partial);
|
225
|
-
len -= partial;
|
226
|
-
data = (void *)((uintptr_t)data + partial);
|
227
|
-
perform_all_rounds(s, s->buffer);
|
228
|
-
}
|
229
|
-
while (len >= 64) {
|
230
|
-
perform_all_rounds(s, data);
|
231
|
-
data = (void *)((uintptr_t)data + 64);
|
232
|
-
len -= 64;
|
233
|
-
}
|
234
|
-
if (len) {
|
235
|
-
memcpy(s->buffer + in_buffer, data, len);
|
236
|
-
}
|
237
|
-
return;
|
238
|
-
}
|
239
|
-
|
240
|
-
char *fio_sha1_result(sha1_s *s) {
|
241
|
-
size_t in_buffer = s->length & 63;
|
242
|
-
if (in_buffer > 55) {
|
243
|
-
memcpy(s->buffer + in_buffer, sha1_padding, 64 - in_buffer);
|
244
|
-
perform_all_rounds(s, s->buffer);
|
245
|
-
memcpy(s->buffer, sha1_padding + 1, 56);
|
246
|
-
} else if (in_buffer != 55) {
|
247
|
-
memcpy(s->buffer + in_buffer, sha1_padding, 56 - in_buffer);
|
248
|
-
} else {
|
249
|
-
s->buffer[55] = sha1_padding[0];
|
250
|
-
}
|
251
|
-
/* store the length in BITS - alignment should be promised by struct */
|
252
|
-
/* this must the number in BITS, encoded as a BIG ENDIAN 64 bit number */
|
253
|
-
uint64_t *len = (uint64_t *)(s->buffer + 56);
|
254
|
-
*len = s->length << 3;
|
255
|
-
#ifndef __BIG_ENDIAN__
|
256
|
-
bswap64(*len);
|
257
|
-
#endif
|
258
|
-
perform_all_rounds(s, s->buffer);
|
259
|
-
|
260
|
-
/* change back to little endian, if required */
|
261
|
-
#ifndef __BIG_ENDIAN__
|
262
|
-
bswap32(s->digest.i[0]);
|
263
|
-
bswap32(s->digest.i[1]);
|
264
|
-
bswap32(s->digest.i[2]);
|
265
|
-
bswap32(s->digest.i[3]);
|
266
|
-
bswap32(s->digest.i[4]);
|
267
|
-
#endif
|
268
|
-
// fprintf(stderr, "result requested, in hex, is:");
|
269
|
-
// for (size_t i = 0; i < 20; i++)
|
270
|
-
// fprintf(stderr, "%02x", (unsigned int)(s->digest.str[i] & 0xFF));
|
271
|
-
// fprintf(stderr, "\r\n");
|
272
|
-
return (char *)s->digest.str;
|
273
|
-
}
|
274
|
-
|
275
|
-
/*******************************************************************************
|
276
|
-
SHA-1 testing
|
277
|
-
*/
|
278
|
-
#if defined(DEBUG) && DEBUG == 1
|
279
|
-
#include <stdio.h>
|
280
|
-
#include <time.h>
|
281
|
-
|
282
|
-
// clang-format off
|
283
|
-
#if defined(HAVE_OPENSSL)
|
284
|
-
# include <openssl/sha.h>
|
285
|
-
#endif
|
286
|
-
// clang-format on
|
287
|
-
|
288
|
-
void fio_sha1_test(void) {
|
289
|
-
struct {
|
290
|
-
char *str;
|
291
|
-
uint8_t hash[21];
|
292
|
-
} sets[] = {
|
293
|
-
{"The quick brown fox jumps over the lazy dog",
|
294
|
-
{0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, 0x9e,
|
295
|
-
0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12, 0}}, // a set with
|
296
|
-
// a string
|
297
|
-
{"",
|
298
|
-
{
|
299
|
-
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
|
300
|
-
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09,
|
301
|
-
}}, // an empty set
|
302
|
-
{NULL, {0}} // Stop
|
303
|
-
};
|
304
|
-
int i = 0;
|
305
|
-
sha1_s sha1;
|
306
|
-
fprintf(stderr, "===================================\n");
|
307
|
-
fprintf(stderr, "fio SHA-1 struct size: %zu\n", sizeof(sha1_s));
|
308
|
-
fprintf(stderr, "+ fio");
|
309
|
-
while (sets[i].str) {
|
310
|
-
sha1 = fio_sha1_init();
|
311
|
-
fio_sha1_write(&sha1, sets[i].str, strlen(sets[i].str));
|
312
|
-
if (strcmp(fio_sha1_result(&sha1), (char *)sets[i].hash)) {
|
313
|
-
fprintf(stderr, ":\n--- fio SHA-1 Test FAILED!\nstring: %s\nexpected: ",
|
314
|
-
sets[i].str);
|
315
|
-
char *p = (char *)sets[i].hash;
|
316
|
-
while (*p)
|
317
|
-
fprintf(stderr, "%02x", *(p++) & 0xFF);
|
318
|
-
fprintf(stderr, "\ngot: ");
|
319
|
-
p = fio_sha1_result(&sha1);
|
320
|
-
while (*p)
|
321
|
-
fprintf(stderr, "%02x", *(p++) & 0xFF);
|
322
|
-
fprintf(stderr, "\n");
|
323
|
-
return;
|
324
|
-
}
|
325
|
-
i++;
|
326
|
-
}
|
327
|
-
fprintf(stderr, " SHA-1 passed.\n");
|
328
|
-
|
329
|
-
#ifdef HAVE_OPENSSL
|
330
|
-
fprintf(stderr, "===================================\n");
|
331
|
-
fprintf(stderr, "fio SHA-1 struct size: %lu\n",
|
332
|
-
(unsigned long)sizeof(sha1_s));
|
333
|
-
fprintf(stderr, "OpenSSL SHA-1 struct size: %lu\n",
|
334
|
-
(unsigned long)sizeof(SHA_CTX));
|
335
|
-
fprintf(stderr, "===================================\n");
|
336
|
-
|
337
|
-
unsigned char hash[SHA512_DIGEST_LENGTH + 1];
|
338
|
-
hash[SHA512_DIGEST_LENGTH] = 0;
|
339
|
-
clock_t start;
|
340
|
-
start = clock();
|
341
|
-
for (i = 0; i < 100000; i++) {
|
342
|
-
sha1 = fio_sha1_init();
|
343
|
-
fio_sha1_write(&sha1, "The quick brown fox jumps over the lazy dog ", 43);
|
344
|
-
fio_sha1_result(&sha1);
|
345
|
-
}
|
346
|
-
fprintf(stderr, "fio 100K SHA-1: %lf\n",
|
347
|
-
(double)(clock() - start) / CLOCKS_PER_SEC);
|
348
|
-
|
349
|
-
hash[SHA_DIGEST_LENGTH] = 0;
|
350
|
-
SHA_CTX o_sh1;
|
351
|
-
start = clock();
|
352
|
-
for (i = 0; i < 100000; i++) {
|
353
|
-
SHA1_Init(&o_sh1);
|
354
|
-
SHA1_Update(&o_sh1, "The quick brown fox jumps over the lazy dog", 43);
|
355
|
-
SHA1_Final(hash, &o_sh1);
|
356
|
-
}
|
357
|
-
fprintf(stderr, "OpenSSL 100K SHA-1: %lf\n",
|
358
|
-
(double)(clock() - start) / CLOCKS_PER_SEC);
|
359
|
-
|
360
|
-
#endif
|
361
|
-
}
|
362
|
-
#endif
|