polyphony 0.83 → 0.84
Sign up to get free protection for your applications and to get access to all the features.
- 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) */
|