xthread 0.1.3

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.
data/queue.c ADDED
@@ -0,0 +1,393 @@
1
+ /**********************************************************************
2
+
3
+ queue.c -
4
+
5
+ Copyright (C) 2011 Keiju Ishitsuka
6
+ Copyright (C) 2011 Penta Advanced Laboratories, Inc.
7
+
8
+ **********************************************************************/
9
+
10
+ #include "ruby.h"
11
+
12
+ #include "xthread.h"
13
+
14
+ #define SIZED_QUEUE_DEFAULT_MAX 16
15
+
16
+ VALUE rb_cXThreadQueue;
17
+ VALUE rb_cXThreadSizedQueue;
18
+
19
+ typedef struct rb_xthread_queue_struct
20
+ {
21
+ VALUE lock;
22
+ VALUE cond;
23
+
24
+ VALUE elements;
25
+ } xthread_queue_t;
26
+
27
+ #define GetXThreadQueuePtr(obj, tobj) \
28
+ TypedData_Get_Struct((obj), xthread_queue_t, &xthread_queue_data_type, (tobj))
29
+
30
+ static void
31
+ xthread_queue_mark(void *ptr)
32
+ {
33
+ xthread_queue_t *que = (xthread_queue_t*)ptr;
34
+
35
+ rb_gc_mark(que->lock);
36
+ rb_gc_mark(que->cond);
37
+ rb_gc_mark(que->elements);
38
+ }
39
+
40
+ static void
41
+ xthread_queue_free(void *ptr)
42
+ {
43
+ ruby_xfree(ptr);
44
+ }
45
+
46
+ static size_t
47
+ xthread_queue_memsize(const void *ptr)
48
+ {
49
+ return ptr ? sizeof(xthread_queue_t) : 0;
50
+ }
51
+
52
+ static const rb_data_type_t xthread_queue_data_type = {
53
+ "xthread_queue",
54
+ {xthread_queue_mark, xthread_queue_free, xthread_queue_memsize,},
55
+ };
56
+
57
+ static void
58
+ xthread_queue_alloc_init(xthread_queue_t *que)
59
+ {
60
+ que->lock = rb_mutex_new();
61
+ que->cond = rb_xthread_cond_new();
62
+ que->elements = rb_xthread_fifo_new();
63
+ }
64
+
65
+ static VALUE
66
+ xthread_queue_alloc(VALUE klass)
67
+ {
68
+ VALUE volatile obj;
69
+ xthread_queue_t *que;
70
+
71
+ obj = TypedData_Make_Struct(klass, xthread_queue_t, &xthread_queue_data_type, que);
72
+ xthread_queue_alloc_init(que);
73
+ return obj;
74
+ }
75
+
76
+ static VALUE
77
+ xthread_queue_initialize(VALUE self)
78
+ {
79
+ return self;
80
+ }
81
+
82
+ VALUE
83
+ rb_xthread_queue_new(void)
84
+ {
85
+ return xthread_queue_alloc(rb_cXThreadQueue);
86
+ }
87
+
88
+ VALUE
89
+ rb_xthread_queue_push(VALUE self, VALUE item)
90
+ {
91
+ xthread_queue_t *que;
92
+ int signal_p = 0;
93
+
94
+ GetXThreadQueuePtr(self, que);
95
+
96
+ if (RTEST(rb_xthread_fifo_empty_p(que->elements))) {
97
+ signal_p = 1;
98
+ }
99
+ rb_xthread_fifo_push(que->elements, item);
100
+ if (signal_p) {
101
+ rb_xthread_cond_signal(que->cond);
102
+ }
103
+ return self;
104
+ }
105
+
106
+ VALUE
107
+ rb_xthread_queue_pop(VALUE self)
108
+ {
109
+ xthread_queue_t *que;
110
+ VALUE item;
111
+
112
+ GetXThreadQueuePtr(self, que);
113
+
114
+ if (RTEST(rb_xthread_fifo_empty_p(que->elements))) {
115
+ rb_mutex_lock(que->lock);
116
+ while (RTEST(rb_xthread_fifo_empty_p(que->elements))) {
117
+ rb_xthread_cond_wait(que->cond, que->lock, Qnil);
118
+ }
119
+ rb_mutex_unlock(que->lock);
120
+ }
121
+ return rb_xthread_fifo_pop(que->elements);
122
+ }
123
+
124
+ VALUE
125
+ rb_xthread_queue_pop_non_block(VALUE self)
126
+ {
127
+ xthread_queue_t *que;
128
+ VALUE item;
129
+
130
+ GetXThreadQueuePtr(self, que);
131
+
132
+ if (RTEST(rb_xthread_fifo_empty_p(que->elements))) {
133
+ rb_raise(rb_eThreadError, "xthread_queue empty");
134
+ }
135
+ else {
136
+ return rb_xthread_fifo_pop(que->elements);
137
+ }
138
+ }
139
+
140
+ static VALUE
141
+ xthread_queue_pop(int argc, VALUE *argv, VALUE self)
142
+ {
143
+ VALUE non_block;
144
+
145
+ rb_scan_args(argc, argv, "01", &non_block);
146
+ if (RTEST(non_block)) {
147
+ return rb_xthread_queue_pop_non_block(self);
148
+ }
149
+ else {
150
+ return rb_xthread_queue_pop(self);
151
+ }
152
+ }
153
+
154
+
155
+ VALUE
156
+ rb_xthread_queue_empty_p(VALUE self)
157
+ {
158
+ xthread_queue_t *que;
159
+ GetXThreadQueuePtr(self, que);
160
+
161
+ return rb_xthread_fifo_empty_p(que->elements);
162
+ }
163
+
164
+ VALUE
165
+ rb_xthread_queue_clear(VALUE self)
166
+ {
167
+ xthread_queue_t *que;
168
+ GetXThreadQueuePtr(self, que);
169
+
170
+ rb_xthread_fifo_clear(que->elements);
171
+ return self;
172
+ }
173
+
174
+ VALUE
175
+ rb_xthread_queue_length(VALUE self)
176
+ {
177
+ xthread_queue_t *que;
178
+ GetXThreadQueuePtr(self, que);
179
+
180
+ return rb_xthread_fifo_length(que->elements);
181
+ }
182
+
183
+ typedef struct rb_xthread_sized_queue_struct
184
+ {
185
+ xthread_queue_t super;
186
+
187
+ long max;
188
+ VALUE cond_wait;
189
+
190
+ } xthread_sized_queue_t;
191
+
192
+ #define GetXThreadSizedQueuePtr(obj, tobj) \
193
+ TypedData_Get_Struct((obj), xthread_sized_queue_t, &xthread_sized_queue_data_type, (tobj))
194
+
195
+ static void
196
+ xthread_sized_queue_mark(void *ptr)
197
+ {
198
+ xthread_sized_queue_t *que = (xthread_sized_queue_t*)ptr;
199
+
200
+ xthread_queue_mark(ptr);
201
+ rb_gc_mark(que->cond_wait);
202
+ }
203
+
204
+ static void
205
+ xthread_sized_queue_free(void *ptr)
206
+ {
207
+ xthread_sized_queue_t *que = (xthread_sized_queue_t*)ptr;
208
+
209
+ ruby_xfree(ptr);
210
+ }
211
+
212
+ static size_t
213
+ xthread_sized_queue_memsize(const void *ptr)
214
+ {
215
+ xthread_sized_queue_t *que = (xthread_sized_queue_t*)ptr;
216
+
217
+ return ptr ? sizeof(xthread_sized_queue_t) : 0;
218
+ }
219
+
220
+ static const rb_data_type_t xthread_sized_queue_data_type = {
221
+ "xthread_sized_queue",
222
+ {xthread_sized_queue_mark, xthread_sized_queue_free, xthread_sized_queue_memsize,},
223
+ &xthread_queue_data_type,
224
+ };
225
+
226
+ static VALUE
227
+ xthread_sized_queue_alloc(VALUE klass)
228
+ {
229
+ VALUE volatile obj;
230
+ xthread_sized_queue_t *que;
231
+
232
+ obj = TypedData_Make_Struct(klass,
233
+ xthread_sized_queue_t, &xthread_sized_queue_data_type, que);
234
+ xthread_queue_alloc_init(&que->super);
235
+
236
+ que->max = SIZED_QUEUE_DEFAULT_MAX;
237
+ que->cond_wait = rb_xthread_cond_new();
238
+
239
+ return obj;
240
+ }
241
+
242
+ static VALUE
243
+ xthread_sized_queue_initialize(VALUE self, VALUE v_max)
244
+ {
245
+ xthread_sized_queue_t *que;
246
+ long max = NUM2LONG(v_max);
247
+
248
+ GetXThreadSizedQueuePtr(self, que);
249
+
250
+ que->max = max;
251
+
252
+ return self;
253
+ }
254
+
255
+ VALUE
256
+ rb_xthread_sized_queue_new(long max)
257
+ {
258
+ xthread_sized_queue_t *que;
259
+ VALUE obj = xthread_sized_queue_alloc(rb_cXThreadSizedQueue);
260
+
261
+ GetXThreadSizedQueuePtr(obj, que);
262
+
263
+ que->max = max;
264
+ return obj;
265
+ }
266
+
267
+ VALUE
268
+ rb_xthread_sized_queue_max(VALUE self)
269
+ {
270
+ xthread_sized_queue_t *que;
271
+
272
+ GetXThreadSizedQueuePtr(self, que);
273
+ return LONG2NUM(que->max);
274
+ }
275
+
276
+ VALUE
277
+ rb_xthread_sized_queue_set_max(VALUE self, VALUE v_max)
278
+ {
279
+ xthread_sized_queue_t *que;
280
+ long max = NUM2LONG(v_max);
281
+ long diff = 0;
282
+ long i;
283
+
284
+ GetXThreadSizedQueuePtr(self, que);
285
+
286
+ if (max < que->max) {
287
+ diff = max - que->max;
288
+ }
289
+ que->max = max;
290
+
291
+ for (i = 0; i < diff; i++) {
292
+ rb_xthread_cond_signal(que->cond_wait);
293
+ }
294
+ }
295
+
296
+ VALUE
297
+ rb_xthread_sized_queue_push(VALUE self, VALUE item)
298
+ {
299
+ xthread_sized_queue_t *que;
300
+
301
+ GetXThreadSizedQueuePtr(self, que);
302
+
303
+ if (NUM2LONG(rb_xthread_fifo_length(que->super.elements)) < que->max) {
304
+ return rb_xthread_queue_push(self, item);
305
+ }
306
+ rb_mutex_lock(que->super.lock);
307
+ while (NUM2LONG(rb_xthread_fifo_length(que->super.elements)) >= que->max) {
308
+ rb_xthread_cond_wait(que->cond_wait, que->super.lock, Qnil);
309
+ }
310
+ rb_mutex_unlock(que->super.lock);
311
+ return rb_xthread_queue_push(self, item);
312
+ }
313
+
314
+ VALUE
315
+ rb_xthread_sized_queue_pop(VALUE self)
316
+ {
317
+ VALUE item;
318
+ xthread_sized_queue_t *que;
319
+ GetXThreadSizedQueuePtr(self, que);
320
+
321
+ item = rb_xthread_queue_pop(self);
322
+
323
+ if (NUM2LONG(rb_xthread_fifo_length(que->super.elements)) < que->max) {
324
+ rb_xthread_cond_signal(que->cond_wait);
325
+ }
326
+ return item;
327
+ }
328
+
329
+ VALUE
330
+ rb_xthread_sized_queue_pop_non_block(VALUE self)
331
+ {
332
+ VALUE item;
333
+ xthread_sized_queue_t *que;
334
+ GetXThreadSizedQueuePtr(self, que);
335
+
336
+ item = rb_xthread_queue_pop_non_block(self);
337
+
338
+ if (NUM2LONG(rb_xthread_fifo_length(que->super.elements)) < que->max) {
339
+ rb_xthread_cond_signal(que->cond_wait);
340
+ }
341
+ return item;
342
+ }
343
+
344
+ static VALUE
345
+ xthread_sized_queue_pop(int argc, VALUE *argv, VALUE self)
346
+ {
347
+ VALUE item;
348
+ xthread_sized_queue_t *que;
349
+ GetXThreadSizedQueuePtr(self, que);
350
+
351
+ item = xthread_queue_pop(argc, argv, self);
352
+
353
+ if (NUM2LONG(rb_xthread_fifo_length(que->super.elements)) < que->max) {
354
+ rb_xthread_cond_signal(que->cond_wait);
355
+ }
356
+ return item;
357
+ }
358
+
359
+ void
360
+ Init_XThreadQueue()
361
+ {
362
+ rb_cXThreadQueue = rb_define_class_under(rb_mXThread, "Queue", rb_cObject);
363
+
364
+ rb_define_alloc_func(rb_cXThreadQueue, xthread_queue_alloc);
365
+ rb_define_method(rb_cXThreadQueue, "initialize", xthread_queue_initialize, 0);
366
+ rb_define_method(rb_cXThreadQueue, "pop", xthread_queue_pop, -1);
367
+ rb_define_alias(rb_cXThreadQueue, "shift", "pop");
368
+ rb_define_alias(rb_cXThreadQueue, "deq", "pop");
369
+ rb_define_method(rb_cXThreadQueue, "push", rb_xthread_queue_push, 1);
370
+ rb_define_alias(rb_cXThreadQueue, "<<", "push");
371
+ rb_define_alias(rb_cXThreadQueue, "enq", "push");
372
+ rb_define_method(rb_cXThreadQueue, "empty?", rb_xthread_queue_empty_p, 0);
373
+ rb_define_method(rb_cXThreadQueue, "clear", rb_xthread_queue_clear, 0);
374
+ rb_define_method(rb_cXThreadQueue, "length", rb_xthread_queue_length, 0);
375
+ rb_define_alias(rb_cXThreadQueue, "size", "length");
376
+
377
+
378
+ rb_cXThreadSizedQueue = rb_define_class_under(rb_mXThread, "SizedQueue", rb_cXThreadQueue);
379
+
380
+ rb_define_alloc_func(rb_cXThreadSizedQueue, xthread_sized_queue_alloc);
381
+ rb_define_method(rb_cXThreadSizedQueue, "initialize", xthread_sized_queue_initialize, 1);
382
+ rb_define_method(rb_cXThreadSizedQueue, "pop", xthread_sized_queue_pop, 0);
383
+ rb_define_alias(rb_cXThreadSizedQueue, "shift", "pop");
384
+ rb_define_alias(rb_cXThreadSizedQueue, "deq", "pop");
385
+ rb_define_method(rb_cXThreadSizedQueue, "push", rb_xthread_sized_queue_push, 1);
386
+ rb_define_alias(rb_cXThreadSizedQueue, "<<", "push");
387
+ rb_define_alias(rb_cXThreadSizedQueue, "enq", "push");
388
+
389
+ rb_define_method(rb_cXThreadSizedQueue, "max", rb_xthread_sized_queue_max, 0);
390
+ rb_define_method(rb_cXThreadSizedQueue, "max=", rb_xthread_sized_queue_set_max, 1);
391
+
392
+
393
+ }
data/xthread.c ADDED
@@ -0,0 +1,28 @@
1
+ /**********************************************************************
2
+
3
+ xthread.c -
4
+
5
+ Copyright (C) 2011 Keiju Ishitsuka
6
+ Copyright (C) 2011 Penta Advanced Laboratories, Inc.
7
+
8
+ **********************************************************************/
9
+
10
+ #include "ruby.h"
11
+
12
+ extern void Init_XThreadFifo();
13
+ extern void Init_XThreadCond();
14
+ extern void Init_XThreadQueue();
15
+ extern void Init_XThreadMonitor();
16
+
17
+ VALUE rb_mXThread;
18
+
19
+ Init_xthread()
20
+ {
21
+ rb_mXThread = rb_define_module("XThread");
22
+
23
+ Init_XThreadFifo();
24
+ Init_XThreadCond();
25
+ Init_XThreadQueue();
26
+ Init_XThreadMonitor();
27
+ }
28
+
data/xthread.gemspec ADDED
@@ -0,0 +1,32 @@
1
+
2
+ require "rubygems"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "xthread"
6
+ s.authors = "Keiju.Ishitsuka"
7
+ s.email = "keiju@ishitsuka.com"
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = "C-implementation version of thread.rb and monitor.eb libraries"
10
+ s.rubyforge_project = s.name
11
+ s.homepage = "http://github.com/keiju/xthread"
12
+ s.version = `git tag`.split.collect{|e| e.sub(/v([0-9]+\.[0-9]+\.[0-9]+).*/, "\\1")}.sort.last
13
+ s.require_path = "."
14
+ # s.test_file = ""
15
+ # s.executable = ""
16
+ s.files = ["LICENSE", "xthread.gemspec"]
17
+ s.files.concat Dir.glob("*.h")
18
+ s.files.concat Dir.glob("*.c")
19
+ s.files.concat Dir.glob("lib/*.rb")
20
+ s.files.concat Dir.glob("lib/xthread/*.rb")
21
+
22
+ s.extensions = ["extconf.rb"]
23
+ s.description = <<EOF
24
+ C-implementation version of thread.rb and monitor.eb libraries
25
+ EOF
26
+ end
27
+
28
+ # Editor settings
29
+ # - Emacs -
30
+ # local variables:
31
+ # mode: Ruby
32
+ # end:
data/xthread.h ADDED
@@ -0,0 +1,65 @@
1
+ /**********************************************************************
2
+
3
+ xthread.h -
4
+
5
+ Copyright (C) 2011 Keiju Ishitsuka
6
+ Copyright (C) 2011 Penta Advanced Laboratories, Inc.
7
+
8
+ **********************************************************************/
9
+
10
+
11
+ #define XTHREAD_VERSION "0.1.2"
12
+
13
+ RUBY_EXTERN VALUE rb_mXThread;
14
+ RUBY_EXTERN VALUE rb_cXThreadFifo;
15
+ RUBY_EXTERN VALUE rb_cXThreadConditionVariable;
16
+ RUBY_EXTERN VALUE rb_cXThreadQueue;
17
+ RUBY_EXTERN VALUE rb_cXThreadSizedQueue;
18
+ RUBY_EXTERN VALUE rb_cXThreadMonitor;
19
+ RUBY_EXTERN VALUE rb_cXThreadMonitorCond;
20
+
21
+
22
+ RUBY_EXTERN VALUE rb_xthread_fifo_new(void);
23
+ RUBY_EXTERN VALUE rb_xthread_fifo_empty_p(VALUE);
24
+ RUBY_EXTERN VALUE rb_xthread_fifo_push(VALUE, VALUE);
25
+ RUBY_EXTERN VALUE rb_xthread_fifo_pop(VALUE);
26
+ RUBY_EXTERN VALUE rb_xthread_fifo_clear(VALUE);
27
+ RUBY_EXTERN VALUE rb_xthread_fifo_length(VALUE);
28
+
29
+ RUBY_EXTERN VALUE rb_xthread_cond_new(void);
30
+ RUBY_EXTERN VALUE rb_xthread_cond_signal(VALUE);
31
+ RUBY_EXTERN VALUE rb_xthread_cond_broadcast(VALUE);
32
+ RUBY_EXTERN VALUE rb_xthread_cond_wait(VALUE, VALUE, VALUE);
33
+
34
+ RUBY_EXTERN VALUE rb_xthread_queue_new(void);
35
+ RUBY_EXTERN VALUE rb_xthread_queue_push(VALUE, VALUE);
36
+ RUBY_EXTERN VALUE rb_xthread_queue_pop(VALUE);
37
+ RUBY_EXTERN VALUE rb_xthread_queue_pop_non_block(VALUE);
38
+ RUBY_EXTERN VALUE rb_xthread_queue_empty_p(VALUE);
39
+ RUBY_EXTERN VALUE rb_xthread_queue_clear(VALUE);
40
+ RUBY_EXTERN VALUE rb_xthread_queue_length(VALUE);
41
+
42
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_new(long);
43
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_max(VALUE);
44
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_set_max(VALUE, VALUE);
45
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_push(VALUE, VALUE);
46
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_pop(VALUE);
47
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_pop_non_block(VALUE);
48
+
49
+ RUBY_EXTERN VALUE rb_xthread_monitor_new(void);
50
+ RUBY_EXTERN VALUE rb_xthread_monitor_try_enter(VALUE);
51
+ RUBY_EXTERN VALUE rb_xthread_monitor_enter(VALUE);
52
+ RUBY_EXTERN VALUE rb_xthread_monitor_exit(VALUE);
53
+ RUBY_EXTERN VALUE rb_xthread_monitor_synchronize(VALUE, VALUE (*)(VALUE), VALUE);
54
+ RUBY_EXTERN VALUE rb_xthread_monitor_new_cond(VALUE);
55
+
56
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_new(VALUE);
57
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait(VALUE, VALUE);
58
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait_while(VALUE);
59
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait_until(VALUE);
60
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_signal(VALUE);
61
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_broadcast(VALUE self);
62
+
63
+
64
+
65
+
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xthread
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 3
10
+ version: 0.1.3
11
+ platform: ruby
12
+ authors:
13
+ - Keiju.Ishitsuka
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-10 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: |
23
+ C-implementation version of thread.rb and monitor.eb libraries
24
+
25
+ email: keiju@ishitsuka.com
26
+ executables: []
27
+
28
+ extensions:
29
+ - extconf.rb
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - LICENSE
34
+ - xthread.gemspec
35
+ - xthread.h
36
+ - monitor.c
37
+ - xthread.c
38
+ - cond.c
39
+ - fifo.c
40
+ - queue.c
41
+ - lib/xthread.rb
42
+ - lib/xthread/monitor.rb
43
+ - extconf.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/keiju/xthread
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - .
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project: xthread
74
+ rubygems_version: 1.3.7
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: C-implementation version of thread.rb and monitor.eb libraries
78
+ test_files: []
79
+