atomic 1.1.14 → 1.1.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/Gemfile +4 -0
- data/README.md +20 -16
- data/Rakefile +9 -11
- data/atomic.gemspec +1 -1
- data/ext/atomic_reference.c +13 -3
- data/ext/extconf.rb +2 -0
- data/test/test_atomic.rb +3 -3
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 960495c0246177f5b31a0a21f15a0e22d61b40ae
|
4
|
+
data.tar.gz: beff1839c55b014a2cb74a37db338db823db53f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd632983d6ebc30d757bde26a94b66b719d64edb0e45c8c9c383e2742efe283966fca3ffa40d5e4c145a20c2d177e146beae3057cd70ecf65514ab4013d9afa4
|
7
|
+
data.tar.gz: 5f94bad1e38a1de11f3e47025a889eb73056055cc069beb84a189fcdb43b1014be7c432f0a6658ef8c6aaf6a10a35e2864f69dbfe974ea5e88726ad6fe69d03f
|
data/.travis.yml
CHANGED
@@ -3,8 +3,8 @@ rvm:
|
|
3
3
|
- 2.0.0
|
4
4
|
- 1.9.3
|
5
5
|
- 1.8.7
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
6
|
+
- jruby-18mode # JRuby in 1.8 mode
|
7
|
+
- jruby-19mode # JRuby in 1.9 mode
|
8
|
+
- rbx-2
|
9
|
+
jdk:
|
10
|
+
- oraclejdk8
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -9,8 +9,8 @@ This library provides:
|
|
9
9
|
|
10
10
|
The Atomic class provides accessors for the contained "value" plus two update methods:
|
11
11
|
|
12
|
-
* update will run the provided block, passing the current value and replacing it with the block result
|
13
|
-
* try_update will run the provided block, passing the current value and replacing it with the block result. If the value changes before the update can happen, it will throw Atomic::ConcurrentUpdateError.
|
12
|
+
* update will run the provided block, passing the current value and replacing it with the block result if the value has not been changed in the meantime. It may run the block repeatedly if there are other concurrent updates in progress.
|
13
|
+
* try_update will run the provided block, passing the current value and replacing it with the block result. If the value changes before the update can happen, it will throw an Atomic::ConcurrentUpdateError.
|
14
14
|
|
15
15
|
The atomic repository is at http://github.com/headius/ruby-atomic.
|
16
16
|
|
@@ -21,24 +21,28 @@ The simplest way to use "atomic" is to call the "update" or "try_update" methods
|
|
21
21
|
|
22
22
|
"try_update" and "update" both call the given block, passing the current value and using the block's result as the new value. If the value is updated by another thread before the block completes, "try update" raises a ConcurrentUpdateError and "update" retries the block. Because "update" may call the block several times when multiple threads are all updating the same value, the block's logic should be kept as simple as possible.
|
23
23
|
|
24
|
-
|
24
|
+
```ruby
|
25
|
+
require 'atomic'
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
my_atomic = Atomic.new(0)
|
28
|
+
my_atomic.update {|v| v + 1}
|
29
|
+
begin
|
30
|
+
my_atomic.try_update {|v| v + 1}
|
31
|
+
rescue Atomic::ConcurrentUpdateError => cue
|
32
|
+
# deal with it (retry, propagate, etc)
|
33
|
+
end
|
34
|
+
```
|
33
35
|
|
34
36
|
It's also possible to use the regular get/set operations on the Atomic, if you want to avoid the exception and respond to contended changes in some other way.
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
```ruby
|
39
|
+
my_atomic = Atomic.new(0)
|
40
|
+
my_atomic.value # => 0
|
41
|
+
my_atomic.value = 1
|
42
|
+
my_atomic.swap(2) # => 1
|
43
|
+
my_atomic.compare_and_swap(2, 3) # => true, updated to 3
|
44
|
+
my_atomic.compare_and_swap(2, 3) # => false, current is not 2
|
45
|
+
```
|
42
46
|
|
43
47
|
Building
|
44
48
|
========
|
data/Rakefile
CHANGED
@@ -39,27 +39,25 @@ if defined?(JRUBY_VERSION)
|
|
39
39
|
end
|
40
40
|
|
41
41
|
desc "Compile the extension"
|
42
|
-
task :
|
42
|
+
task :compile_java => "pkg/classes" do |t|
|
43
43
|
ant.javac :srcdir => "ext", :destdir => t.prerequisites.first,
|
44
44
|
:source => "1.5", :target => "1.5", :debug => true,
|
45
45
|
:classpath => "${java.class.path}:${sun.boot.class.path}"
|
46
46
|
end
|
47
47
|
|
48
48
|
desc "Build the jar"
|
49
|
-
task :jar => :
|
49
|
+
task :jar => :compile_java do
|
50
50
|
ant.jar :basedir => "pkg/classes", :destfile => "lib/atomic_reference.jar", :includes => "**/*.class"
|
51
51
|
end
|
52
52
|
|
53
|
-
task :
|
53
|
+
task :compile => :jar
|
54
54
|
else
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
ruby "extconf.rb"
|
60
|
-
sh "make"
|
61
|
-
end
|
55
|
+
require "rake/extensiontask"
|
56
|
+
Rake::ExtensionTask.new "atomic" do |ext|
|
57
|
+
ext.ext_dir = 'ext'
|
58
|
+
ext.name ='atomic_reference'
|
62
59
|
end
|
63
60
|
end
|
64
61
|
|
65
|
-
task :
|
62
|
+
task :package => :compile
|
63
|
+
task :test => :compile
|
data/atomic.gemspec
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{atomic}
|
7
|
-
s.version = "1.1.
|
7
|
+
s.version = "1.1.15"
|
8
8
|
s.authors = ["Charles Oliver Nutter", "MenTaLguY", "Sokolov Yura"]
|
9
9
|
s.date = Time.now.strftime('%Y-%m-%d')
|
10
10
|
s.summary = "An atomic reference implementation for JRuby, Rubinius, and MRI"
|
data/ext/atomic_reference.c
CHANGED
@@ -15,6 +15,10 @@
|
|
15
15
|
#include <atomic.h>
|
16
16
|
#endif
|
17
17
|
|
18
|
+
#ifdef HAVE_LIBKERN_OSATOMIC_H
|
19
|
+
#include <libkern/OSAtomic.h>
|
20
|
+
#endif
|
21
|
+
|
18
22
|
static void ir_mark(void *value) {
|
19
23
|
rb_gc_mark_maybe((VALUE) value);
|
20
24
|
}
|
@@ -67,12 +71,18 @@ static VALUE ir_compare_and_set(volatile VALUE self, VALUE expect_value, VALUE n
|
|
67
71
|
return Qtrue;
|
68
72
|
}
|
69
73
|
#endif
|
70
|
-
#elif
|
71
|
-
if (
|
74
|
+
#elif defined _MSC_VER && defined _M_AMD64
|
75
|
+
if (InterlockedCompareExchange64((LONGLONG*)&DATA_PTR(self), new_value, expect_value)) {
|
76
|
+
return Qtrue;
|
77
|
+
}
|
78
|
+
#elif defined _MSC_VER && defined _M_IX86
|
79
|
+
if (InterlockedCompareExchange((LONG*)&DATA_PTR(self), new_value, expect_value)) {
|
72
80
|
return Qtrue;
|
73
81
|
}
|
74
82
|
#else
|
75
|
-
|
83
|
+
if (__sync_bool_compare_and_swap(&DATA_PTR(self), expect_value, new_value)) {
|
84
|
+
return Qtrue;
|
85
|
+
}
|
76
86
|
#endif
|
77
87
|
return Qfalse;
|
78
88
|
}
|
data/ext/extconf.rb
CHANGED
data/test/test_atomic.rb
CHANGED
@@ -10,10 +10,10 @@
|
|
10
10
|
# See the License for the specific language governing permissions and
|
11
11
|
# limitations under the License.
|
12
12
|
|
13
|
-
require '
|
13
|
+
require 'minitest/autorun'
|
14
14
|
require 'atomic'
|
15
15
|
|
16
|
-
class TestAtomic < Test
|
16
|
+
class TestAtomic < MiniTest::Test
|
17
17
|
def test_construct
|
18
18
|
atomic = Atomic.new
|
19
19
|
assert_equal nil, atomic.value
|
@@ -58,7 +58,7 @@ class TestAtomic < Test::Unit::TestCase
|
|
58
58
|
def test_try_update_fails
|
59
59
|
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
|
60
60
|
atomic = Atomic.new(1000)
|
61
|
-
|
61
|
+
assert_raises Atomic::ConcurrentUpdateError do
|
62
62
|
# assigning within block exploits implementation detail for test
|
63
63
|
atomic.try_update{|v| atomic.value = 1001 ; v + 1}
|
64
64
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atomic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Oliver Nutter
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2014-02-26 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: An atomic reference implementation for JRuby, Rubinius, and MRI
|
16
16
|
email:
|
@@ -22,10 +22,9 @@ extensions:
|
|
22
22
|
- ext/extconf.rb
|
23
23
|
extra_rdoc_files: []
|
24
24
|
files:
|
25
|
-
-
|
26
|
-
-
|
27
|
-
-
|
28
|
-
- .travis.yml
|
25
|
+
- ".gitignore"
|
26
|
+
- ".travis.yml"
|
27
|
+
- Gemfile
|
29
28
|
- LICENSE
|
30
29
|
- README.md
|
31
30
|
- Rakefile
|
@@ -36,6 +35,7 @@ files:
|
|
36
35
|
- examples/graph_atomic_bench.rb
|
37
36
|
- ext/AtomicReferenceService.java
|
38
37
|
- ext/atomic_reference.c
|
38
|
+
- ext/extconf.rb
|
39
39
|
- ext/org/jruby/ext/atomic/AtomicReferenceLibrary.java
|
40
40
|
- lib/atomic.rb
|
41
41
|
- lib/atomic/concurrent_update_error.rb
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- lib/atomic/numeric_cas_wrapper.rb
|
47
47
|
- lib/atomic/rbx.rb
|
48
48
|
- lib/atomic/ruby.rb
|
49
|
+
- test/test_atomic.rb
|
49
50
|
homepage: http://github.com/headius/ruby-atomic
|
50
51
|
licenses:
|
51
52
|
- Apache-2.0
|
@@ -56,19 +57,20 @@ require_paths:
|
|
56
57
|
- lib
|
57
58
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- -
|
60
|
+
- - ">="
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '0'
|
62
63
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
64
|
requirements:
|
64
|
-
- -
|
65
|
+
- - ">="
|
65
66
|
- !ruby/object:Gem::Version
|
66
67
|
version: '0'
|
67
68
|
requirements: []
|
68
69
|
rubyforge_project:
|
69
|
-
rubygems_version: 2.0
|
70
|
+
rubygems_version: 2.2.0
|
70
71
|
signing_key:
|
71
72
|
specification_version: 4
|
72
73
|
summary: An atomic reference implementation for JRuby, Rubinius, and MRI
|
73
74
|
test_files:
|
74
75
|
- test/test_atomic.rb
|
76
|
+
has_rdoc:
|