arbiter_machines 0.1.5-aarch64-linux
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/CHANGELOG.md +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +221 -0
- data/ext/arbiter_machines_native/core/CHANGELOG.md +22 -0
- data/ext/arbiter_machines_native/core/README.md +20 -0
- data/ext/arbiter_machines_native/extconf.rb +3 -0
- data/lib/arbiter_machines/version.rb +5 -0
- data/lib/arbiter_machines.rb +4 -0
- data/lib/arbiter_machines_native/arbiter_machines_native.so +0 -0
- data/sig/arbiter_machines.rbs +12 -0
- metadata +62 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3ec1cc02077cd0a3484e47dec1d2bfe3139db4b295f2a083322404bb476c2462
|
|
4
|
+
data.tar.gz: d364fa500c077c33a03f80615e857fb45e75b9e8cfec8a814a24783c6d1de895
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7b7ad6b35d3e98b4e9bbf712334186db2642e129d5c31be9b819ea672f4b21784d3ac1d387af65895a1a1a5700e3ebae03814de42eb1df2dbdc052c73955a850
|
|
7
|
+
data.tar.gz: 484ab97b811be4da0aca64ec75fcf920a722bac9c18e611759fe437aa69a1fe880eca425c95b852e027718c1a4fd198c5f5e5895e8740de1e38c3d0964452011
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.5](https://github.com/seuros/arbiter_machines/compare/arbiter_machines/v0.1.4...arbiter_machines/v0.1.5) (2026-11-06)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* share RArray count conversion in arbiter ffi ([0a026aa](https://github.com/seuros/arbiter_machines/commit/0a026aac2e17efecc2546bb8b9532b89f516e7f0))
|
|
9
|
+
|
|
10
|
+
## [0.1.4](https://github.com/seuros/arbiter_machines/compare/arbiter_machines/v0.1.3...arbiter_machines/v0.1.4) (2026-11-06)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* crates.io keywords and categories for the core ([10c8cad](https://github.com/seuros/arbiter_machines/commit/10c8cad0f35cb6c44dbe0e5573275f2267afc306))
|
|
16
|
+
|
|
17
|
+
## [0.1.3](https://github.com/seuros/arbiter_machines/compare/arbiter_machines/v0.1.2...arbiter_machines/v0.1.3) (2026-11-06)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* keep test sources out of the packaged gem and crate ([513f507](https://github.com/seuros/arbiter_machines/commit/513f5074a2058f23742ee47b2289cd8b8872d6d3))
|
|
23
|
+
|
|
24
|
+
## [0.1.2](https://github.com/seuros/arbiter_machines/compare/arbiter_machines/v0.1.1...arbiter_machines/v0.1.2) (2026-11-06)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* cross builds no longer compile for the host ([feeb4f0](https://github.com/seuros/arbiter_machines/commit/feeb4f09e5d0b20b81a3fffb35562594b80e2e0a))
|
|
30
|
+
|
|
31
|
+
## [0.1.1](https://github.com/seuros/arbiter_machines/compare/arbiter_machines-v0.1.0...arbiter_machines/v0.1.1) (2026-11-06)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Features
|
|
35
|
+
|
|
36
|
+
* initial extraction ([0ce828b](https://github.com/seuros/arbiter_machines/commit/0ce828bfacd5c9ef7482136b73d7be18339e19b9))
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abdelkader Boudih
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# ArbiterMachines
|
|
2
|
+
|
|
3
|
+
> When the slow job holds the key the urgent job needs, more workers won't help. 🛰️
|
|
4
|
+
|
|
5
|
+
A priority arbiter for Ruby. You declare your tasks with their priorities and your resources with their ceilings. The `Arbiter` tells you who may take what, who has to wait, who just inherited someone else's urgency, and who is about to deadlock. Your code still takes and releases the actual locks. The arbiter only ever answers one question: is this a good idea right now?
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gem 'arbiter_machines'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
# Two tasks: a janitor at priority 1, a payment at priority 10.
|
|
15
|
+
# One resource: the ledger lock, ceiling 10.
|
|
16
|
+
arbiter = ArbiterMachines::Arbiter.new(
|
|
17
|
+
priorities: [1, 10],
|
|
18
|
+
ceilings: [10],
|
|
19
|
+
protocol: :inheritance
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
arbiter.acquire(task: 0, resource: 0) # => [:granted, nil] janitor takes the ledger
|
|
23
|
+
arbiter.acquire(task: 1, resource: 0) # => [:blocked, 0] payment waits on resource 0
|
|
24
|
+
arbiter.effective_priorities # => [10, 10] janitor now runs as urgent
|
|
25
|
+
|
|
26
|
+
arbiter.release(task: 0, resource: 0) # => true janitor done, wait cleared
|
|
27
|
+
arbiter.acquire(task: 1, resource: 0) # => [:granted, nil] payment retries and gets in
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Tasks and resources are positional indices into the arrays you passed in. Larger number means more urgent.
|
|
31
|
+
|
|
32
|
+
## A Message to the Resistance
|
|
33
|
+
|
|
34
|
+
So you gave the nightly cleanup job priority 1, the payment processor priority 10, and a pile of report builders priority 5. Sensible. Then one night the cleanup job took the ledger lock for a quick vacuum, the payment job arrived and blocked on it, and twelve report builders showed up and ran. All of them. Before the cleanup job got another slice of CPU.
|
|
35
|
+
|
|
36
|
+
The payment job, your most urgent work, sat behind priority-5 reports because a priority-1 job was holding its lock and nobody told the scheduler that the priority-1 job was suddenly very important.
|
|
37
|
+
|
|
38
|
+
That's priority inversion. It put a rover on Mars into a reboot loop in 1997, and it's been quietly doing the same thing to job queues ever since. The fix has been known just as long: while the janitor holds something the payment job needs, the janitor *is* the payment job. It inherits the urgency, finishes fast, hands the lock over.
|
|
39
|
+
|
|
40
|
+
This gem does the accounting for that. Who holds what, who waits on whom, what everybody's priority really is right now, and whether the next acquire closes a loop nobody can escape from.
|
|
41
|
+
|
|
42
|
+
## Chapter 1: Stardate 2025.186, the AMS Dijkstra
|
|
43
|
+
|
|
44
|
+
> **AMS Dijkstra**, NCC-4201, *Dijkstra*-class traffic-control vessel.
|
|
45
|
+
> One airlock. Two waiting crews. No circular holding pattern.
|
|
46
|
+
|
|
47
|
+
The vessel doesn't open airlocks. It keeps the chart: which crew is in which lock, which crew is waiting at which door, and which crew's urgency has been lent to the crew blocking it. Before any crew is cleared to wait, the chart is checked for a loop. A loop is never charted, because a charted loop is a ship nobody leaves.
|
|
48
|
+
|
|
49
|
+
Somewhere on the bridge, a junior officer suggests:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
def process_payment
|
|
53
|
+
ledger_lock.synchronize do # the janitor has this, and the janitor is slow
|
|
54
|
+
charge_card
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
"That," says the traffic controller, "is how urgent work waits for the floor to be mopped."
|
|
60
|
+
|
|
61
|
+
## The Flight Plan
|
|
62
|
+
|
|
63
|
+
Every resource is either free or held. Every task is either running, holding, or waiting at exactly one door.
|
|
64
|
+
|
|
65
|
+
```mermaid
|
|
66
|
+
stateDiagram-v2
|
|
67
|
+
[*] --> free
|
|
68
|
+
free --> held: acquire, granted
|
|
69
|
+
held --> held: holder acquires again, already_owned
|
|
70
|
+
held --> held: other task acquires, blocked (holder inherits urgency)
|
|
71
|
+
held --> free: holder releases, waiters cleared to retry
|
|
72
|
+
held --> held: acquire would close a wait loop, deadlock (nothing changes)
|
|
73
|
+
free --> [*]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
And the night the janitor held the ledger:
|
|
77
|
+
|
|
78
|
+
```mermaid
|
|
79
|
+
sequenceDiagram
|
|
80
|
+
participant J as Janitor (task 0, prio 1)
|
|
81
|
+
participant A as Arbiter
|
|
82
|
+
participant P as Payment (task 1, prio 10)
|
|
83
|
+
|
|
84
|
+
J->>A: acquire(task 0, resource 0)
|
|
85
|
+
A-->>J: granted
|
|
86
|
+
Note over J: starts vacuuming the ledger
|
|
87
|
+
|
|
88
|
+
P->>A: acquire(task 1, resource 0)
|
|
89
|
+
A-->>P: blocked on resource 0
|
|
90
|
+
Note over A: effective priorities now [10, 10]
|
|
91
|
+
Note over J: runs as priority 10, no report builder gets ahead
|
|
92
|
+
|
|
93
|
+
J->>A: release(task 0, resource 0)
|
|
94
|
+
A-->>J: true
|
|
95
|
+
Note over A: effective priorities back to [1, 10], wait cleared
|
|
96
|
+
|
|
97
|
+
P->>A: acquire(task 1, resource 0)
|
|
98
|
+
A-->>P: granted
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## How Arbitration Works
|
|
102
|
+
|
|
103
|
+
### Acquire
|
|
104
|
+
|
|
105
|
+
`acquire` returns a two-element array: a status and, when blocked, the resource index you're waiting on.
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
arbiter = ArbiterMachines::Arbiter.new(
|
|
109
|
+
priorities: [1, 5, 10], ceilings: [10, 10], protocol: :inheritance
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
arbiter.acquire(task: 0, resource: 0) # => [:granted, nil]
|
|
113
|
+
arbiter.acquire(task: 0, resource: 0) # => [:already_owned, nil]
|
|
114
|
+
arbiter.acquire(task: 1, resource: 1) # => [:granted, nil]
|
|
115
|
+
arbiter.acquire(task: 1, resource: 0) # => [:blocked, 0]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Task 1 now holds resource 1 and is waiting on resource 0, which task 0 holds.
|
|
119
|
+
|
|
120
|
+
### Inheritance is transitive
|
|
121
|
+
|
|
122
|
+
Urgency flows up the chain. If a third task waits on task 1, task 1 gets its priority, and so does task 0 behind it.
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
arbiter.acquire(task: 2, resource: 1) # => [:blocked, 1]
|
|
126
|
+
arbiter.effective_priorities # => [10, 10, 10]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Task 2, priority 10, waits on task 1. Task 1 waits on task 0. Everybody in the chain runs at 10 until the chain clears.
|
|
130
|
+
|
|
131
|
+
### Release and retry
|
|
132
|
+
|
|
133
|
+
Releasing clears the waits on that resource. It does not hand the resource to anyone. The waiters call `acquire` again, and the arbiter decides fresh.
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
arbiter.release(task: 0, resource: 0) # => true
|
|
137
|
+
arbiter.effective_priorities # => [1, 10, 10] task 1 still blocks task 2
|
|
138
|
+
arbiter.acquire(task: 1, resource: 0) # => [:granted, nil]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Release by a task that doesn't hold the resource returns `false` and changes nothing.
|
|
142
|
+
|
|
143
|
+
### Stop waiting
|
|
144
|
+
|
|
145
|
+
A task that gives up on a door calls `cancel_wait`. Its held resources stay held. Only the wait is dropped, and the urgency it was lending goes with it.
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
arbiter = ArbiterMachines::Arbiter.new(
|
|
149
|
+
priorities: [1, 5, 10], ceilings: [10, 10], protocol: :inheritance
|
|
150
|
+
)
|
|
151
|
+
arbiter.acquire(task: 0, resource: 0)
|
|
152
|
+
arbiter.acquire(task: 2, resource: 0) # => [:blocked, 0]
|
|
153
|
+
arbiter.effective_priorities # => [10, 5, 10]
|
|
154
|
+
|
|
155
|
+
arbiter.cancel_wait(task: 2) # => true
|
|
156
|
+
arbiter.effective_priorities # => [1, 5, 10]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Deadlock is refused, not reported after the fact
|
|
160
|
+
|
|
161
|
+
Two tasks each holding what the other wants is a loop. The arbiter sees it before charting the second wait and returns `:deadlock`. Nothing about the current state changes, so you can back out cleanly.
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
arbiter = ArbiterMachines::Arbiter.new(
|
|
165
|
+
priorities: [1, 5, 10], ceilings: [10, 10], protocol: :inheritance
|
|
166
|
+
)
|
|
167
|
+
arbiter.acquire(task: 0, resource: 0)
|
|
168
|
+
arbiter.acquire(task: 1, resource: 1)
|
|
169
|
+
arbiter.acquire(task: 0, resource: 1) # => [:blocked, 1]
|
|
170
|
+
arbiter.acquire(task: 1, resource: 0) # => [:deadlock, nil]
|
|
171
|
+
arbiter.effective_priorities # => [1, 5, 10] untouched
|
|
172
|
+
|
|
173
|
+
arbiter.cancel_wait(task: 0) # => true, task 0 backs off
|
|
174
|
+
arbiter.acquire(task: 1, resource: 0) # => [:blocked, 0] now it's a plain wait
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### The other protocol: immediate ceiling
|
|
178
|
+
|
|
179
|
+
With `:immediate_ceiling`, a task jumps to the resource's ceiling the moment it takes the resource, before anyone has to wait. Nobody with a priority at or below the ceiling can get in behind it.
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
arbiter = ArbiterMachines::Arbiter.new(
|
|
183
|
+
priorities: [1, 5, 10], ceilings: [8, 10], protocol: :immediate_ceiling
|
|
184
|
+
)
|
|
185
|
+
arbiter.acquire(task: 0, resource: 0) # => [:granted, nil]
|
|
186
|
+
arbiter.effective_priorities # => [8, 5, 10] task 0 raised to the ceiling
|
|
187
|
+
arbiter.acquire(task: 1, resource: 1) # => [:blocked, 0] priority 5 can't clear a ceiling of 8
|
|
188
|
+
arbiter.acquire(task: 2, resource: 1) # => [:granted, nil] priority 10 can
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
A ceiling has to be at least as high as every task that will ever take the resource. Task 2 at priority 10 asking for resource 0 with ceiling 8 is a misdeclaration, and the arbiter says so:
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
arbiter.acquire(task: 2, resource: 0) # => [:invalid, nil]
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## The Rules of the Vessel
|
|
198
|
+
|
|
199
|
+
- **Up to 8 tasks and 8 resources**, chosen independently by the lengths of `priorities:` and `ceilings:`. Empty or longer arrays raise `ArgumentError`.
|
|
200
|
+
- **Priorities, ceilings, and indices are non-negative Integers** below `2**32`. Floats and strings raise `TypeError`, out-of-range raises `RangeError`.
|
|
201
|
+
- **Out-of-range task or resource indices** in `acquire` return `[:invalid, nil]`. In `cancel_wait` they return `false`. Nothing raises for a bad index, only for a bad type.
|
|
202
|
+
- **`effective_priorities` is a fresh Array** every call. Mutate it all you like, the arbiter doesn't care.
|
|
203
|
+
- **Frozen means frozen.** `freeze` the arbiter and `acquire`, `release`, and `cancel_wait` raise `FrozenError`. Reads still work.
|
|
204
|
+
- **Ceilings are always required**, even under `:inheritance`, where they're not consulted.
|
|
205
|
+
|
|
206
|
+
## What You Think You're Doing vs Reality
|
|
207
|
+
|
|
208
|
+
### You Think: "Priority 10 means it runs first."
|
|
209
|
+
### Reality: Priority 10 means it waits first, behind whoever holds its lock.
|
|
210
|
+
|
|
211
|
+
A priority is a promise about scheduling, not about locks. The moment a high-priority task blocks on a lock held by a low-priority one, every medium task in the system is effectively more urgent than your most urgent work. Inheritance is what makes the number mean something again.
|
|
212
|
+
|
|
213
|
+
## What's Yours
|
|
214
|
+
|
|
215
|
+
The arbiter never touches a mutex, a thread, or a scheduler. When it says `:granted`, you take the lock. When it says `:blocked`, you wait however you wait, then ask again after the holder releases. When it reports an effective priority, you're the one who has to tell your scheduler. Keep one arbiter per group of resources, and keep its calls serialized.
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT License. See [LICENSE.txt](LICENSE.txt) for details.
|
|
220
|
+
|
|
221
|
+
**Remember: Nobody can hear the payment job scream while the janitor mops at priority 1.**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.2](https://github.com/seuros/arbiter_machines/compare/arbiter-machines-v0.2.1...arbiter-machines-v0.2.2) (2026-11-06)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* crates.io keywords and categories for the core ([10c8cad](https://github.com/seuros/arbiter_machines/commit/10c8cad0f35cb6c44dbe0e5573275f2267afc306))
|
|
9
|
+
|
|
10
|
+
## [0.2.1](https://github.com/seuros/arbiter_machines/compare/arbiter-machines-v0.2.0...arbiter-machines-v0.2.1) (2026-11-06)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* keep test sources out of the packaged gem and crate ([513f507](https://github.com/seuros/arbiter_machines/commit/513f5074a2058f23742ee47b2289cd8b8872d6d3))
|
|
16
|
+
|
|
17
|
+
## [0.2.0](https://github.com/seuros/arbiter_machines/compare/arbiter-machines-v0.1.0...arbiter-machines-v0.2.0) (2026-11-06)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* initial extraction ([0ce828b](https://github.com/seuros/arbiter_machines/commit/0ce828bfacd5c9ef7482136b73d7be18339e19b9))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# arbiter-machines
|
|
2
|
+
|
|
3
|
+
> **AMS Dijkstra**, NCC-4201, *Dijkstra*-class traffic-control vessel.
|
|
4
|
+
|
|
5
|
+
Engine-room flight manual: coordinate airlock ownership without a circular wait.
|
|
6
|
+
|
|
7
|
+
Allocation-free `no_std` ownership and wait-for decisions for fixed tasks/resources.
|
|
8
|
+
Larger numeric priority means higher priority. One outstanding wait per task;
|
|
9
|
+
nonrecursive ownership. Releases wake affected waiters to retry but never silently
|
|
10
|
+
transfer ownership.
|
|
11
|
+
|
|
12
|
+
Inheritance propagates priorities transitively to owners. Immediate-ceiling mode
|
|
13
|
+
raises owners to held-resource ceilings and blocks acquisition unless effective
|
|
14
|
+
priority exceeds every ceiling held by another task. Each configured resource
|
|
15
|
+
ceiling must bound all tasks permitted to use it; requests exceeding it reject.
|
|
16
|
+
The core detects prospective wait-for cycles before inserting a wait.
|
|
17
|
+
|
|
18
|
+
These decisions require an executor honoring priorities and ownership. No OS
|
|
19
|
+
priority manipulation, lock implementation, waiter-queue fairness, preemption
|
|
20
|
+
driver, multi-resource atomic acquisition, or Ruby scheduling guarantee.
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ArbiterMachines
|
|
2
|
+
VERSION: String
|
|
3
|
+
class Arbiter
|
|
4
|
+
def self.new: (priorities: Array[Integer], ceilings: Array[Integer], protocol: :inheritance | :immediate_ceiling) -> instance
|
|
5
|
+
def acquire: (task: Integer, resource: Integer) -> [Symbol, Integer?]
|
|
6
|
+
def release: (task: Integer, resource: Integer) -> bool
|
|
7
|
+
def cancel_wait: (task: Integer) -> bool
|
|
8
|
+
def effective_priorities: () -> Array[Integer]
|
|
9
|
+
def task_count: () -> Integer
|
|
10
|
+
def resource_count: () -> Integer
|
|
11
|
+
end
|
|
12
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: arbiter_machines
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.5
|
|
5
|
+
platform: aarch64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- Abdelkader Boudih
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-11-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Thin Ruby adapter to the standalone allocation-free arbiter-machines
|
|
14
|
+
Rust core. Initial unstable local implementation; caller enforces all decisions.
|
|
15
|
+
email:
|
|
16
|
+
- oss@seuros.com
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- CHANGELOG.md
|
|
22
|
+
- LICENSE.txt
|
|
23
|
+
- README.md
|
|
24
|
+
- ext/arbiter_machines_native/core/CHANGELOG.md
|
|
25
|
+
- ext/arbiter_machines_native/core/README.md
|
|
26
|
+
- ext/arbiter_machines_native/extconf.rb
|
|
27
|
+
- lib/arbiter_machines.rb
|
|
28
|
+
- lib/arbiter_machines/version.rb
|
|
29
|
+
- lib/arbiter_machines_native/arbiter_machines_native.so
|
|
30
|
+
- sig/arbiter_machines.rbs
|
|
31
|
+
homepage: https://github.com/seuros/arbiter_machines
|
|
32
|
+
licenses:
|
|
33
|
+
- MIT
|
|
34
|
+
metadata:
|
|
35
|
+
source_code_uri: https://github.com/seuros/arbiter_machines
|
|
36
|
+
bug_tracker_uri: https://github.com/seuros/arbiter_machines/issues
|
|
37
|
+
rubygems_mfa_required: 'true'
|
|
38
|
+
cargo_crate_name: arbiter_machines_native
|
|
39
|
+
cargo_manifest_path: ext/arbiter_machines_native/ffi/Cargo.toml
|
|
40
|
+
post_install_message:
|
|
41
|
+
rdoc_options: []
|
|
42
|
+
require_paths:
|
|
43
|
+
- lib
|
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '4.0'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: 4.1.dev
|
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
requirements: []
|
|
58
|
+
rubygems_version: 3.5.23
|
|
59
|
+
signing_key:
|
|
60
|
+
specification_version: 4
|
|
61
|
+
summary: Native bounded priority inheritance and resource ceiling decisions
|
|
62
|
+
test_files: []
|