spinel_native 0.3.0 → 0.3.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 +9 -0
- data/README.md +2 -2
- data/lib/spinel/native/builder.rb +18 -1
- data/lib/spinel/native/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6eb84c9447a7802b37d923c0fc03328b913d196cd7394f45f7d8ff8ebdae61f8
|
|
4
|
+
data.tar.gz: a4761840558347f8d65510053ce013351011ed8a98dfe21e463b3c93e7ba1198
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a16adfa8b94475d39fa61eea71cd6e886977efa37207517204fc30a96e8478e139d7efd33837e23cc71b1b9cfa559274d825ff79514e58072fb997ff46ed17b
|
|
7
|
+
data.tar.gz: d898452eff97062057a9dbd82d112bfd35653fce9ce8b8a27adc208644950e7510aeb18e43bd41cc627ae25d56d73c972a746c3ae58ebe2b0518f916fc317787
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1 (2026-09-20)
|
|
4
|
+
|
|
5
|
+
- Run the kernel with the GVL held. The CRuby shim Spinel emits locks its
|
|
6
|
+
mutex under the GVL and then releases the GVL for the call, which deadlocks
|
|
7
|
+
on the second concurrent call from another Ruby thread (Puma under load).
|
|
8
|
+
Until the shim is fixed upstream, spinel_native rewrites the call site so
|
|
9
|
+
the kernel runs under the GVL; kernels no longer overlap other Ruby threads.
|
|
10
|
+
- The build cache key includes the spinel_native version.
|
|
11
|
+
|
|
3
12
|
## 0.3.0 (2026-09-18)
|
|
4
13
|
|
|
5
14
|
- `native_entries :a, :b`: in a stateful kernel, name the methods called from
|
data/README.md
CHANGED
|
@@ -284,8 +284,8 @@ SPINEL_NATIVE_VERBOSE=1 # print the commands and timings
|
|
|
284
284
|
- A `raise` inside the kernel arrives in Ruby as the same exception class and
|
|
285
285
|
message. Integer overflow raises `RangeError` where CRuby would promote to a
|
|
286
286
|
Bignum, and a Bignum argument is a `RangeError` at the boundary.
|
|
287
|
-
-
|
|
288
|
-
`native_state` needs no locking of its own.
|
|
287
|
+
- Kernels run one call at a time per module, with the GVL held (see the
|
|
288
|
+
0.3.1 changelog for why), so `native_state` needs no locking of its own.
|
|
289
289
|
- In a stateful module with `native_entries`, only the entries reach the
|
|
290
290
|
kernel's state. A non-entry method called from Ruby runs as Ruby, on the
|
|
291
291
|
module's own ivars.
|
|
@@ -55,7 +55,7 @@ module Spinel
|
|
|
55
55
|
def fingerprint
|
|
56
56
|
@fingerprint ||= begin
|
|
57
57
|
st = File.stat(spinel_bin)
|
|
58
|
-
Digest::SHA256.hexdigest([st.size, st.mtime.to_i, RUBY_VERSION, RUBY_PLATFORM, RbConfig::CONFIG["CC"]].join("|"))
|
|
58
|
+
Digest::SHA256.hexdigest([st.size, st.mtime.to_i, RUBY_VERSION, RUBY_PLATFORM, RbConfig::CONFIG["CC"], VERSION].join("|"))
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -158,6 +158,23 @@ module Spinel
|
|
|
158
158
|
"--ext", "cruby", "--ext-init", "spx_init_#{@feature}", "--ext-entry", entry_list,
|
|
159
159
|
"-o", File.join(@dir, "#{@feature}.c")]
|
|
160
160
|
sh(cmd, "spinel")
|
|
161
|
+
keep_gvl(File.join(@dir, "#{@feature}_ext.c"))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# The shim Spinel emits takes its mutex while holding the GVL and then
|
|
165
|
+
# releases the GVL for the kernel call. A second Ruby thread entering
|
|
166
|
+
# the shim blocks on the mutex with the GVL held, the first cannot take
|
|
167
|
+
# the GVL back to unlock, and the process deadlocks on its second
|
|
168
|
+
# concurrent call (reproduced under Puma with wrk). Until the shim
|
|
169
|
+
# orders the two the other way round, run the kernel with the GVL held:
|
|
170
|
+
# the mutex is then never contended and the conversions, which touch
|
|
171
|
+
# the single-threaded Spinel heap, are serialized too. The cost is that
|
|
172
|
+
# kernels do not overlap with other Ruby threads.
|
|
173
|
+
def keep_gvl(shim)
|
|
174
|
+
src = File.read(shim)
|
|
175
|
+
patched = src.gsub(/rb_thread_call_without_gvl\((spx_run_\d+), &c__, RUBY_UBF_IO, NULL\)/, '\1(&c__)')
|
|
176
|
+
raise CompileError, "unexpected shim shape in #{shim}: no rb_thread_call_without_gvl call sites" if patched == src
|
|
177
|
+
File.write(shim, patched)
|
|
161
178
|
end
|
|
162
179
|
|
|
163
180
|
# Every kernel carries its own copy of the runtime and exports the same
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spinel_native
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Hasiński
|
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
64
64
|
- !ruby/object:Gem::Version
|
|
65
65
|
version: '0'
|
|
66
66
|
requirements: []
|
|
67
|
-
rubygems_version: 4.0.
|
|
67
|
+
rubygems_version: 4.0.20
|
|
68
68
|
specification_version: 4
|
|
69
69
|
summary: Compile individual Ruby methods to native code with the Spinel AOT compiler
|
|
70
70
|
test_files: []
|