uringmachine 0.28.3 → 0.29.1
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/CHANGELOG.md +15 -1
- data/TODO.md +29 -35
- data/benchmark/common.rb +6 -6
- data/benchmark/gets.rb +49 -0
- data/benchmark/gets_concurrent.rb +122 -0
- data/benchmark/{read_each.rb → output.rb} +27 -24
- data/docs/design/buffer_pool.md +35 -0
- data/docs/um_api.md +2 -0
- data/ext/um/extconf.rb +6 -5
- data/ext/um/um.c +50 -16
- data/ext/um/um.h +102 -32
- data/ext/um/um_buffer_pool.c +248 -0
- data/ext/um/um_class.c +28 -16
- data/ext/um/um_op.c +29 -13
- data/ext/um/um_ssl.c +24 -27
- data/ext/um/um_stream.c +382 -150
- data/ext/um/um_stream_class.c +119 -63
- data/ext/um/um_utils.c +6 -6
- data/grant-2025/tasks.md +13 -7
- data/lib/uringmachine/fiber_scheduler.rb +36 -10
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +60 -19
- data/test/helper.rb +4 -0
- data/test/test_fiber.rb +93 -12
- data/test/test_fiber_scheduler.rb +8 -50
- data/test/test_stream.rb +466 -124
- data/test/test_um.rb +133 -49
- metadata +6 -4
- data/ext/um/um_buffer.c +0 -49
data/test/test_um.rb
CHANGED
|
@@ -292,6 +292,20 @@ class ScheduleTest < UMBaseTest
|
|
|
292
292
|
assert_kind_of TOError, e
|
|
293
293
|
end
|
|
294
294
|
|
|
295
|
+
def test_timeout_with_exception_instance
|
|
296
|
+
res = nil
|
|
297
|
+
e = TOError.new
|
|
298
|
+
begin
|
|
299
|
+
res = machine.timeout(0.01, e) {
|
|
300
|
+
machine.sleep(1)
|
|
301
|
+
:foo
|
|
302
|
+
}
|
|
303
|
+
rescue => res
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
assert_equal e, res
|
|
307
|
+
end
|
|
308
|
+
|
|
295
309
|
def test_timeout_with_raising_block
|
|
296
310
|
e = nil
|
|
297
311
|
begin
|
|
@@ -1222,63 +1236,63 @@ end
|
|
|
1222
1236
|
class ShutdownTest < UMBaseTest
|
|
1223
1237
|
def test_shutdown
|
|
1224
1238
|
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
1225
|
-
res =
|
|
1239
|
+
res = machine.send(c_fd, 'abc', 3, 0)
|
|
1226
1240
|
assert_equal 3, res
|
|
1227
1241
|
|
|
1228
1242
|
buf = +''
|
|
1229
|
-
res =
|
|
1243
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1230
1244
|
assert_equal 3, res
|
|
1231
1245
|
assert_equal 'abc', buf
|
|
1232
1246
|
|
|
1233
|
-
res =
|
|
1247
|
+
res = machine.shutdown(c_fd, UM::SHUT_WR)
|
|
1234
1248
|
assert_equal 0, res
|
|
1235
1249
|
|
|
1236
|
-
assert_raises(Errno::EPIPE) {
|
|
1250
|
+
assert_raises(Errno::EPIPE) { machine.send(c_fd, 'abc', 3, 0) }
|
|
1237
1251
|
|
|
1238
|
-
res =
|
|
1252
|
+
res = machine.shutdown(s_fd, UM::SHUT_RD)
|
|
1239
1253
|
assert_equal 0, res
|
|
1240
1254
|
|
|
1241
|
-
res =
|
|
1255
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1242
1256
|
assert_equal 0, res
|
|
1243
1257
|
|
|
1244
|
-
res =
|
|
1258
|
+
res = machine.shutdown(c_fd, UM::SHUT_RDWR)
|
|
1245
1259
|
assert_equal 0, res
|
|
1246
1260
|
|
|
1247
|
-
assert_raises(Errno::EINVAL) {
|
|
1261
|
+
assert_raises(Errno::EINVAL) { machine.shutdown(c_fd, -9999) }
|
|
1248
1262
|
ensure
|
|
1249
|
-
|
|
1250
|
-
|
|
1263
|
+
machine.close(c_fd)
|
|
1264
|
+
machine.close(s_fd)
|
|
1251
1265
|
end
|
|
1252
1266
|
end
|
|
1253
1267
|
|
|
1254
1268
|
class ShutdownAsyncTest < UMBaseTest
|
|
1255
1269
|
def test_shutdown_async
|
|
1256
1270
|
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
1257
|
-
res =
|
|
1271
|
+
res = machine.send(c_fd, 'abc', 3, 0)
|
|
1258
1272
|
assert_equal 3, res
|
|
1259
1273
|
|
|
1260
1274
|
buf = +''
|
|
1261
|
-
res =
|
|
1275
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1262
1276
|
assert_equal 3, res
|
|
1263
1277
|
assert_equal 'abc', buf
|
|
1264
1278
|
|
|
1265
|
-
res =
|
|
1279
|
+
res = machine.shutdown_async(c_fd, UM::SHUT_WR)
|
|
1266
1280
|
assert_equal c_fd, res
|
|
1267
1281
|
|
|
1268
1282
|
machine.sleep(0.01)
|
|
1269
|
-
assert_raises(Errno::EPIPE) {
|
|
1283
|
+
assert_raises(Errno::EPIPE) { machine.send(c_fd, 'abc', 3, 0) }
|
|
1270
1284
|
|
|
1271
|
-
res =
|
|
1285
|
+
res = machine.shutdown_async(s_fd, UM::SHUT_RD)
|
|
1272
1286
|
assert_equal s_fd, res
|
|
1273
1287
|
|
|
1274
|
-
res =
|
|
1288
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1275
1289
|
assert_equal 0, res
|
|
1276
1290
|
|
|
1277
|
-
res =
|
|
1291
|
+
res = machine.shutdown_async(c_fd, UM::SHUT_RDWR)
|
|
1278
1292
|
assert_equal c_fd, res
|
|
1279
1293
|
ensure
|
|
1280
|
-
|
|
1281
|
-
|
|
1294
|
+
machine.close(c_fd)
|
|
1295
|
+
machine.close(s_fd)
|
|
1282
1296
|
end
|
|
1283
1297
|
end
|
|
1284
1298
|
|
|
@@ -1345,7 +1359,7 @@ class AcceptEachTest < UMBaseTest
|
|
|
1345
1359
|
def test_accept_each_interrupted
|
|
1346
1360
|
count = 0
|
|
1347
1361
|
terminated = nil
|
|
1348
|
-
f =
|
|
1362
|
+
f = machine.spin do
|
|
1349
1363
|
machine.accept_each(@server.fileno) do |fd|
|
|
1350
1364
|
count += 1
|
|
1351
1365
|
break if count == 3
|
|
@@ -1355,13 +1369,13 @@ class AcceptEachTest < UMBaseTest
|
|
|
1355
1369
|
end
|
|
1356
1370
|
|
|
1357
1371
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1358
|
-
|
|
1372
|
+
machine.sleep(0.01)
|
|
1359
1373
|
|
|
1360
1374
|
assert_equal 1, count
|
|
1361
1375
|
refute terminated
|
|
1362
1376
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1377
|
+
machine.schedule(f, UM::Terminate.new)
|
|
1378
|
+
machine.sleep(0.01)
|
|
1365
1379
|
|
|
1366
1380
|
assert f.done?
|
|
1367
1381
|
assert terminated
|
|
@@ -1375,7 +1389,7 @@ class AcceptEachTest < UMBaseTest
|
|
|
1375
1389
|
def test_accept_each_closed
|
|
1376
1390
|
count = 0
|
|
1377
1391
|
done = nil
|
|
1378
|
-
|
|
1392
|
+
machine.spin do
|
|
1379
1393
|
machine.accept_each(@server.fileno) do |fd|
|
|
1380
1394
|
count += 1
|
|
1381
1395
|
end
|
|
@@ -1384,17 +1398,17 @@ class AcceptEachTest < UMBaseTest
|
|
|
1384
1398
|
end
|
|
1385
1399
|
|
|
1386
1400
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1387
|
-
|
|
1401
|
+
machine.sleep(0.01)
|
|
1388
1402
|
|
|
1389
1403
|
assert_equal 1, count
|
|
1390
1404
|
refute done
|
|
1391
1405
|
|
|
1392
1406
|
machine.close(@server.fileno)
|
|
1393
|
-
|
|
1407
|
+
machine.sleep(0.01)
|
|
1394
1408
|
refute done
|
|
1395
1409
|
|
|
1396
1410
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1397
|
-
|
|
1411
|
+
machine.sleep(0.01)
|
|
1398
1412
|
|
|
1399
1413
|
assert_equal 2, count
|
|
1400
1414
|
refute done
|
|
@@ -1402,6 +1416,35 @@ class AcceptEachTest < UMBaseTest
|
|
|
1402
1416
|
s.close rescue nil
|
|
1403
1417
|
end
|
|
1404
1418
|
|
|
1419
|
+
def test_accept_each_shutdown
|
|
1420
|
+
count = 0
|
|
1421
|
+
done = nil
|
|
1422
|
+
e = nil
|
|
1423
|
+
machine.spin do
|
|
1424
|
+
machine.accept_each(@server.fileno) do |fd|
|
|
1425
|
+
count += 1
|
|
1426
|
+
end
|
|
1427
|
+
rescue => e
|
|
1428
|
+
ensure
|
|
1429
|
+
done = true
|
|
1430
|
+
end
|
|
1431
|
+
|
|
1432
|
+
s = TCPSocket.new('127.0.0.1', @port)
|
|
1433
|
+
machine.sleep(0.01)
|
|
1434
|
+
|
|
1435
|
+
assert_equal 1, count
|
|
1436
|
+
refute done
|
|
1437
|
+
|
|
1438
|
+
machine.shutdown(@server.fileno, UM::SHUT_RD)
|
|
1439
|
+
machine.sleep(0.01)
|
|
1440
|
+
assert_equal true, done
|
|
1441
|
+
assert_nil e
|
|
1442
|
+
|
|
1443
|
+
assert_raises(Errno::ECONNREFUSED) { TCPSocket.new('127.0.0.1', @port) }
|
|
1444
|
+
ensure
|
|
1445
|
+
s.close rescue nil
|
|
1446
|
+
end
|
|
1447
|
+
|
|
1405
1448
|
def test_accept_each_bad_fd
|
|
1406
1449
|
assert_raises(Errno::ENOTSOCK) { machine.accept_each(STDOUT.fileno) }
|
|
1407
1450
|
|
|
@@ -1451,20 +1494,20 @@ class AcceptIntoQueueTest < UMBaseTest
|
|
|
1451
1494
|
def test_accept_into_queue_interrupted
|
|
1452
1495
|
terminated = nil
|
|
1453
1496
|
queue = UM::Queue.new
|
|
1454
|
-
f =
|
|
1497
|
+
f = machine.spin do
|
|
1455
1498
|
machine.accept_into_queue(@server_fd, queue)
|
|
1456
1499
|
rescue UM::Terminate
|
|
1457
1500
|
terminated = true
|
|
1458
1501
|
end
|
|
1459
1502
|
|
|
1460
1503
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1461
|
-
|
|
1504
|
+
machine.sleep(0.01)
|
|
1462
1505
|
|
|
1463
1506
|
assert_equal 1, queue.count
|
|
1464
1507
|
refute terminated
|
|
1465
1508
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1509
|
+
machine.schedule(f, UM::Terminate.new)
|
|
1510
|
+
machine.sleep(0.01)
|
|
1468
1511
|
|
|
1469
1512
|
assert f.done?
|
|
1470
1513
|
assert terminated
|
|
@@ -1475,6 +1518,36 @@ class AcceptIntoQueueTest < UMBaseTest
|
|
|
1475
1518
|
s.close
|
|
1476
1519
|
end
|
|
1477
1520
|
|
|
1521
|
+
def test_accept_into_queue_shutdown
|
|
1522
|
+
done = nil
|
|
1523
|
+
err = nil
|
|
1524
|
+
queue = UM::Queue.new
|
|
1525
|
+
f = machine.spin do
|
|
1526
|
+
machine.accept_into_queue(@server_fd, queue)
|
|
1527
|
+
rescue => err
|
|
1528
|
+
ensure
|
|
1529
|
+
done = true
|
|
1530
|
+
end
|
|
1531
|
+
|
|
1532
|
+
s = TCPSocket.new('127.0.0.1', @port)
|
|
1533
|
+
machine.sleep(0.01)
|
|
1534
|
+
|
|
1535
|
+
assert_equal 1, queue.count
|
|
1536
|
+
refute done
|
|
1537
|
+
|
|
1538
|
+
machine.shutdown(@server_fd, UM::SHUT_RD)
|
|
1539
|
+
machine.sleep(0.01)
|
|
1540
|
+
|
|
1541
|
+
assert f.done?
|
|
1542
|
+
assert done
|
|
1543
|
+
assert_nil err
|
|
1544
|
+
|
|
1545
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1546
|
+
assert_equal 256, machine.metrics[:ops_free]
|
|
1547
|
+
ensure
|
|
1548
|
+
s.close
|
|
1549
|
+
end
|
|
1550
|
+
|
|
1478
1551
|
def test_accept_into_queue_bad_fd
|
|
1479
1552
|
queue = UM::Queue.new
|
|
1480
1553
|
assert_raises(Errno::ENOTSOCK) { machine.accept_into_queue(STDOUT.fileno, queue) }
|
|
@@ -1664,8 +1737,8 @@ class SendvTest < UMBaseTest
|
|
|
1664
1737
|
end
|
|
1665
1738
|
|
|
1666
1739
|
def teardown
|
|
1667
|
-
|
|
1668
|
-
|
|
1740
|
+
machine.close(@s1)
|
|
1741
|
+
machine.close(@s2)
|
|
1669
1742
|
super
|
|
1670
1743
|
end
|
|
1671
1744
|
|
|
@@ -2082,7 +2155,7 @@ class SendRecvFdTest < UMBaseTest
|
|
|
2082
2155
|
end
|
|
2083
2156
|
|
|
2084
2157
|
buf = +''
|
|
2085
|
-
|
|
2158
|
+
|
|
2086
2159
|
machine.send(@s1_fd, 'coocoo', 6, 0)
|
|
2087
2160
|
machine.recv(@s1_fd, buf, 128, 0)
|
|
2088
2161
|
assert_equal 'coocoo', buf
|
|
@@ -2116,7 +2189,7 @@ class SendRecvFdTest < UMBaseTest
|
|
|
2116
2189
|
def test_recv_fd_bad_msg
|
|
2117
2190
|
buf = "\0" * 1000
|
|
2118
2191
|
machine.write(@s1_fd, buf)
|
|
2119
|
-
|
|
2192
|
+
|
|
2120
2193
|
assert_raises(Errno::EINVAL) {
|
|
2121
2194
|
res = machine.recv_fd(@s2_fd)
|
|
2122
2195
|
p res: res
|
|
@@ -2968,7 +3041,7 @@ class StatxTest < UMBaseTest
|
|
|
2968
3041
|
end
|
|
2969
3042
|
|
|
2970
3043
|
def test_statx_mask
|
|
2971
|
-
fd =
|
|
3044
|
+
fd = machine.open(__FILE__, UM::O_RDONLY)
|
|
2972
3045
|
ustat = machine.statx(fd, nil, UM::AT_EMPTY_PATH, UM::STATX_MTIME | UM::STATX_SIZE)
|
|
2973
3046
|
rstat = File.stat(__FILE__)
|
|
2974
3047
|
|
|
@@ -2977,7 +3050,7 @@ class StatxTest < UMBaseTest
|
|
|
2977
3050
|
assert_equal 0, machine.metrics[:ops_pending]
|
|
2978
3051
|
assert_equal 256, machine.metrics[:ops_free]
|
|
2979
3052
|
ensure
|
|
2980
|
-
|
|
3053
|
+
machine.close_async(fd)
|
|
2981
3054
|
end
|
|
2982
3055
|
|
|
2983
3056
|
def test_statx_bad_path
|
|
@@ -3082,15 +3155,20 @@ end
|
|
|
3082
3155
|
class MetricsTest < UMBaseTest
|
|
3083
3156
|
def test_metrics_empty
|
|
3084
3157
|
assert_equal({
|
|
3085
|
-
size:
|
|
3086
|
-
total_ops:
|
|
3087
|
-
total_switches:
|
|
3088
|
-
total_waits:
|
|
3089
|
-
ops_pending:
|
|
3090
|
-
ops_unsubmitted:
|
|
3091
|
-
ops_runqueue:
|
|
3092
|
-
ops_free:
|
|
3093
|
-
ops_transient:
|
|
3158
|
+
size: 4096,
|
|
3159
|
+
total_ops: 0,
|
|
3160
|
+
total_switches: 0,
|
|
3161
|
+
total_waits: 0,
|
|
3162
|
+
ops_pending: 0,
|
|
3163
|
+
ops_unsubmitted: 0,
|
|
3164
|
+
ops_runqueue: 0,
|
|
3165
|
+
ops_free: 0,
|
|
3166
|
+
ops_transient: 0,
|
|
3167
|
+
buffers_allocated: 0,
|
|
3168
|
+
buffers_free: 0,
|
|
3169
|
+
segments_free: 0,
|
|
3170
|
+
buffer_space_allocated: 0,
|
|
3171
|
+
buffer_space_commited: 0
|
|
3094
3172
|
}, machine.metrics)
|
|
3095
3173
|
end
|
|
3096
3174
|
|
|
@@ -3203,7 +3281,9 @@ class ProfileModeTest < UMBaseTest
|
|
|
3203
3281
|
assert_equal false, machine.profile_mode?
|
|
3204
3282
|
assert_equal([
|
|
3205
3283
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3206
|
-
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
3284
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3285
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3286
|
+
:buffer_space_allocated, :buffer_space_commited
|
|
3207
3287
|
], machine.metrics.keys)
|
|
3208
3288
|
|
|
3209
3289
|
machine.profile_mode = true
|
|
@@ -3211,6 +3291,8 @@ class ProfileModeTest < UMBaseTest
|
|
|
3211
3291
|
assert_equal([
|
|
3212
3292
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3213
3293
|
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3294
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3295
|
+
:buffer_space_allocated, :buffer_space_commited,
|
|
3214
3296
|
:time_total_cpu, :time_total_wait,
|
|
3215
3297
|
], machine.metrics.keys)
|
|
3216
3298
|
|
|
@@ -3218,7 +3300,9 @@ class ProfileModeTest < UMBaseTest
|
|
|
3218
3300
|
assert_equal false, machine.profile_mode?
|
|
3219
3301
|
assert_equal([
|
|
3220
3302
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3221
|
-
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
3303
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3304
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3305
|
+
:buffer_space_allocated, :buffer_space_commited
|
|
3222
3306
|
], machine.metrics.keys)
|
|
3223
3307
|
end
|
|
3224
3308
|
|
|
@@ -3390,7 +3474,7 @@ class SetChildSubreaperTest < Minitest::Test
|
|
|
3390
3474
|
def test_pr_set_child_subreaper
|
|
3391
3475
|
r, w = IO.pipe
|
|
3392
3476
|
UM.pr_set_child_subreaper(true)
|
|
3393
|
-
|
|
3477
|
+
|
|
3394
3478
|
child_pid = fork {
|
|
3395
3479
|
r2, w2 = IO.pipe
|
|
3396
3480
|
pid = fork {
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: uringmachine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.29.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sharon Rosner
|
|
@@ -24,7 +24,7 @@ extra_rdoc_files:
|
|
|
24
24
|
- ext/um/um.h
|
|
25
25
|
- ext/um/um_async_op.c
|
|
26
26
|
- ext/um/um_async_op_class.c
|
|
27
|
-
- ext/um/
|
|
27
|
+
- ext/um/um_buffer_pool.c
|
|
28
28
|
- ext/um/um_class.c
|
|
29
29
|
- ext/um/um_const.c
|
|
30
30
|
- ext/um/um_ext.c
|
|
@@ -66,6 +66,8 @@ files:
|
|
|
66
66
|
- benchmark/chart_bm_io_pipe_x.png
|
|
67
67
|
- benchmark/common.rb
|
|
68
68
|
- benchmark/dns_client.rb
|
|
69
|
+
- benchmark/gets.rb
|
|
70
|
+
- benchmark/gets_concurrent.rb
|
|
69
71
|
- benchmark/http_parse.rb
|
|
70
72
|
- benchmark/http_server_accept_queue.rb
|
|
71
73
|
- benchmark/http_server_multi_accept.rb
|
|
@@ -76,7 +78,7 @@ files:
|
|
|
76
78
|
- benchmark/mutex_single.rb
|
|
77
79
|
- benchmark/openssl.rb
|
|
78
80
|
- benchmark/openssl_socketpair.rb
|
|
79
|
-
- benchmark/
|
|
81
|
+
- benchmark/output.rb
|
|
80
82
|
- benchmark/run_bm.rb
|
|
81
83
|
- benchmark/send.rb
|
|
82
84
|
- benchmark/snooze.rb
|
|
@@ -104,7 +106,7 @@ files:
|
|
|
104
106
|
- ext/um/um.h
|
|
105
107
|
- ext/um/um_async_op.c
|
|
106
108
|
- ext/um/um_async_op_class.c
|
|
107
|
-
- ext/um/
|
|
109
|
+
- ext/um/um_buffer_pool.c
|
|
108
110
|
- ext/um/um_class.c
|
|
109
111
|
- ext/um/um_const.c
|
|
110
112
|
- ext/um/um_ext.c
|
data/ext/um/um_buffer.c
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#include "um.h"
|
|
2
|
-
|
|
3
|
-
inline long buffer_size(long len) {
|
|
4
|
-
len--;
|
|
5
|
-
len |= len >> 1;
|
|
6
|
-
len |= len >> 2;
|
|
7
|
-
len |= len >> 4;
|
|
8
|
-
len |= len >> 8;
|
|
9
|
-
len |= len >> 16;
|
|
10
|
-
len++;
|
|
11
|
-
return (len > 4096) ? len : 4096;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
inline struct um_buffer *um_buffer_checkout(struct um *machine, int len) {
|
|
15
|
-
struct um_buffer *buffer = machine->buffer_freelist;
|
|
16
|
-
if (buffer)
|
|
17
|
-
machine->buffer_freelist = buffer->next;
|
|
18
|
-
else {
|
|
19
|
-
buffer = malloc(sizeof(struct um_buffer));
|
|
20
|
-
memset(buffer, 0, sizeof(struct um_buffer));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (buffer->len < len) {
|
|
24
|
-
if (buffer->ptr) {
|
|
25
|
-
free(buffer->ptr);
|
|
26
|
-
buffer->ptr = NULL;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
buffer->len = buffer_size(len);
|
|
30
|
-
if (posix_memalign(&buffer->ptr, 4096, buffer->len))
|
|
31
|
-
um_raise_internal_error("Failed to allocate buffer");
|
|
32
|
-
}
|
|
33
|
-
return buffer;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
inline void um_buffer_checkin(struct um *machine, struct um_buffer *buffer) {
|
|
37
|
-
buffer->next = machine->buffer_freelist;
|
|
38
|
-
machine->buffer_freelist = buffer;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
inline void um_free_buffer_linked_list(struct um *machine) {
|
|
42
|
-
struct um_buffer *buffer = machine->buffer_freelist;
|
|
43
|
-
while (buffer) {
|
|
44
|
-
struct um_buffer *next = buffer->next;
|
|
45
|
-
if (buffer->ptr) free(buffer->ptr);
|
|
46
|
-
free(buffer);
|
|
47
|
-
buffer = next;
|
|
48
|
-
}
|
|
49
|
-
}
|