ratomic 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/ratomic/counter.h +45 -0
- data/ext/ratomic/extconf.rb +16 -0
- data/ext/ratomic/fixed-size-object-pool.h +76 -0
- data/ext/ratomic/hashmap.h +74 -0
- data/ext/ratomic/mpmc-queue.h +68 -0
- data/ext/ratomic/ratomic.c +16 -0
- data/lib/ratomic/ratomic.bundle +0 -0
- data/lib/ratomic/version.rb +5 -0
- data/lib/ratomic.rb +68 -0
- data/ratomic.gemspec +40 -0
- data/rs/Cargo.lock +196 -0
- data/rs/Cargo.toml +26 -0
- data/rs/cbindgen.toml +12 -0
- data/rs/rust-atomics.h +89 -0
- data/rs/src/bin/mpmc_queue.rs +89 -0
- data/rs/src/counter.rs +57 -0
- data/rs/src/fixed_size_object_pool.rs +120 -0
- data/rs/src/gc_guard.rs +88 -0
- data/rs/src/hashmap.rs +129 -0
- data/rs/src/lib.rs +23 -0
- data/rs/src/mpmc_queue.rs +231 -0
- data/rs/src/sem.rs +75 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 997065e8a812fe84d836e06402ba1250d54116a251aa220cc255799f41c1da57
|
4
|
+
data.tar.gz: c0b6ea1afbf4d04b4638150a63063ad63e54d52aa0ee4ef4a6816d3240ec74a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a085aa02d2ff513781b1ef44d89505f9bc397c254840126d3d8a2560b6c293257ff43b49c0c96450c915c1494d440e6272b6efb704a2477a0d1a60fd1ca6cd55
|
7
|
+
data.tar.gz: 92439604f4f93a306d6b672db005f1864d1afad8c9c5cd8b7e64dfb045c941ea576e6b45802647d5c32618db1e461715a8e27f7246028acfa5438c621624b331
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#include "rust-atomics.h"
|
2
|
+
#include <ruby.h>
|
3
|
+
|
4
|
+
const rb_data_type_t atomic_counter_data = {
|
5
|
+
.function = {.dfree = RUBY_DEFAULT_FREE},
|
6
|
+
.flags = RUBY_TYPED_FROZEN_SHAREABLE};
|
7
|
+
|
8
|
+
VALUE rb_atomic_counter_alloc(VALUE klass) {
|
9
|
+
atomic_counter_t *counter;
|
10
|
+
TypedData_Make_Struct0(obj, klass, atomic_counter_t, ATOMIC_COUNTER_SIZE,
|
11
|
+
&atomic_counter_data, counter);
|
12
|
+
atomic_counter_init(counter, 0);
|
13
|
+
VALUE rb_cRactor = rb_const_get(rb_cObject, rb_intern("Ractor"));
|
14
|
+
rb_funcall(rb_cRactor, rb_intern("make_shareable"), 1, obj);
|
15
|
+
return obj;
|
16
|
+
}
|
17
|
+
|
18
|
+
VALUE rb_atomic_counter_increment(VALUE self, VALUE amt) {
|
19
|
+
atomic_counter_t *counter;
|
20
|
+
TypedData_Get_Struct(self, atomic_counter_t, &atomic_counter_data, counter);
|
21
|
+
atomic_counter_increment(counter, FIX2LONG(amt));
|
22
|
+
return Qnil;
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE rb_atomic_counter_decrement(VALUE self, VALUE amt) {
|
26
|
+
atomic_counter_t *counter;
|
27
|
+
TypedData_Get_Struct(self, atomic_counter_t, &atomic_counter_data, counter);
|
28
|
+
atomic_counter_decrement(counter, FIX2LONG(amt));
|
29
|
+
return Qnil;
|
30
|
+
}
|
31
|
+
|
32
|
+
VALUE rb_atomic_counter_read(VALUE self) {
|
33
|
+
atomic_counter_t *counter;
|
34
|
+
TypedData_Get_Struct(self, atomic_counter_t, &atomic_counter_data, counter);
|
35
|
+
return LONG2FIX(atomic_counter_read(counter));
|
36
|
+
}
|
37
|
+
|
38
|
+
static void init_counter(VALUE rb_mRoot) {
|
39
|
+
VALUE rb_cAtomicCounter =
|
40
|
+
rb_define_class_under(rb_mRoot, "Counter", rb_cObject);
|
41
|
+
rb_define_alloc_func(rb_cAtomicCounter, rb_atomic_counter_alloc);
|
42
|
+
rb_define_method(rb_cAtomicCounter, "increment", rb_atomic_counter_increment, 1);
|
43
|
+
rb_define_method(rb_cAtomicCounter, "decrement", rb_atomic_counter_decrement, 1);
|
44
|
+
rb_define_method(rb_cAtomicCounter, "read", rb_atomic_counter_read, 0);
|
45
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mkmf"
|
4
|
+
|
5
|
+
# Makes all symbols private by default to avoid unintended conflict
|
6
|
+
# with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
|
7
|
+
# selectively, or entirely remove this flag.
|
8
|
+
append_cflags("-fvisibility=hidden")
|
9
|
+
|
10
|
+
rust_atomics_path = File.expand_path("../../../rs", __FILE__)
|
11
|
+
# rubocop:disable Style/GlobalVars
|
12
|
+
$INCFLAGS << " -I#{rust_atomics_path}"
|
13
|
+
$LDFLAGS << " -L#{rust_atomics_path}/target/release -lrust_atomics"
|
14
|
+
# rubocop:enable Style/GlobalVars
|
15
|
+
|
16
|
+
create_makefile("ratomic/ratomic")
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#include "rust-atomics.h"
|
2
|
+
#include <ruby.h>
|
3
|
+
|
4
|
+
void rb_fixed_size_object_pool_mark(void *);
|
5
|
+
void rb_fixed_size_object_pool_free(void *);
|
6
|
+
|
7
|
+
const rb_data_type_t fixed_size_object_pool_data = {
|
8
|
+
.function = {.dfree = rb_fixed_size_object_pool_free,
|
9
|
+
.dmark = rb_fixed_size_object_pool_mark},
|
10
|
+
.flags = RUBY_TYPED_FROZEN_SHAREABLE};
|
11
|
+
|
12
|
+
void rb_fixed_size_object_pool_free(void *ptr) {
|
13
|
+
fixed_size_object_pool_t *pool = ptr;
|
14
|
+
fixed_size_object_pool_drop(pool);
|
15
|
+
}
|
16
|
+
|
17
|
+
void rb_fixed_size_object_pool_mark(void *ptr) {
|
18
|
+
fixed_size_object_pool_t *pool = ptr;
|
19
|
+
fixed_size_object_pool_mark(pool, rb_gc_mark);
|
20
|
+
}
|
21
|
+
|
22
|
+
VALUE rb_fixed_size_object_pool_alloc(VALUE klass) {
|
23
|
+
fixed_size_object_pool_t *pool;
|
24
|
+
TypedData_Make_Struct0(obj, klass, fixed_size_object_pool_t,
|
25
|
+
FIXED_SIZE_OBJECT_POOL_SIZE,
|
26
|
+
&fixed_size_object_pool_data, pool);
|
27
|
+
fixed_size_object_pool_alloc(pool);
|
28
|
+
VALUE rb_cRactor = rb_const_get(rb_cObject, rb_intern("Ractor"));
|
29
|
+
rb_funcall(rb_cRactor, rb_intern("make_shareable"), 1, obj);
|
30
|
+
return obj;
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE rb_fixed_size_object_pool_initialize(VALUE self, VALUE size,
|
34
|
+
VALUE timeout_in_ms) {
|
35
|
+
fixed_size_object_pool_t *pool;
|
36
|
+
TypedData_Get_Struct(self, fixed_size_object_pool_t,
|
37
|
+
&fixed_size_object_pool_data, pool);
|
38
|
+
fixed_size_object_pool_init(pool, FIX2LONG(size), FIX2LONG(timeout_in_ms),
|
39
|
+
rb_yield);
|
40
|
+
return Qnil;
|
41
|
+
}
|
42
|
+
|
43
|
+
VALUE rb_fixed_size_object_pool_checkout(VALUE self) {
|
44
|
+
fixed_size_object_pool_t *pool;
|
45
|
+
TypedData_Get_Struct(self, fixed_size_object_pool_t,
|
46
|
+
&fixed_size_object_pool_data, pool);
|
47
|
+
PooledItem pooled = fixed_size_object_pool_checkout(pool);
|
48
|
+
if (pooled.idx == 0 && pooled.rbobj == 0) {
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
VALUE ary = rb_ary_new_capa(2);
|
52
|
+
rb_ary_push(ary, pooled.rbobj);
|
53
|
+
rb_ary_push(ary, LONG2FIX(pooled.idx));
|
54
|
+
return ary;
|
55
|
+
}
|
56
|
+
|
57
|
+
VALUE rb_fixed_size_object_pool_checkin(VALUE self, VALUE idx) {
|
58
|
+
fixed_size_object_pool_t *pool;
|
59
|
+
TypedData_Get_Struct(self, fixed_size_object_pool_t,
|
60
|
+
&fixed_size_object_pool_data, pool);
|
61
|
+
fixed_size_object_pool_checkin(pool, FIX2LONG(idx));
|
62
|
+
return Qnil;
|
63
|
+
}
|
64
|
+
|
65
|
+
static void init_fixed_size_object_pool(VALUE rb_mRoot) {
|
66
|
+
VALUE rb_cFixedSizeObjectPool =
|
67
|
+
rb_define_class_under(rb_mRoot, "FixedSizeObjectPool", rb_cObject);
|
68
|
+
rb_define_alloc_func(rb_cFixedSizeObjectPool,
|
69
|
+
rb_fixed_size_object_pool_alloc);
|
70
|
+
rb_define_method(rb_cFixedSizeObjectPool, "initialize",
|
71
|
+
rb_fixed_size_object_pool_initialize, 2);
|
72
|
+
rb_define_method(rb_cFixedSizeObjectPool, "checkout",
|
73
|
+
rb_fixed_size_object_pool_checkout, 0);
|
74
|
+
rb_define_method(rb_cFixedSizeObjectPool, "checkin",
|
75
|
+
rb_fixed_size_object_pool_checkin, 1);
|
76
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#include "rust-atomics.h"
|
2
|
+
#include <ruby.h>
|
3
|
+
|
4
|
+
void rb_concurrent_hash_map_mark(void *);
|
5
|
+
void rb_concurrent_hash_map_free(void *);
|
6
|
+
|
7
|
+
const rb_data_type_t concurrent_hash_map_data = {
|
8
|
+
.function = {.dfree = rb_concurrent_hash_map_free,
|
9
|
+
.dmark = rb_concurrent_hash_map_mark},
|
10
|
+
.flags = RUBY_TYPED_FROZEN_SHAREABLE};
|
11
|
+
|
12
|
+
void rb_concurrent_hash_map_free(void *ptr) {
|
13
|
+
concurrent_hash_map_t *hashmap = ptr;
|
14
|
+
concurrent_hash_map_drop(hashmap);
|
15
|
+
}
|
16
|
+
|
17
|
+
void rb_concurrent_hash_map_mark(void *ptr) {
|
18
|
+
concurrent_hash_map_t *hashmap = ptr;
|
19
|
+
concurrent_hash_map_mark(hashmap, rb_gc_mark);
|
20
|
+
}
|
21
|
+
|
22
|
+
VALUE rb_concurrent_hash_map_alloc(VALUE klass) {
|
23
|
+
concurrent_hash_map_t *hashmap;
|
24
|
+
TypedData_Make_Struct0(obj, klass, concurrent_hash_map_t,
|
25
|
+
CONCURRENT_HASH_MAP_SIZE, &concurrent_hash_map_data,
|
26
|
+
hashmap);
|
27
|
+
concurrent_hash_map_init(hashmap);
|
28
|
+
VALUE rb_cRactor = rb_const_get(rb_cObject, rb_intern("Ractor"));
|
29
|
+
rb_funcall(rb_cRactor, rb_intern("make_shareable"), 1, obj);
|
30
|
+
return obj;
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE rb_concurrent_hash_map_get(VALUE self, VALUE key) {
|
34
|
+
concurrent_hash_map_t *hashmap;
|
35
|
+
TypedData_Get_Struct(self, concurrent_hash_map_t, &concurrent_hash_map_data,
|
36
|
+
hashmap);
|
37
|
+
return concurrent_hash_map_get(hashmap, key, Qnil);
|
38
|
+
}
|
39
|
+
|
40
|
+
VALUE rb_concurrent_hash_map_set(VALUE self, VALUE key, VALUE value) {
|
41
|
+
concurrent_hash_map_t *hashmap;
|
42
|
+
TypedData_Get_Struct(self, concurrent_hash_map_t, &concurrent_hash_map_data,
|
43
|
+
hashmap);
|
44
|
+
concurrent_hash_map_set(hashmap, key, value);
|
45
|
+
return Qnil;
|
46
|
+
}
|
47
|
+
|
48
|
+
VALUE rb_concurrent_hash_map_clear(VALUE self) {
|
49
|
+
concurrent_hash_map_t *hashmap;
|
50
|
+
TypedData_Get_Struct(self, concurrent_hash_map_t, &concurrent_hash_map_data,
|
51
|
+
hashmap);
|
52
|
+
concurrent_hash_map_clear(hashmap);
|
53
|
+
return Qnil;
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE rb_concurrent_hash_map_fetch_and_modify(VALUE self, VALUE key) {
|
57
|
+
rb_need_block();
|
58
|
+
concurrent_hash_map_t *hashmap;
|
59
|
+
TypedData_Get_Struct(self, concurrent_hash_map_t, &concurrent_hash_map_data,
|
60
|
+
hashmap);
|
61
|
+
concurrent_hash_map_fetch_and_modify(hashmap, key, rb_yield);
|
62
|
+
return Qnil;
|
63
|
+
}
|
64
|
+
|
65
|
+
static void init_hashmap(VALUE rb_mRoot) {
|
66
|
+
VALUE rb_cConcurrentHashMap =
|
67
|
+
rb_define_class_under(rb_mRoot, "ConcurrentHashMap", rb_cObject);
|
68
|
+
rb_define_alloc_func(rb_cConcurrentHashMap, rb_concurrent_hash_map_alloc);
|
69
|
+
rb_define_method(rb_cConcurrentHashMap, "get", rb_concurrent_hash_map_get, 1);
|
70
|
+
rb_define_method(rb_cConcurrentHashMap, "set", rb_concurrent_hash_map_set, 2);
|
71
|
+
rb_define_method(rb_cConcurrentHashMap, "clear", rb_concurrent_hash_map_clear, 0);
|
72
|
+
rb_define_method(rb_cConcurrentHashMap, "fetch_and_modify",
|
73
|
+
rb_concurrent_hash_map_fetch_and_modify, 1);
|
74
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#include "rust-atomics.h"
|
2
|
+
#include <ruby.h>
|
3
|
+
#include <ruby/thread.h>
|
4
|
+
|
5
|
+
void rb_mpmc_queue_mark(void *);
|
6
|
+
void rb_mpmc_queue_free(void *);
|
7
|
+
|
8
|
+
const rb_data_type_t mpmc_queue_data = {
|
9
|
+
.function = {.dfree = rb_mpmc_queue_free, .dmark = rb_mpmc_queue_mark},
|
10
|
+
.flags = RUBY_TYPED_FROZEN_SHAREABLE};
|
11
|
+
|
12
|
+
void rb_mpmc_queue_free(void *ptr) {
|
13
|
+
mpmc_queue_t *queue = ptr;
|
14
|
+
mpmc_queue_drop(queue);
|
15
|
+
}
|
16
|
+
|
17
|
+
void rb_mpmc_queue_mark(void *ptr) {
|
18
|
+
mpmc_queue_t *queue = ptr;
|
19
|
+
mpmc_queue_mark(queue, rb_gc_mark);
|
20
|
+
}
|
21
|
+
|
22
|
+
VALUE rb_mpmc_queue_alloc(VALUE klass) {
|
23
|
+
mpmc_queue_t *queue;
|
24
|
+
TypedData_Make_Struct0(obj, klass, mpmc_queue_t, MPMC_QUEUE_OBJECT_SIZE,
|
25
|
+
&mpmc_queue_data, queue);
|
26
|
+
mpmc_queue_alloc(queue);
|
27
|
+
VALUE rb_cRactor = rb_const_get(rb_cObject, rb_intern("Ractor"));
|
28
|
+
rb_funcall(rb_cRactor, rb_intern("make_shareable"), 1, obj);
|
29
|
+
return obj;
|
30
|
+
}
|
31
|
+
|
32
|
+
VALUE rb_mpmc_queue_initialize(VALUE self, VALUE cap) {
|
33
|
+
mpmc_queue_t *queue;
|
34
|
+
TypedData_Get_Struct(self, mpmc_queue_t, &mpmc_queue_data, queue);
|
35
|
+
mpmc_queue_init(queue, FIX2LONG(cap), Qnil);
|
36
|
+
return Qnil;
|
37
|
+
}
|
38
|
+
|
39
|
+
typedef struct {
|
40
|
+
mpmc_queue_t *queue;
|
41
|
+
VALUE value;
|
42
|
+
} push_payload_t;
|
43
|
+
|
44
|
+
VALUE rb_mpmc_queue_push(VALUE self, VALUE value) {
|
45
|
+
mpmc_queue_t *queue;
|
46
|
+
TypedData_Get_Struct(self, mpmc_queue_t, &mpmc_queue_data, queue);
|
47
|
+
push_payload_t push_payload = {.queue = queue, .value = value};
|
48
|
+
rb_thread_call_without_gvl(mpmc_queue_push, &push_payload, NULL, NULL);
|
49
|
+
return Qtrue;
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE rb_mpmc_queue_pop(VALUE self) {
|
53
|
+
mpmc_queue_t *queue;
|
54
|
+
TypedData_Get_Struct(self, mpmc_queue_t, &mpmc_queue_data, queue);
|
55
|
+
void *ptr = rb_thread_call_without_gvl(mpmc_queue_pop, queue, NULL, NULL);
|
56
|
+
VALUE item = (VALUE)ptr;
|
57
|
+
return item;
|
58
|
+
}
|
59
|
+
|
60
|
+
static void init_mpmc_queue(VALUE rb_mRoot) {
|
61
|
+
VALUE rb_cMpmcQueue =
|
62
|
+
rb_define_class_under(rb_mRoot, "Queue", rb_cObject);
|
63
|
+
rb_define_alloc_func(rb_cMpmcQueue, rb_mpmc_queue_alloc);
|
64
|
+
|
65
|
+
rb_define_method(rb_cMpmcQueue, "initialize", rb_mpmc_queue_initialize, 1);
|
66
|
+
rb_define_method(rb_cMpmcQueue, "push", rb_mpmc_queue_push, 1);
|
67
|
+
rb_define_method(rb_cMpmcQueue, "pop", rb_mpmc_queue_pop, 0);
|
68
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#include "counter.h"
|
2
|
+
#include "fixed-size-object-pool.h"
|
3
|
+
#include "hashmap.h"
|
4
|
+
#include "mpmc-queue.h"
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
RUBY_FUNC_EXPORTED void Init_ratomic(void) {
|
8
|
+
rb_ext_ractor_safe(true);
|
9
|
+
|
10
|
+
VALUE rb_mRoot = rb_define_module("Ratomic");
|
11
|
+
|
12
|
+
init_counter(rb_mRoot);
|
13
|
+
init_hashmap(rb_mRoot);
|
14
|
+
init_fixed_size_object_pool(rb_mRoot);
|
15
|
+
init_mpmc_queue(rb_mRoot);
|
16
|
+
}
|
Binary file
|
data/lib/ratomic.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "ratomic/version"
|
4
|
+
require_relative "ratomic/ratomic"
|
5
|
+
|
6
|
+
module Ratomic
|
7
|
+
class Error < StandardError; end
|
8
|
+
|
9
|
+
##
|
10
|
+
# An atomic counter which can be incremented and decremented
|
11
|
+
# safely by multiple Ractors concurrently.
|
12
|
+
class Counter
|
13
|
+
def value
|
14
|
+
read
|
15
|
+
end
|
16
|
+
|
17
|
+
def inc(amt = 1)
|
18
|
+
raise ArgumentError, "amount must be positive: #{amt}" if amt < 0
|
19
|
+
increment(amt)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dec(amt = 1)
|
23
|
+
raise ArgumentError, "amount must be positive: #{amt}" if amt < 0
|
24
|
+
decrement(amt)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Undefined
|
29
|
+
def inspect
|
30
|
+
"#<Undefined>"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
UNDEFINED = Ractor.make_shareable(Undefined.new)
|
34
|
+
|
35
|
+
class Pool < FixedSizeObjectPool
|
36
|
+
def initialize(size = 5, timeout = 1.0)
|
37
|
+
super(size, (timeout * 1000).to_i)
|
38
|
+
end
|
39
|
+
|
40
|
+
def with
|
41
|
+
obj_and_idx = checkout
|
42
|
+
if obj_and_idx.nil?
|
43
|
+
raise Ratomic::Error, "pool checkout timeout"
|
44
|
+
else
|
45
|
+
yield obj_and_idx[0]
|
46
|
+
end
|
47
|
+
ensure
|
48
|
+
unless obj_and_idx.nil?
|
49
|
+
checkin(obj_and_idx[1])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Map < ConcurrentHashMap
|
55
|
+
def []=(key, value)
|
56
|
+
set(key, value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def [](key)
|
60
|
+
get(key)
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO add as much of the Hash API as possible.
|
64
|
+
# Stretch goal? Support Enumerable if DashMap can safely
|
65
|
+
# iterate.
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/ratomic.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/ratomic/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ratomic"
|
7
|
+
spec.version = Ratomic::VERSION
|
8
|
+
spec.authors = ["Mike Perham"]
|
9
|
+
spec.email = ["mike@perham.net"]
|
10
|
+
|
11
|
+
spec.summary = "Mutable data structures for Ractors"
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = "https://github.com/mperham/ratomic"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.4.0"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/mperham/ratomic"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/mperham/ratomic"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
gemspec = File.basename(__FILE__)
|
24
|
+
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
|
25
|
+
ls.readlines("\x0", chomp: true).select do |f|
|
26
|
+
(f == gemspec) || f.start_with?(*%w[lib/ ext/ rs/])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
%w(lib/ratomic/ratomic.bundle lib/ratomic/ratomic.so).each do |file|
|
30
|
+
File.exist?(file) && spec.files << file
|
31
|
+
end
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
spec.extensions = ["ext/ratomic/extconf.rb"]
|
34
|
+
|
35
|
+
# Uncomment to register a new dependency of your gem
|
36
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
37
|
+
|
38
|
+
# For more information and examples about making a new gem, check out our
|
39
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
40
|
+
end
|
data/rs/Cargo.lock
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
2
|
+
# It is not intended for manual editing.
|
3
|
+
version = 4
|
4
|
+
|
5
|
+
[[package]]
|
6
|
+
name = "autocfg"
|
7
|
+
version = "1.4.0"
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
9
|
+
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
10
|
+
|
11
|
+
[[package]]
|
12
|
+
name = "bitflags"
|
13
|
+
version = "2.9.0"
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
15
|
+
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
16
|
+
|
17
|
+
[[package]]
|
18
|
+
name = "cfg-if"
|
19
|
+
version = "1.0.0"
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
21
|
+
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
22
|
+
|
23
|
+
[[package]]
|
24
|
+
name = "crossbeam-channel"
|
25
|
+
version = "0.5.14"
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
27
|
+
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
|
28
|
+
dependencies = [
|
29
|
+
"crossbeam-utils",
|
30
|
+
]
|
31
|
+
|
32
|
+
[[package]]
|
33
|
+
name = "crossbeam-utils"
|
34
|
+
version = "0.8.21"
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
36
|
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
37
|
+
|
38
|
+
[[package]]
|
39
|
+
name = "dashmap"
|
40
|
+
version = "6.1.0"
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
42
|
+
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
43
|
+
dependencies = [
|
44
|
+
"cfg-if",
|
45
|
+
"crossbeam-utils",
|
46
|
+
"hashbrown",
|
47
|
+
"lock_api",
|
48
|
+
"once_cell",
|
49
|
+
"parking_lot_core",
|
50
|
+
]
|
51
|
+
|
52
|
+
[[package]]
|
53
|
+
name = "hashbrown"
|
54
|
+
version = "0.14.5"
|
55
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
56
|
+
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
57
|
+
|
58
|
+
[[package]]
|
59
|
+
name = "libc"
|
60
|
+
version = "0.2.171"
|
61
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
62
|
+
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
63
|
+
|
64
|
+
[[package]]
|
65
|
+
name = "lock_api"
|
66
|
+
version = "0.4.12"
|
67
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
68
|
+
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
69
|
+
dependencies = [
|
70
|
+
"autocfg",
|
71
|
+
"scopeguard",
|
72
|
+
]
|
73
|
+
|
74
|
+
[[package]]
|
75
|
+
name = "once_cell"
|
76
|
+
version = "1.21.1"
|
77
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
78
|
+
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
79
|
+
|
80
|
+
[[package]]
|
81
|
+
name = "parking_lot"
|
82
|
+
version = "0.12.3"
|
83
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
84
|
+
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
85
|
+
dependencies = [
|
86
|
+
"lock_api",
|
87
|
+
"parking_lot_core",
|
88
|
+
]
|
89
|
+
|
90
|
+
[[package]]
|
91
|
+
name = "parking_lot_core"
|
92
|
+
version = "0.9.10"
|
93
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
94
|
+
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
95
|
+
dependencies = [
|
96
|
+
"cfg-if",
|
97
|
+
"libc",
|
98
|
+
"redox_syscall",
|
99
|
+
"smallvec",
|
100
|
+
"windows-targets",
|
101
|
+
]
|
102
|
+
|
103
|
+
[[package]]
|
104
|
+
name = "redox_syscall"
|
105
|
+
version = "0.5.10"
|
106
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
107
|
+
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
|
108
|
+
dependencies = [
|
109
|
+
"bitflags",
|
110
|
+
]
|
111
|
+
|
112
|
+
[[package]]
|
113
|
+
name = "rust-atomics"
|
114
|
+
version = "0.1.0"
|
115
|
+
dependencies = [
|
116
|
+
"crossbeam-channel",
|
117
|
+
"dashmap",
|
118
|
+
"libc",
|
119
|
+
"parking_lot",
|
120
|
+
]
|
121
|
+
|
122
|
+
[[package]]
|
123
|
+
name = "scopeguard"
|
124
|
+
version = "1.2.0"
|
125
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
126
|
+
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
127
|
+
|
128
|
+
[[package]]
|
129
|
+
name = "smallvec"
|
130
|
+
version = "1.14.0"
|
131
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
132
|
+
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
133
|
+
|
134
|
+
[[package]]
|
135
|
+
name = "windows-targets"
|
136
|
+
version = "0.52.6"
|
137
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
138
|
+
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
139
|
+
dependencies = [
|
140
|
+
"windows_aarch64_gnullvm",
|
141
|
+
"windows_aarch64_msvc",
|
142
|
+
"windows_i686_gnu",
|
143
|
+
"windows_i686_gnullvm",
|
144
|
+
"windows_i686_msvc",
|
145
|
+
"windows_x86_64_gnu",
|
146
|
+
"windows_x86_64_gnullvm",
|
147
|
+
"windows_x86_64_msvc",
|
148
|
+
]
|
149
|
+
|
150
|
+
[[package]]
|
151
|
+
name = "windows_aarch64_gnullvm"
|
152
|
+
version = "0.52.6"
|
153
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
154
|
+
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
155
|
+
|
156
|
+
[[package]]
|
157
|
+
name = "windows_aarch64_msvc"
|
158
|
+
version = "0.52.6"
|
159
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
160
|
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
161
|
+
|
162
|
+
[[package]]
|
163
|
+
name = "windows_i686_gnu"
|
164
|
+
version = "0.52.6"
|
165
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
166
|
+
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
167
|
+
|
168
|
+
[[package]]
|
169
|
+
name = "windows_i686_gnullvm"
|
170
|
+
version = "0.52.6"
|
171
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
172
|
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
173
|
+
|
174
|
+
[[package]]
|
175
|
+
name = "windows_i686_msvc"
|
176
|
+
version = "0.52.6"
|
177
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
178
|
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
179
|
+
|
180
|
+
[[package]]
|
181
|
+
name = "windows_x86_64_gnu"
|
182
|
+
version = "0.52.6"
|
183
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
184
|
+
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
185
|
+
|
186
|
+
[[package]]
|
187
|
+
name = "windows_x86_64_gnullvm"
|
188
|
+
version = "0.52.6"
|
189
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
190
|
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
191
|
+
|
192
|
+
[[package]]
|
193
|
+
name = "windows_x86_64_msvc"
|
194
|
+
version = "0.52.6"
|
195
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
196
|
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
data/rs/Cargo.toml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
[package]
|
2
|
+
name = "rust-atomics"
|
3
|
+
version = "0.1.0"
|
4
|
+
edition = "2024"
|
5
|
+
|
6
|
+
[lib]
|
7
|
+
crate-type = ["lib", "staticlib"]
|
8
|
+
|
9
|
+
[features]
|
10
|
+
simulation = []
|
11
|
+
|
12
|
+
[dependencies]
|
13
|
+
crossbeam-channel = "0.5.14"
|
14
|
+
dashmap = "6.1.0"
|
15
|
+
parking_lot = "0.12.3"
|
16
|
+
libc = "0.2.170"
|
17
|
+
|
18
|
+
[profile.release]
|
19
|
+
panic = "abort"
|
20
|
+
lto = true
|
21
|
+
codegen-units = 1
|
22
|
+
|
23
|
+
[[bin]]
|
24
|
+
bench = false
|
25
|
+
name = "mpmc_queue"
|
26
|
+
test = false
|
data/rs/cbindgen.toml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
language = "c"
|
2
|
+
include_guard = "RUST_ATOMICS_H"
|
3
|
+
style = "type"
|
4
|
+
|
5
|
+
[export.rename]
|
6
|
+
"AtomicCounter" = "atomic_counter_t"
|
7
|
+
"ConcurrentHashMap" = "concurrent_hash_map_t"
|
8
|
+
"FixedSizeObjectPool" = "fixed_size_object_pool_t"
|
9
|
+
"MpmcQueue" = "mpmc_queue_t"
|
10
|
+
|
11
|
+
[export]
|
12
|
+
include = ["QueuePushArg"]
|