Skip to content

Commit 41d05c7

Browse files
committed
Rewrote CAtomicFixnum based on CAtomic.
1 parent 2f28534 commit 41d05c7

File tree

4 files changed

+27
-116
lines changed

4 files changed

+27
-116
lines changed

ext/concurrent_ruby_ext/atomic_boolean.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include <ruby.h>
2-
#include <stdbool.h>
32

43
#include "atomic_boolean.h"
54
#include "atomic_reference.h"
Lines changed: 18 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,49 @@
11
#include <ruby.h>
2-
#include <stdbool.h>
32

43
#include "atomic_fixnum.h"
4+
#include "atomic_reference.h"
55

6-
// http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/_005f_005fatomic-Builtins.html
7-
8-
VALUE atomic_fixnum_allocate(VALUE klass) {
9-
CAtomicFixnum* atomic;
10-
VALUE sval = Data_Make_Struct(klass, CAtomicFixnum, NULL, atomic_fixnum_deallocate, atomic);
11-
12-
#ifndef __USE_GCC_ATOMIC
13-
pthread_mutex_init(&atomic->mutex, NULL);
14-
#endif
15-
16-
return(sval);
6+
void atomic_fixnum_mark(void *value) {
7+
rb_gc_mark_maybe((VALUE) value);
178
}
189

19-
void atomic_fixnum_deallocate(void* sval) {
20-
CAtomicFixnum* atomic = (CAtomicFixnum*) sval;
21-
22-
#ifndef __USE_GCC_ATOMIC
23-
pthread_mutex_destroy(&atomic->mutex);
24-
#endif
25-
26-
free(atomic);
10+
VALUE atomic_fixnum_allocate(VALUE klass) {
11+
return rb_data_object_alloc(klass, (void *) Qnil, atomic_fixnum_mark, NULL);
2712
}
2813

2914
VALUE method_atomic_fixnum_initialize(int argc, VALUE* argv, VALUE self) {
30-
CAtomicFixnum* atomic;
31-
15+
VALUE value = INT2NUM(0);
3216
rb_check_arity(argc, 0, 1);
33-
if (argc == 1) Check_Type(argv[0], T_FIXNUM);
34-
35-
Data_Get_Struct(self, CAtomicFixnum, atomic);
36-
37-
atomic->value = (argc == 1 ? FIX2INT(argv[0]) : 0);
17+
if (argc == 1) {
18+
Check_Type(argv[0], T_FIXNUM);
19+
value = argv[0];
20+
}
21+
DATA_PTR(self) = (void *) value;
3822
return(self);
3923
}
4024

4125
VALUE method_atomic_fixnum_value(VALUE self) {
42-
CAtomicFixnum* atomic;
43-
long value;
44-
45-
Data_Get_Struct(self, CAtomicFixnum, atomic);
46-
47-
#ifdef __USE_GCC_ATOMIC
48-
value = __atomic_load_n(&atomic->value, __ATOMIC_SEQ_CST);
49-
#else
50-
pthread_mutex_lock(&atomic->mutex);
51-
value = atomic->value;
52-
pthread_mutex_unlock(&atomic->mutex);
53-
#endif
54-
55-
return INT2FIX(value);
26+
return (VALUE) DATA_PTR(self);
5627
}
5728

5829
VALUE method_atomic_fixnum_value_set(VALUE self, VALUE value) {
59-
CAtomicFixnum* atomic;
60-
long new_value;
61-
6230
Check_Type(value, T_FIXNUM);
63-
64-
new_value = FIX2INT(value);
65-
Data_Get_Struct(self, CAtomicFixnum, atomic);
66-
67-
#ifdef __USE_GCC_ATOMIC
68-
__atomic_store_n(&atomic->value, new_value, __ATOMIC_SEQ_CST);
69-
#else
70-
pthread_mutex_lock(&atomic->mutex);
71-
atomic->value = new_value;
72-
pthread_mutex_unlock(&atomic->mutex);
73-
#endif
74-
31+
DATA_PTR(self) = (void *) value;
7532
return(value);
7633
}
7734

7835
VALUE method_atomic_fixnum_increment(VALUE self) {
79-
CAtomicFixnum* atomic;
80-
long value;
81-
82-
Data_Get_Struct(self, CAtomicFixnum, atomic);
83-
value = ++atomic->value;
84-
85-
return(INT2FIX(value));
36+
long value = NUM2INT((VALUE) DATA_PTR(self));
37+
return method_atomic_fixnum_value_set(self, INT2NUM(value + 1));
8638
}
8739

8840
VALUE method_atomic_fixnum_decrement(VALUE self) {
89-
CAtomicFixnum* atomic;
90-
long value;
91-
92-
Data_Get_Struct(self, CAtomicFixnum, atomic);
93-
value = --atomic->value;
94-
95-
return(INT2FIX(value));
41+
long value = NUM2INT((VALUE) DATA_PTR(self));
42+
return method_atomic_fixnum_value_set(self, INT2NUM(value - 1));
9643
}
9744

9845
VALUE method_atomic_fixnum_compare_and_set(VALUE self, VALUE rb_expect, VALUE rb_update) {
99-
CAtomicFixnum* atomic;
100-
long expect, update;
101-
102-
#ifdef __USE_GCC_ATOMIC
103-
VALUE value;
104-
#else
105-
VALUE value = Qfalse;
106-
#endif
107-
10846
Check_Type(rb_expect, T_FIXNUM);
10947
Check_Type(rb_update, T_FIXNUM);
110-
111-
Data_Get_Struct(self, CAtomicFixnum, atomic);
112-
113-
expect = FIX2INT(rb_expect);
114-
update = FIX2INT(rb_update);
115-
116-
#ifdef __USE_GCC_ATOMIC
117-
value = __atomic_compare_exchange_n(&atomic->value, &expect, update, false,
118-
__ATOMIC_RELEASE, __ATOMIC_SEQ_CST) ? Qtrue : Qfalse;
119-
#else
120-
pthread_mutex_lock(&atomic->mutex);
121-
if (atomic->value == expect) {
122-
atomic->value = update;
123-
value = Qtrue;
124-
}
125-
pthread_mutex_unlock(&atomic->mutex);
126-
#endif
127-
128-
return(value);
48+
return ir_compare_and_set(self, rb_expect, rb_update);
12949
}

ext/concurrent_ruby_ext/atomic_fixnum.h

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
11
#ifndef __ATOMIC_FIXNUM_H__
22
#define __ATOMIC_FIXNUM_H__
33

4-
#ifdef __ATOMIC_SEQ_CST
5-
#define __USE_GCC_ATOMIC
6-
#endif
7-
8-
#ifndef __USE_GCC_ATOMIC
9-
#include <pthread.h>
10-
#endif
11-
12-
typedef struct atomic_fixnum {
13-
long value;
14-
#ifndef __USE_GCC_ATOMIC
15-
pthread_mutex_t mutex;
16-
#endif
17-
} CAtomicFixnum;
18-
4+
void atomic_fixnum_mark(void*);
195
VALUE atomic_fixnum_allocate(VALUE);
20-
void atomic_fixnum_deallocate(void*);
216
VALUE method_atomic_fixnum_initialize(int, VALUE*, VALUE);
227
VALUE method_atomic_fixnum_value(VALUE);
238
VALUE method_atomic_fixnum_value_set(VALUE, VALUE);

spec/concurrent/atomic/atomic_fixnum_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,14 @@ module Concurrent
165165
end
166166
end
167167

168-
if TestHelpers.jruby?
168+
if defined? Concurrent::CAtomicFixnum
169+
170+
describe CAtomicFixnum do
171+
it_should_behave_like :atomic_fixnum
172+
end
173+
end
174+
175+
if RUBY_PLATFORM == 'java'
169176

170177
describe JavaAtomicFixnum do
171178
it_should_behave_like :atomic_fixnum

0 commit comments

Comments
 (0)