uringmachine 0.28.3 → 0.29.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 +4 -4
- data/CHANGELOG.md +10 -1
- data/TODO.md +29 -35
- data/benchmark/common.rb +6 -6
- data/benchmark/gets.rb +49 -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 +42 -13
- data/ext/um/um.h +103 -31
- data/ext/um/um_buffer_pool.c +246 -0
- data/ext/um/um_class.c +24 -12
- data/ext/um/um_op.c +29 -13
- data/ext/um/um_ssl.c +24 -27
- data/ext/um/um_stream.c +380 -150
- data/ext/um/um_stream_class.c +119 -63
- data/ext/um/um_utils.c +6 -6
- data/grant-2025/tasks.md +12 -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 +2 -0
- data/test/test_fiber.rb +93 -12
- data/test/test_fiber_scheduler.rb +5 -47
- data/test/test_stream.rb +447 -125
- data/test/test_um.rb +119 -49
- metadata +5 -4
- data/ext/um/um_buffer.c +0 -49
data/test/test_um.rb
CHANGED
|
@@ -1222,63 +1222,63 @@ end
|
|
|
1222
1222
|
class ShutdownTest < UMBaseTest
|
|
1223
1223
|
def test_shutdown
|
|
1224
1224
|
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
1225
|
-
res =
|
|
1225
|
+
res = machine.send(c_fd, 'abc', 3, 0)
|
|
1226
1226
|
assert_equal 3, res
|
|
1227
1227
|
|
|
1228
1228
|
buf = +''
|
|
1229
|
-
res =
|
|
1229
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1230
1230
|
assert_equal 3, res
|
|
1231
1231
|
assert_equal 'abc', buf
|
|
1232
1232
|
|
|
1233
|
-
res =
|
|
1233
|
+
res = machine.shutdown(c_fd, UM::SHUT_WR)
|
|
1234
1234
|
assert_equal 0, res
|
|
1235
1235
|
|
|
1236
|
-
assert_raises(Errno::EPIPE) {
|
|
1236
|
+
assert_raises(Errno::EPIPE) { machine.send(c_fd, 'abc', 3, 0) }
|
|
1237
1237
|
|
|
1238
|
-
res =
|
|
1238
|
+
res = machine.shutdown(s_fd, UM::SHUT_RD)
|
|
1239
1239
|
assert_equal 0, res
|
|
1240
1240
|
|
|
1241
|
-
res =
|
|
1241
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1242
1242
|
assert_equal 0, res
|
|
1243
1243
|
|
|
1244
|
-
res =
|
|
1244
|
+
res = machine.shutdown(c_fd, UM::SHUT_RDWR)
|
|
1245
1245
|
assert_equal 0, res
|
|
1246
1246
|
|
|
1247
|
-
assert_raises(Errno::EINVAL) {
|
|
1247
|
+
assert_raises(Errno::EINVAL) { machine.shutdown(c_fd, -9999) }
|
|
1248
1248
|
ensure
|
|
1249
|
-
|
|
1250
|
-
|
|
1249
|
+
machine.close(c_fd)
|
|
1250
|
+
machine.close(s_fd)
|
|
1251
1251
|
end
|
|
1252
1252
|
end
|
|
1253
1253
|
|
|
1254
1254
|
class ShutdownAsyncTest < UMBaseTest
|
|
1255
1255
|
def test_shutdown_async
|
|
1256
1256
|
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
1257
|
-
res =
|
|
1257
|
+
res = machine.send(c_fd, 'abc', 3, 0)
|
|
1258
1258
|
assert_equal 3, res
|
|
1259
1259
|
|
|
1260
1260
|
buf = +''
|
|
1261
|
-
res =
|
|
1261
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1262
1262
|
assert_equal 3, res
|
|
1263
1263
|
assert_equal 'abc', buf
|
|
1264
1264
|
|
|
1265
|
-
res =
|
|
1265
|
+
res = machine.shutdown_async(c_fd, UM::SHUT_WR)
|
|
1266
1266
|
assert_equal c_fd, res
|
|
1267
1267
|
|
|
1268
1268
|
machine.sleep(0.01)
|
|
1269
|
-
assert_raises(Errno::EPIPE) {
|
|
1269
|
+
assert_raises(Errno::EPIPE) { machine.send(c_fd, 'abc', 3, 0) }
|
|
1270
1270
|
|
|
1271
|
-
res =
|
|
1271
|
+
res = machine.shutdown_async(s_fd, UM::SHUT_RD)
|
|
1272
1272
|
assert_equal s_fd, res
|
|
1273
1273
|
|
|
1274
|
-
res =
|
|
1274
|
+
res = machine.recv(s_fd, buf, 256, 0)
|
|
1275
1275
|
assert_equal 0, res
|
|
1276
1276
|
|
|
1277
|
-
res =
|
|
1277
|
+
res = machine.shutdown_async(c_fd, UM::SHUT_RDWR)
|
|
1278
1278
|
assert_equal c_fd, res
|
|
1279
1279
|
ensure
|
|
1280
|
-
|
|
1281
|
-
|
|
1280
|
+
machine.close(c_fd)
|
|
1281
|
+
machine.close(s_fd)
|
|
1282
1282
|
end
|
|
1283
1283
|
end
|
|
1284
1284
|
|
|
@@ -1345,7 +1345,7 @@ class AcceptEachTest < UMBaseTest
|
|
|
1345
1345
|
def test_accept_each_interrupted
|
|
1346
1346
|
count = 0
|
|
1347
1347
|
terminated = nil
|
|
1348
|
-
f =
|
|
1348
|
+
f = machine.spin do
|
|
1349
1349
|
machine.accept_each(@server.fileno) do |fd|
|
|
1350
1350
|
count += 1
|
|
1351
1351
|
break if count == 3
|
|
@@ -1355,13 +1355,13 @@ class AcceptEachTest < UMBaseTest
|
|
|
1355
1355
|
end
|
|
1356
1356
|
|
|
1357
1357
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1358
|
-
|
|
1358
|
+
machine.sleep(0.01)
|
|
1359
1359
|
|
|
1360
1360
|
assert_equal 1, count
|
|
1361
1361
|
refute terminated
|
|
1362
1362
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1363
|
+
machine.schedule(f, UM::Terminate.new)
|
|
1364
|
+
machine.sleep(0.01)
|
|
1365
1365
|
|
|
1366
1366
|
assert f.done?
|
|
1367
1367
|
assert terminated
|
|
@@ -1375,7 +1375,7 @@ class AcceptEachTest < UMBaseTest
|
|
|
1375
1375
|
def test_accept_each_closed
|
|
1376
1376
|
count = 0
|
|
1377
1377
|
done = nil
|
|
1378
|
-
|
|
1378
|
+
machine.spin do
|
|
1379
1379
|
machine.accept_each(@server.fileno) do |fd|
|
|
1380
1380
|
count += 1
|
|
1381
1381
|
end
|
|
@@ -1384,17 +1384,17 @@ class AcceptEachTest < UMBaseTest
|
|
|
1384
1384
|
end
|
|
1385
1385
|
|
|
1386
1386
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1387
|
-
|
|
1387
|
+
machine.sleep(0.01)
|
|
1388
1388
|
|
|
1389
1389
|
assert_equal 1, count
|
|
1390
1390
|
refute done
|
|
1391
1391
|
|
|
1392
1392
|
machine.close(@server.fileno)
|
|
1393
|
-
|
|
1393
|
+
machine.sleep(0.01)
|
|
1394
1394
|
refute done
|
|
1395
1395
|
|
|
1396
1396
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1397
|
-
|
|
1397
|
+
machine.sleep(0.01)
|
|
1398
1398
|
|
|
1399
1399
|
assert_equal 2, count
|
|
1400
1400
|
refute done
|
|
@@ -1402,6 +1402,35 @@ class AcceptEachTest < UMBaseTest
|
|
|
1402
1402
|
s.close rescue nil
|
|
1403
1403
|
end
|
|
1404
1404
|
|
|
1405
|
+
def test_accept_each_shutdown
|
|
1406
|
+
count = 0
|
|
1407
|
+
done = nil
|
|
1408
|
+
e = nil
|
|
1409
|
+
machine.spin do
|
|
1410
|
+
machine.accept_each(@server.fileno) do |fd|
|
|
1411
|
+
count += 1
|
|
1412
|
+
end
|
|
1413
|
+
rescue => e
|
|
1414
|
+
ensure
|
|
1415
|
+
done = true
|
|
1416
|
+
end
|
|
1417
|
+
|
|
1418
|
+
s = TCPSocket.new('127.0.0.1', @port)
|
|
1419
|
+
machine.sleep(0.01)
|
|
1420
|
+
|
|
1421
|
+
assert_equal 1, count
|
|
1422
|
+
refute done
|
|
1423
|
+
|
|
1424
|
+
machine.shutdown(@server.fileno, UM::SHUT_RD)
|
|
1425
|
+
machine.sleep(0.01)
|
|
1426
|
+
assert_equal true, done
|
|
1427
|
+
assert_nil e
|
|
1428
|
+
|
|
1429
|
+
assert_raises(Errno::ECONNREFUSED) { TCPSocket.new('127.0.0.1', @port) }
|
|
1430
|
+
ensure
|
|
1431
|
+
s.close rescue nil
|
|
1432
|
+
end
|
|
1433
|
+
|
|
1405
1434
|
def test_accept_each_bad_fd
|
|
1406
1435
|
assert_raises(Errno::ENOTSOCK) { machine.accept_each(STDOUT.fileno) }
|
|
1407
1436
|
|
|
@@ -1451,20 +1480,20 @@ class AcceptIntoQueueTest < UMBaseTest
|
|
|
1451
1480
|
def test_accept_into_queue_interrupted
|
|
1452
1481
|
terminated = nil
|
|
1453
1482
|
queue = UM::Queue.new
|
|
1454
|
-
f =
|
|
1483
|
+
f = machine.spin do
|
|
1455
1484
|
machine.accept_into_queue(@server_fd, queue)
|
|
1456
1485
|
rescue UM::Terminate
|
|
1457
1486
|
terminated = true
|
|
1458
1487
|
end
|
|
1459
1488
|
|
|
1460
1489
|
s = TCPSocket.new('127.0.0.1', @port)
|
|
1461
|
-
|
|
1490
|
+
machine.sleep(0.01)
|
|
1462
1491
|
|
|
1463
1492
|
assert_equal 1, queue.count
|
|
1464
1493
|
refute terminated
|
|
1465
1494
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1495
|
+
machine.schedule(f, UM::Terminate.new)
|
|
1496
|
+
machine.sleep(0.01)
|
|
1468
1497
|
|
|
1469
1498
|
assert f.done?
|
|
1470
1499
|
assert terminated
|
|
@@ -1475,6 +1504,36 @@ class AcceptIntoQueueTest < UMBaseTest
|
|
|
1475
1504
|
s.close
|
|
1476
1505
|
end
|
|
1477
1506
|
|
|
1507
|
+
def test_accept_into_queue_shutdown
|
|
1508
|
+
done = nil
|
|
1509
|
+
err = nil
|
|
1510
|
+
queue = UM::Queue.new
|
|
1511
|
+
f = machine.spin do
|
|
1512
|
+
machine.accept_into_queue(@server_fd, queue)
|
|
1513
|
+
rescue => err
|
|
1514
|
+
ensure
|
|
1515
|
+
done = true
|
|
1516
|
+
end
|
|
1517
|
+
|
|
1518
|
+
s = TCPSocket.new('127.0.0.1', @port)
|
|
1519
|
+
machine.sleep(0.01)
|
|
1520
|
+
|
|
1521
|
+
assert_equal 1, queue.count
|
|
1522
|
+
refute done
|
|
1523
|
+
|
|
1524
|
+
machine.shutdown(@server_fd, UM::SHUT_RD)
|
|
1525
|
+
machine.sleep(0.01)
|
|
1526
|
+
|
|
1527
|
+
assert f.done?
|
|
1528
|
+
assert done
|
|
1529
|
+
assert_nil err
|
|
1530
|
+
|
|
1531
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1532
|
+
assert_equal 256, machine.metrics[:ops_free]
|
|
1533
|
+
ensure
|
|
1534
|
+
s.close
|
|
1535
|
+
end
|
|
1536
|
+
|
|
1478
1537
|
def test_accept_into_queue_bad_fd
|
|
1479
1538
|
queue = UM::Queue.new
|
|
1480
1539
|
assert_raises(Errno::ENOTSOCK) { machine.accept_into_queue(STDOUT.fileno, queue) }
|
|
@@ -1664,8 +1723,8 @@ class SendvTest < UMBaseTest
|
|
|
1664
1723
|
end
|
|
1665
1724
|
|
|
1666
1725
|
def teardown
|
|
1667
|
-
|
|
1668
|
-
|
|
1726
|
+
machine.close(@s1)
|
|
1727
|
+
machine.close(@s2)
|
|
1669
1728
|
super
|
|
1670
1729
|
end
|
|
1671
1730
|
|
|
@@ -2082,7 +2141,7 @@ class SendRecvFdTest < UMBaseTest
|
|
|
2082
2141
|
end
|
|
2083
2142
|
|
|
2084
2143
|
buf = +''
|
|
2085
|
-
|
|
2144
|
+
|
|
2086
2145
|
machine.send(@s1_fd, 'coocoo', 6, 0)
|
|
2087
2146
|
machine.recv(@s1_fd, buf, 128, 0)
|
|
2088
2147
|
assert_equal 'coocoo', buf
|
|
@@ -2116,7 +2175,7 @@ class SendRecvFdTest < UMBaseTest
|
|
|
2116
2175
|
def test_recv_fd_bad_msg
|
|
2117
2176
|
buf = "\0" * 1000
|
|
2118
2177
|
machine.write(@s1_fd, buf)
|
|
2119
|
-
|
|
2178
|
+
|
|
2120
2179
|
assert_raises(Errno::EINVAL) {
|
|
2121
2180
|
res = machine.recv_fd(@s2_fd)
|
|
2122
2181
|
p res: res
|
|
@@ -2968,7 +3027,7 @@ class StatxTest < UMBaseTest
|
|
|
2968
3027
|
end
|
|
2969
3028
|
|
|
2970
3029
|
def test_statx_mask
|
|
2971
|
-
fd =
|
|
3030
|
+
fd = machine.open(__FILE__, UM::O_RDONLY)
|
|
2972
3031
|
ustat = machine.statx(fd, nil, UM::AT_EMPTY_PATH, UM::STATX_MTIME | UM::STATX_SIZE)
|
|
2973
3032
|
rstat = File.stat(__FILE__)
|
|
2974
3033
|
|
|
@@ -2977,7 +3036,7 @@ class StatxTest < UMBaseTest
|
|
|
2977
3036
|
assert_equal 0, machine.metrics[:ops_pending]
|
|
2978
3037
|
assert_equal 256, machine.metrics[:ops_free]
|
|
2979
3038
|
ensure
|
|
2980
|
-
|
|
3039
|
+
machine.close_async(fd)
|
|
2981
3040
|
end
|
|
2982
3041
|
|
|
2983
3042
|
def test_statx_bad_path
|
|
@@ -3082,15 +3141,20 @@ end
|
|
|
3082
3141
|
class MetricsTest < UMBaseTest
|
|
3083
3142
|
def test_metrics_empty
|
|
3084
3143
|
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:
|
|
3144
|
+
size: 4096,
|
|
3145
|
+
total_ops: 0,
|
|
3146
|
+
total_switches: 0,
|
|
3147
|
+
total_waits: 0,
|
|
3148
|
+
ops_pending: 0,
|
|
3149
|
+
ops_unsubmitted: 0,
|
|
3150
|
+
ops_runqueue: 0,
|
|
3151
|
+
ops_free: 0,
|
|
3152
|
+
ops_transient: 0,
|
|
3153
|
+
buffers_allocated: 0,
|
|
3154
|
+
buffers_free: 0,
|
|
3155
|
+
segments_free: 0,
|
|
3156
|
+
buffer_space_allocated: 0,
|
|
3157
|
+
buffer_space_commited: 0
|
|
3094
3158
|
}, machine.metrics)
|
|
3095
3159
|
end
|
|
3096
3160
|
|
|
@@ -3203,7 +3267,9 @@ class ProfileModeTest < UMBaseTest
|
|
|
3203
3267
|
assert_equal false, machine.profile_mode?
|
|
3204
3268
|
assert_equal([
|
|
3205
3269
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3206
|
-
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
3270
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3271
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3272
|
+
:buffer_space_allocated, :buffer_space_commited
|
|
3207
3273
|
], machine.metrics.keys)
|
|
3208
3274
|
|
|
3209
3275
|
machine.profile_mode = true
|
|
@@ -3211,6 +3277,8 @@ class ProfileModeTest < UMBaseTest
|
|
|
3211
3277
|
assert_equal([
|
|
3212
3278
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3213
3279
|
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3280
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3281
|
+
:buffer_space_allocated, :buffer_space_commited,
|
|
3214
3282
|
:time_total_cpu, :time_total_wait,
|
|
3215
3283
|
], machine.metrics.keys)
|
|
3216
3284
|
|
|
@@ -3218,7 +3286,9 @@ class ProfileModeTest < UMBaseTest
|
|
|
3218
3286
|
assert_equal false, machine.profile_mode?
|
|
3219
3287
|
assert_equal([
|
|
3220
3288
|
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
3221
|
-
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
3289
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
3290
|
+
:buffers_allocated, :buffers_free, :segments_free,
|
|
3291
|
+
:buffer_space_allocated, :buffer_space_commited
|
|
3222
3292
|
], machine.metrics.keys)
|
|
3223
3293
|
end
|
|
3224
3294
|
|
|
@@ -3390,7 +3460,7 @@ class SetChildSubreaperTest < Minitest::Test
|
|
|
3390
3460
|
def test_pr_set_child_subreaper
|
|
3391
3461
|
r, w = IO.pipe
|
|
3392
3462
|
UM.pr_set_child_subreaper(true)
|
|
3393
|
-
|
|
3463
|
+
|
|
3394
3464
|
child_pid = fork {
|
|
3395
3465
|
r2, w2 = IO.pipe
|
|
3396
3466
|
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.0
|
|
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,7 @@ 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
|
|
69
70
|
- benchmark/http_parse.rb
|
|
70
71
|
- benchmark/http_server_accept_queue.rb
|
|
71
72
|
- benchmark/http_server_multi_accept.rb
|
|
@@ -76,7 +77,7 @@ files:
|
|
|
76
77
|
- benchmark/mutex_single.rb
|
|
77
78
|
- benchmark/openssl.rb
|
|
78
79
|
- benchmark/openssl_socketpair.rb
|
|
79
|
-
- benchmark/
|
|
80
|
+
- benchmark/output.rb
|
|
80
81
|
- benchmark/run_bm.rb
|
|
81
82
|
- benchmark/send.rb
|
|
82
83
|
- benchmark/snooze.rb
|
|
@@ -104,7 +105,7 @@ files:
|
|
|
104
105
|
- ext/um/um.h
|
|
105
106
|
- ext/um/um_async_op.c
|
|
106
107
|
- ext/um/um_async_op_class.c
|
|
107
|
-
- ext/um/
|
|
108
|
+
- ext/um/um_buffer_pool.c
|
|
108
109
|
- ext/um/um_class.c
|
|
109
110
|
- ext/um/um_const.c
|
|
110
111
|
- 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
|
-
}
|