polyphony 0.83 → 0.84
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 +4 -4
- data/.gitmodules +3 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +14 -0
- data/ext/polyphony/backend_io_uring.c +42 -6
- data/ext/polyphony/backend_libev.c +45 -0
- data/ext/polyphony/extconf.rb +17 -0
- data/ext/polyphony/polyphony.c +5 -0
- data/ext/polyphony/polyphony.h +1 -0
- data/lib/polyphony/extensions/io.rb +10 -0
- data/lib/polyphony/extensions/pipe.rb +4 -0
- data/lib/polyphony/version.rb +1 -1
- data/test/test_io.rb +60 -1
- metadata +2 -13
- data/ext/liburing/liburing/README.md +0 -4
- data/ext/liburing/liburing/barrier.h +0 -73
- data/ext/liburing/liburing/compat.h +0 -15
- data/ext/liburing/liburing/io_uring.h +0 -343
- data/ext/liburing/liburing.h +0 -585
- data/ext/liburing/queue.c +0 -333
- data/ext/liburing/register.c +0 -187
- data/ext/liburing/setup.c +0 -210
- data/ext/liburing/syscall.c +0 -54
- data/ext/liburing/syscall.h +0 -18
- data/ext/polyphony/liburing.c +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce9742f5b50581c5569df4ad3e2232c7c32392a92e7ab23960373c8a4e3b0de4
|
4
|
+
data.tar.gz: a695f3191cc7cefb7d720565c3564b24784beb836528342e8d4fd9e8d0231dda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 041cb949e600ef328ed6d1c92badcaa9ef502e4776043d6a7786a811d5935de450f933b8eff4dd6100db6e55ff19878186bd9ef6bb840ac1cdcdb8c53341f51c
|
7
|
+
data.tar.gz: fc0542606c3ee5ab044cc5e8175a60fb3fa6a8466422643ff1446fb0271a6db09236b5c0dbc7a632fa47853ae0ac3a2007fa4644a85283b4225f453f6155dbce
|
data/.gitmodules
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -24,3 +24,17 @@ task :docs do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
CLEAN.include "**/*.o", "**/*.so", "**/*.so.*", "**/*.a", "**/*.bundle", "**/*.jar", "pkg", "tmp"
|
27
|
+
|
28
|
+
task :release do
|
29
|
+
require_relative './lib/polyphony/version'
|
30
|
+
version = Polyphony::VERSION
|
31
|
+
|
32
|
+
puts 'Building polyphony...'
|
33
|
+
`gem build polyphony.gemspec`
|
34
|
+
|
35
|
+
puts "Pushing polyphony #{version}..."
|
36
|
+
`gem push extralite-#{version}.gem`
|
37
|
+
|
38
|
+
puts "Cleaning up..."
|
39
|
+
`rm *.gem`
|
40
|
+
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#include <errno.h>
|
15
15
|
|
16
16
|
#include "polyphony.h"
|
17
|
-
#include "
|
17
|
+
#include "liburing.h"
|
18
18
|
#include "backend_io_uring_context.h"
|
19
19
|
#include "ruby/thread.h"
|
20
20
|
#include "ruby/io.h"
|
@@ -304,7 +304,7 @@ int io_uring_backend_defer_submit_and_await(
|
|
304
304
|
// op was not completed (an exception was raised), so we need to cancel it
|
305
305
|
ctx->result = -ECANCELED;
|
306
306
|
sqe = io_uring_get_sqe(&backend->ring);
|
307
|
-
io_uring_prep_cancel(sqe, ctx, 0);
|
307
|
+
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
308
308
|
backend->pending_sqes = 0;
|
309
309
|
io_uring_submit(&backend->ring);
|
310
310
|
}
|
@@ -971,6 +971,41 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize)
|
|
971
971
|
return io_uring_backend_splice(backend, src, dest, chunksize, 1);
|
972
972
|
}
|
973
973
|
|
974
|
+
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
975
|
+
Backend_t *backend;
|
976
|
+
GetBackend(self, backend);
|
977
|
+
|
978
|
+
int src_fd;
|
979
|
+
int dest_fd;
|
980
|
+
rb_io_t *src_fptr;
|
981
|
+
rb_io_t *dest_fptr;
|
982
|
+
VALUE resume_value = Qnil;
|
983
|
+
|
984
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
985
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
986
|
+
|
987
|
+
while (1) {
|
988
|
+
op_context_t *ctx = context_store_acquire(&backend->store, OP_SPLICE);
|
989
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(&backend->ring);
|
990
|
+
int result;
|
991
|
+
int completed;
|
992
|
+
|
993
|
+
io_uring_prep_tee(sqe, src_fd, dest_fd, NUM2INT(maxlen), 0);
|
994
|
+
|
995
|
+
result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
|
996
|
+
completed = context_store_release(&backend->store, ctx);
|
997
|
+
RAISE_IF_EXCEPTION(resume_value);
|
998
|
+
if (!completed) return resume_value;
|
999
|
+
|
1000
|
+
if (result < 0)
|
1001
|
+
rb_syserr_fail(-result, strerror(-result));
|
1002
|
+
|
1003
|
+
return INT2NUM(result);
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
RB_GC_GUARD(resume_value);
|
1007
|
+
}
|
1008
|
+
|
974
1009
|
VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
|
975
1010
|
Backend_t *backend;
|
976
1011
|
int fd;
|
@@ -1125,7 +1160,7 @@ VALUE Backend_timeout_ensure(VALUE arg) {
|
|
1125
1160
|
timeout_ctx->ctx->result = -ECANCELED;
|
1126
1161
|
// op was not completed, so we need to cancel it
|
1127
1162
|
sqe = io_uring_get_sqe(&timeout_ctx->backend->ring);
|
1128
|
-
io_uring_prep_cancel(sqe, timeout_ctx->ctx, 0);
|
1163
|
+
io_uring_prep_cancel(sqe, (__u64)timeout_ctx->ctx, 0);
|
1129
1164
|
timeout_ctx->backend->pending_sqes = 0;
|
1130
1165
|
io_uring_submit(&timeout_ctx->backend->ring);
|
1131
1166
|
}
|
@@ -1318,7 +1353,7 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
1318
1353
|
ctx->ref_count = sqe_count;
|
1319
1354
|
ctx->result = -ECANCELED;
|
1320
1355
|
sqe = io_uring_get_sqe(&backend->ring);
|
1321
|
-
io_uring_prep_cancel(sqe, ctx, 0);
|
1356
|
+
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
1322
1357
|
backend->pending_sqes = 0;
|
1323
1358
|
io_uring_submit(&backend->ring);
|
1324
1359
|
}
|
@@ -1349,7 +1384,7 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
1349
1384
|
// op was not completed (an exception was raised), so we need to cancel it
|
1350
1385
|
ctx->result = -ECANCELED;
|
1351
1386
|
sqe = io_uring_get_sqe(&backend->ring);
|
1352
|
-
io_uring_prep_cancel(sqe, ctx, 0);
|
1387
|
+
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
1353
1388
|
backend->pending_sqes = 0;
|
1354
1389
|
io_uring_submit(&backend->ring);
|
1355
1390
|
RAISE_IF_EXCEPTION(resume_value);
|
@@ -1416,7 +1451,7 @@ static inline void splice_chunks_cancel(Backend_t *backend, op_context_t *ctx) {
|
|
1416
1451
|
|
1417
1452
|
ctx->result = -ECANCELED;
|
1418
1453
|
sqe = io_uring_get_sqe(&backend->ring);
|
1419
|
-
io_uring_prep_cancel(sqe, ctx, 0);
|
1454
|
+
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
1420
1455
|
backend->pending_sqes = 0;
|
1421
1456
|
io_uring_submit(&backend->ring);
|
1422
1457
|
}
|
@@ -1619,6 +1654,7 @@ void Init_Backend() {
|
|
1619
1654
|
rb_define_method(cBackend, "sleep", Backend_sleep, 1);
|
1620
1655
|
rb_define_method(cBackend, "splice", Backend_splice, 3);
|
1621
1656
|
rb_define_method(cBackend, "splice_to_eof", Backend_splice_to_eof, 3);
|
1657
|
+
rb_define_method(cBackend, "tee", Backend_tee, 3);
|
1622
1658
|
rb_define_method(cBackend, "timeout", Backend_timeout, -1);
|
1623
1659
|
rb_define_method(cBackend, "timer_loop", Backend_timer_loop, 1);
|
1624
1660
|
rb_define_method(cBackend, "wait_event", Backend_wait_event, 1);
|
@@ -940,7 +940,52 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
940
940
|
error:
|
941
941
|
return RAISE_EXCEPTION(switchpoint_result);
|
942
942
|
}
|
943
|
+
|
944
|
+
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
945
|
+
Backend_t *backend;
|
946
|
+
struct libev_rw_io watcher;
|
947
|
+
VALUE switchpoint_result = Qnil;
|
948
|
+
int src_fd;
|
949
|
+
int dest_fd;
|
950
|
+
rb_io_t *src_fptr;
|
951
|
+
rb_io_t *dest_fptr;
|
952
|
+
int len;
|
953
|
+
|
954
|
+
GetBackend(self, backend);
|
955
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
956
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
957
|
+
watcher.ctx.fiber = Qnil;
|
958
|
+
|
959
|
+
while (1) {
|
960
|
+
backend->base.op_count++;
|
961
|
+
len = tee(src_fd, dest_fd, NUM2INT(maxlen), 0);
|
962
|
+
if (len < 0) {
|
963
|
+
int e = errno;
|
964
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
965
|
+
|
966
|
+
switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
|
967
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
968
|
+
}
|
969
|
+
else {
|
970
|
+
break;
|
971
|
+
}
|
972
|
+
}
|
973
|
+
|
974
|
+
if (watcher.ctx.fiber == Qnil) {
|
975
|
+
switchpoint_result = backend_snooze(&backend->base);
|
976
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
977
|
+
}
|
978
|
+
|
979
|
+
RB_GC_GUARD(watcher.ctx.fiber);
|
980
|
+
RB_GC_GUARD(switchpoint_result);
|
981
|
+
|
982
|
+
return INT2NUM(len);
|
983
|
+
error:
|
984
|
+
return RAISE_EXCEPTION(switchpoint_result);
|
985
|
+
}
|
986
|
+
|
943
987
|
#else
|
988
|
+
|
944
989
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
945
990
|
Backend_t *backend;
|
946
991
|
struct libev_io watcher;
|
data/ext/polyphony/extconf.rb
CHANGED
@@ -28,6 +28,22 @@ puts "Building Polyphony... (#{config.inspect})"
|
|
28
28
|
|
29
29
|
require_relative 'zlib_conf'
|
30
30
|
|
31
|
+
if config[:io_uring]
|
32
|
+
liburing_path = File.expand_path('../../vendor/liburing', __dir__)
|
33
|
+
FileUtils.cd liburing_path do
|
34
|
+
system('./configure', exception: true)
|
35
|
+
FileUtils.cd File.join(liburing_path, 'src') do
|
36
|
+
system('make', 'liburing.a', exception: true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if !find_header 'liburing.h', File.expand_path('../../vendor/liburing/src/include', __dir__)
|
41
|
+
raise "Couldn't find liburing.h"
|
42
|
+
end
|
43
|
+
|
44
|
+
$LDFLAGS << " -L#{File.expand_path('../../vendor/liburing/src', __dir__)} -l uring"
|
45
|
+
end
|
46
|
+
|
31
47
|
$defs << '-DPOLYPHONY_USE_PIDFD_OPEN' if config[:pidfd_open]
|
32
48
|
if config[:io_uring]
|
33
49
|
$defs << "-DPOLYPHONY_BACKEND_LIBURING"
|
@@ -56,4 +72,5 @@ CONFIG['optflags'] << ' -fno-strict-aliasing' unless RUBY_PLATFORM =~ /mswin/
|
|
56
72
|
|
57
73
|
have_func('rb_fiber_transfer', 'ruby.h')
|
58
74
|
|
75
|
+
|
59
76
|
create_makefile 'polyphony_ext'
|
data/ext/polyphony/polyphony.c
CHANGED
@@ -94,6 +94,10 @@ VALUE Polyphony_backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE c
|
|
94
94
|
return Backend_splice_to_eof(BACKEND(), src, dest, chunksize);
|
95
95
|
}
|
96
96
|
|
97
|
+
VALUE Polyphony_backend_tee(VALUE self, VALUE src, VALUE dest, VALUE chunksize) {
|
98
|
+
return Backend_tee(BACKEND(), src, dest, chunksize);
|
99
|
+
}
|
100
|
+
|
97
101
|
VALUE Polyphony_backend_timeout(int argc,VALUE *argv, VALUE self) {
|
98
102
|
return Backend_timeout(argc, argv, BACKEND());
|
99
103
|
}
|
@@ -186,6 +190,7 @@ void Init_Polyphony() {
|
|
186
190
|
rb_define_singleton_method(mPolyphony, "backend_sleep", Polyphony_backend_sleep, 1);
|
187
191
|
rb_define_singleton_method(mPolyphony, "backend_splice", Polyphony_backend_splice, 3);
|
188
192
|
rb_define_singleton_method(mPolyphony, "backend_splice_to_eof", Polyphony_backend_splice_to_eof, 3);
|
193
|
+
rb_define_singleton_method(mPolyphony, "backend_tee", Polyphony_backend_tee, 3);
|
189
194
|
rb_define_singleton_method(mPolyphony, "backend_timeout", Polyphony_backend_timeout, -1);
|
190
195
|
rb_define_singleton_method(mPolyphony, "backend_timer_loop", Polyphony_backend_timer_loop, 1);
|
191
196
|
rb_define_singleton_method(mPolyphony, "backend_wait_event", Polyphony_backend_wait_event, 1);
|
data/ext/polyphony/polyphony.h
CHANGED
@@ -112,6 +112,7 @@ VALUE Backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags);
|
|
112
112
|
VALUE Backend_sleep(VALUE self, VALUE duration);
|
113
113
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
|
114
114
|
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize);
|
115
|
+
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
|
115
116
|
VALUE Backend_timeout(int argc,VALUE *argv, VALUE self);
|
116
117
|
VALUE Backend_timer_loop(VALUE self, VALUE interval);
|
117
118
|
VALUE Backend_wait_event(VALUE self, VALUE raise);
|
@@ -81,6 +81,12 @@ class ::IO
|
|
81
81
|
def splice_to_eof(src, dest, chunk_size = 8192)
|
82
82
|
Polyphony.backend_splice_to_eof(src, dest, chunk_size)
|
83
83
|
end
|
84
|
+
|
85
|
+
if RUBY_PLATFORM =~ /linux/
|
86
|
+
def tee(src, dest, maxlen)
|
87
|
+
Polyphony.backend_tee(src, dest, maxlen)
|
88
|
+
end
|
89
|
+
end
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
@@ -272,4 +278,8 @@ class ::IO
|
|
272
278
|
def splice_to_eof_from(src, chunksize = 8192)
|
273
279
|
Polyphony.backend_splice_to_eof(src, self, chunksize)
|
274
280
|
end
|
281
|
+
|
282
|
+
def tee_from(src, maxlen)
|
283
|
+
Polyphony.backend_tee(src, self, maxlen)
|
284
|
+
end
|
275
285
|
end
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_io.rb
CHANGED
@@ -367,6 +367,65 @@ class IOTest < MiniTest::Test
|
|
367
367
|
f.await
|
368
368
|
end
|
369
369
|
end
|
370
|
+
|
371
|
+
def test_tee_from
|
372
|
+
skip "tested only on Linux" unless RUBY_PLATFORM =~ /linux/
|
373
|
+
|
374
|
+
src = Polyphony.pipe
|
375
|
+
dest1 = Polyphony.pipe
|
376
|
+
dest2 = Polyphony.pipe
|
377
|
+
|
378
|
+
len1 = len2 = nil
|
379
|
+
|
380
|
+
spin {
|
381
|
+
len1 = dest1.tee_from(src, 1000)
|
382
|
+
dest1.close
|
383
|
+
len2 = IO.splice(src, dest2, 1000)
|
384
|
+
dest2.close
|
385
|
+
}
|
386
|
+
|
387
|
+
src << 'foobar'
|
388
|
+
src.close
|
389
|
+
result1 = dest1.read
|
390
|
+
result2 = dest2.read
|
391
|
+
|
392
|
+
assert_equal 'foobar', result1
|
393
|
+
assert_equal 6, len1
|
394
|
+
|
395
|
+
assert_equal 'foobar', result2
|
396
|
+
assert_equal 6, len2
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_tee_class_method
|
400
|
+
skip "tested only on Linux" unless RUBY_PLATFORM =~ /linux/
|
401
|
+
|
402
|
+
src = Polyphony.pipe
|
403
|
+
dest1 = Polyphony.pipe
|
404
|
+
dest2 = Polyphony.pipe
|
405
|
+
|
406
|
+
len1 = len2 = nil
|
407
|
+
|
408
|
+
spin {
|
409
|
+
len1 = IO.tee(src, dest1, 1000)
|
410
|
+
dest1.close
|
411
|
+
len2 = IO.splice(src, dest2, 1000)
|
412
|
+
dest2.close
|
413
|
+
}
|
414
|
+
|
415
|
+
src << 'foobar'
|
416
|
+
src.close
|
417
|
+
result1 = dest1.read
|
418
|
+
result2 = dest2.read
|
419
|
+
|
420
|
+
assert_equal 'foobar', result1
|
421
|
+
assert_equal 6, len1
|
422
|
+
|
423
|
+
assert_equal 'foobar', result2
|
424
|
+
assert_equal 6, len2
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
|
370
429
|
end
|
371
430
|
|
372
431
|
class IOWithRawBufferTest < MiniTest::Test
|
@@ -643,7 +702,7 @@ class IOExtensionsTest < MiniTest::Test
|
|
643
702
|
gz = Zlib::GzipReader.new(dest)
|
644
703
|
data = gz.read
|
645
704
|
assert_equal IO.read(__FILE__), data
|
646
|
-
assert_in_range (now-
|
705
|
+
assert_in_range (now-2)..(now+1), gz.mtime
|
647
706
|
assert_nil gz.orig_name
|
648
707
|
assert_nil gz.comment
|
649
708
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.84'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -315,16 +315,6 @@ files:
|
|
315
315
|
- ext/libev/ev_win32.c
|
316
316
|
- ext/libev/ev_wrap.h
|
317
317
|
- ext/libev/test_libev_win32.c
|
318
|
-
- ext/liburing/liburing.h
|
319
|
-
- ext/liburing/liburing/README.md
|
320
|
-
- ext/liburing/liburing/barrier.h
|
321
|
-
- ext/liburing/liburing/compat.h
|
322
|
-
- ext/liburing/liburing/io_uring.h
|
323
|
-
- ext/liburing/queue.c
|
324
|
-
- ext/liburing/register.c
|
325
|
-
- ext/liburing/setup.c
|
326
|
-
- ext/liburing/syscall.c
|
327
|
-
- ext/liburing/syscall.h
|
328
318
|
- ext/polyphony/backend_common.c
|
329
319
|
- ext/polyphony/backend_common.h
|
330
320
|
- ext/polyphony/backend_io_uring.c
|
@@ -337,7 +327,6 @@ files:
|
|
337
327
|
- ext/polyphony/io_extensions.c
|
338
328
|
- ext/polyphony/libev.c
|
339
329
|
- ext/polyphony/libev.h
|
340
|
-
- ext/polyphony/liburing.c
|
341
330
|
- ext/polyphony/pipe.c
|
342
331
|
- ext/polyphony/playground.c
|
343
332
|
- ext/polyphony/polyphony.c
|
@@ -1,73 +0,0 @@
|
|
1
|
-
/* SPDX-License-Identifier: MIT */
|
2
|
-
#ifndef LIBURING_BARRIER_H
|
3
|
-
#define LIBURING_BARRIER_H
|
4
|
-
|
5
|
-
/*
|
6
|
-
From the kernel documentation file refcount-vs-atomic.rst:
|
7
|
-
|
8
|
-
A RELEASE memory ordering guarantees that all prior loads and
|
9
|
-
stores (all po-earlier instructions) on the same CPU are completed
|
10
|
-
before the operation. It also guarantees that all po-earlier
|
11
|
-
stores on the same CPU and all propagated stores from other CPUs
|
12
|
-
must propagate to all other CPUs before the release operation
|
13
|
-
(A-cumulative property). This is implemented using
|
14
|
-
:c:func:`smp_store_release`.
|
15
|
-
|
16
|
-
An ACQUIRE memory ordering guarantees that all post loads and
|
17
|
-
stores (all po-later instructions) on the same CPU are
|
18
|
-
completed after the acquire operation. It also guarantees that all
|
19
|
-
po-later stores on the same CPU must propagate to all other CPUs
|
20
|
-
after the acquire operation executes. This is implemented using
|
21
|
-
:c:func:`smp_acquire__after_ctrl_dep`.
|
22
|
-
*/
|
23
|
-
|
24
|
-
#ifdef __cplusplus
|
25
|
-
#include <atomic>
|
26
|
-
|
27
|
-
template <typename T>
|
28
|
-
static inline void IO_URING_WRITE_ONCE(T &var, T val)
|
29
|
-
{
|
30
|
-
std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(&var),
|
31
|
-
val, std::memory_order_relaxed);
|
32
|
-
}
|
33
|
-
template <typename T>
|
34
|
-
static inline T IO_URING_READ_ONCE(const T &var)
|
35
|
-
{
|
36
|
-
return std::atomic_load_explicit(
|
37
|
-
reinterpret_cast<const std::atomic<T> *>(&var),
|
38
|
-
std::memory_order_relaxed);
|
39
|
-
}
|
40
|
-
|
41
|
-
template <typename T>
|
42
|
-
static inline void io_uring_smp_store_release(T *p, T v)
|
43
|
-
{
|
44
|
-
std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(p), v,
|
45
|
-
std::memory_order_release);
|
46
|
-
}
|
47
|
-
|
48
|
-
template <typename T>
|
49
|
-
static inline T io_uring_smp_load_acquire(const T *p)
|
50
|
-
{
|
51
|
-
return std::atomic_load_explicit(
|
52
|
-
reinterpret_cast<const std::atomic<T> *>(p),
|
53
|
-
std::memory_order_acquire);
|
54
|
-
}
|
55
|
-
#else
|
56
|
-
#include <stdatomic.h>
|
57
|
-
|
58
|
-
#define IO_URING_WRITE_ONCE(var, val) \
|
59
|
-
atomic_store_explicit((_Atomic typeof(var) *)&(var), \
|
60
|
-
(val), memory_order_relaxed)
|
61
|
-
#define IO_URING_READ_ONCE(var) \
|
62
|
-
atomic_load_explicit((_Atomic typeof(var) *)&(var), \
|
63
|
-
memory_order_relaxed)
|
64
|
-
|
65
|
-
#define io_uring_smp_store_release(p, v) \
|
66
|
-
atomic_store_explicit((_Atomic typeof(*(p)) *)(p), (v), \
|
67
|
-
memory_order_release)
|
68
|
-
#define io_uring_smp_load_acquire(p) \
|
69
|
-
atomic_load_explicit((_Atomic typeof(*(p)) *)(p), \
|
70
|
-
memory_order_acquire)
|
71
|
-
#endif
|
72
|
-
|
73
|
-
#endif /* defined(LIBURING_BARRIER_H) */
|