atomic-ruby 0.15.1 → 0.15.2
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 +4 -0
- data/README.md +7 -7
- data/ext/atomic_ruby/atomic_ruby.c +53 -7
- data/ext/atomic_ruby/atomic_ruby.h +1 -0
- data/lib/atomic-ruby/atomic_thread_pool.rb +2 -0
- data/lib/atomic-ruby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c6210195ad6d82fbbb6a84f66bc8ce5faef54d50ed3227c3655ec43a996a9f6
|
|
4
|
+
data.tar.gz: eef94abbb8c8bfb1d9a54d36f8f8b0404d49210e6e6a109851fa014a6512aaa5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c89b7c62bda07206115c80c45088d1ae44e5c3aa84288932fae8fad51312d3490bf9510af559178fe6311e5d8ce4ecf87dca0da3420ced47a0113783e63a741d
|
|
7
|
+
data.tar.gz: a5c5ecee1ce3f96b5e2c525897c1c979fa3f99b7be6cd971d6882e2a43bf9b735f0de58bcf67dbf1179b0298a006a25ba45e910ee0c104f965c305e4af93f6be
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -268,7 +268,7 @@ puts "Atomic Ruby Atomic Bank Account: #{results[2].real.round(6)} seconds"
|
|
|
268
268
|
|
|
269
269
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
270
270
|
concurrent-ruby version: 1.3.6
|
|
271
|
-
atomic-ruby version: 0.15.
|
|
271
|
+
atomic-ruby version: 0.15.2
|
|
272
272
|
|
|
273
273
|
Balances:
|
|
274
274
|
Synchronized Bank Account Balance: 975
|
|
@@ -359,7 +359,7 @@ end
|
|
|
359
359
|
|
|
360
360
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
361
361
|
concurrent-ruby version: 1.3.6
|
|
362
|
-
atomic-ruby version: 0.15.
|
|
362
|
+
atomic-ruby version: 0.15.2
|
|
363
363
|
|
|
364
364
|
Warming up --------------------------------------
|
|
365
365
|
Synchronized Boolean Toggle 157.000 i/100ms
|
|
@@ -442,7 +442,7 @@ end
|
|
|
442
442
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_condition_variable_benchmark.rb
|
|
443
443
|
|
|
444
444
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
445
|
-
atomic-ruby version: 0.15.
|
|
445
|
+
atomic-ruby version: 0.15.2
|
|
446
446
|
|
|
447
447
|
Warming up --------------------------------------
|
|
448
448
|
Synchronized Condition Variable Wait/Signal 3.977k i/100ms
|
|
@@ -517,7 +517,7 @@ end
|
|
|
517
517
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_queue_benchmark.rb
|
|
518
518
|
|
|
519
519
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
520
|
-
atomic-ruby version: 0.15.
|
|
520
|
+
atomic-ruby version: 0.15.2
|
|
521
521
|
|
|
522
522
|
Warming up --------------------------------------
|
|
523
523
|
Synchronized Queue Push/Pop 181.000 i/100ms
|
|
@@ -587,11 +587,11 @@ puts "Atomic Ruby Atomic Thread Pool: #{results[1].real.round(6)} seconds"
|
|
|
587
587
|
|
|
588
588
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
589
589
|
concurrent-ruby version: 1.3.8
|
|
590
|
-
atomic-ruby version: 0.15.
|
|
590
|
+
atomic-ruby version: 0.15.2
|
|
591
591
|
|
|
592
592
|
Benchmark Results:
|
|
593
|
-
Concurrent Ruby Thread Pool: 5.
|
|
594
|
-
Atomic Ruby Atomic Thread Pool: 4.
|
|
593
|
+
Concurrent Ruby Thread Pool: 5.081233 seconds
|
|
594
|
+
Atomic Ruby Atomic Thread Pool: 4.737824 seconds
|
|
595
595
|
```
|
|
596
596
|
|
|
597
597
|
</details>
|
|
@@ -536,6 +536,7 @@ typedef struct {
|
|
|
536
536
|
_Atomic unsigned long long waiting_time;
|
|
537
537
|
_Atomic unsigned long long blocked_time;
|
|
538
538
|
_Atomic unsigned long long running_cpu_time;
|
|
539
|
+
bool active;
|
|
539
540
|
} atomic_ruby_thread_pool_monitor_t;
|
|
540
541
|
|
|
541
542
|
typedef struct {
|
|
@@ -546,8 +547,27 @@ typedef struct {
|
|
|
546
547
|
} atomic_ruby_thread_pool_worker_state_t;
|
|
547
548
|
|
|
548
549
|
static rb_internal_thread_specific_key_t atomic_ruby_thread_pool_worker_key;
|
|
550
|
+
static rb_nativethread_lock_t atomic_ruby_thread_pool_monitor_lock;
|
|
551
|
+
static unsigned int atomic_ruby_thread_pool_monitor_count;
|
|
552
|
+
static rb_internal_thread_event_hook_t *atomic_ruby_thread_pool_event_hook;
|
|
553
|
+
|
|
554
|
+
static void atomic_ruby_thread_pool_event_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *user_data);
|
|
555
|
+
|
|
556
|
+
static void atomic_ruby_thread_pool_monitor_stop(atomic_ruby_thread_pool_monitor_t *monitor) {
|
|
557
|
+
rb_nativethread_lock_lock(&atomic_ruby_thread_pool_monitor_lock);
|
|
558
|
+
if (monitor->active) {
|
|
559
|
+
monitor->active = false;
|
|
560
|
+
atomic_ruby_thread_pool_monitor_count--;
|
|
561
|
+
if (atomic_ruby_thread_pool_monitor_count == 0) {
|
|
562
|
+
rb_internal_thread_remove_event_hook(atomic_ruby_thread_pool_event_hook);
|
|
563
|
+
atomic_ruby_thread_pool_event_hook = NULL;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
rb_nativethread_lock_unlock(&atomic_ruby_thread_pool_monitor_lock);
|
|
567
|
+
}
|
|
549
568
|
|
|
550
569
|
static void atomic_ruby_thread_pool_monitor_free(void *ptr) {
|
|
570
|
+
atomic_ruby_thread_pool_monitor_stop(ptr);
|
|
551
571
|
xfree(ptr);
|
|
552
572
|
}
|
|
553
573
|
|
|
@@ -655,9 +675,37 @@ static VALUE rb_cThreadPoolMonitor_allocate(VALUE klass) {
|
|
|
655
675
|
atomic_init(&monitor->waiting_time, 0);
|
|
656
676
|
atomic_init(&monitor->blocked_time, 0);
|
|
657
677
|
atomic_init(&monitor->running_cpu_time, 0);
|
|
678
|
+
monitor->active = false;
|
|
658
679
|
return obj;
|
|
659
680
|
}
|
|
660
681
|
|
|
682
|
+
static VALUE rb_cThreadPoolMonitor_start(VALUE self) {
|
|
683
|
+
atomic_ruby_thread_pool_monitor_t *monitor;
|
|
684
|
+
TypedData_Get_Struct(self, atomic_ruby_thread_pool_monitor_t, &atomic_ruby_thread_pool_monitor_type, monitor);
|
|
685
|
+
rb_nativethread_lock_lock(&atomic_ruby_thread_pool_monitor_lock);
|
|
686
|
+
if (!monitor->active) {
|
|
687
|
+
monitor->active = true;
|
|
688
|
+
if (atomic_ruby_thread_pool_monitor_count++ == 0) {
|
|
689
|
+
atomic_ruby_thread_pool_event_hook = rb_internal_thread_add_event_hook(
|
|
690
|
+
atomic_ruby_thread_pool_event_callback,
|
|
691
|
+
RUBY_INTERNAL_THREAD_EVENT_READY |
|
|
692
|
+
RUBY_INTERNAL_THREAD_EVENT_RESUMED |
|
|
693
|
+
RUBY_INTERNAL_THREAD_EVENT_SUSPENDED,
|
|
694
|
+
NULL
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
rb_nativethread_lock_unlock(&atomic_ruby_thread_pool_monitor_lock);
|
|
699
|
+
return Qnil;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
static VALUE rb_cThreadPoolMonitor_stop(VALUE self) {
|
|
703
|
+
atomic_ruby_thread_pool_monitor_t *monitor;
|
|
704
|
+
TypedData_Get_Struct(self, atomic_ruby_thread_pool_monitor_t, &atomic_ruby_thread_pool_monitor_type, monitor);
|
|
705
|
+
atomic_ruby_thread_pool_monitor_stop(monitor);
|
|
706
|
+
return Qnil;
|
|
707
|
+
}
|
|
708
|
+
|
|
661
709
|
static VALUE rb_cThreadPoolMonitor_register_worker(VALUE self) {
|
|
662
710
|
atomic_ruby_thread_pool_monitor_t *monitor;
|
|
663
711
|
TypedData_Get_Struct(self, atomic_ruby_thread_pool_monitor_t, &atomic_ruby_thread_pool_monitor_type, monitor);
|
|
@@ -756,15 +804,13 @@ RUBY_FUNC_EXPORTED void Init_atomic_ruby(void) {
|
|
|
756
804
|
rb_define_private_method(rb_cAtomicConditionVariable, "_waiter_count", rb_cAtomicConditionVariable_waiter_count, 0);
|
|
757
805
|
|
|
758
806
|
atomic_ruby_thread_pool_worker_key = rb_internal_thread_specific_key_create();
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
RUBY_INTERNAL_THREAD_EVENT_RESUMED |
|
|
763
|
-
RUBY_INTERNAL_THREAD_EVENT_SUSPENDED,
|
|
764
|
-
NULL
|
|
765
|
-
);
|
|
807
|
+
rb_nativethread_lock_initialize(&atomic_ruby_thread_pool_monitor_lock);
|
|
808
|
+
atomic_ruby_thread_pool_monitor_count = 0;
|
|
809
|
+
atomic_ruby_thread_pool_event_hook = NULL;
|
|
766
810
|
VALUE rb_cThreadPoolMonitor = rb_define_class_under(rb_mAtomicRuby, "ThreadPoolMonitor", rb_cObject);
|
|
767
811
|
rb_define_alloc_func(rb_cThreadPoolMonitor, rb_cThreadPoolMonitor_allocate);
|
|
812
|
+
rb_define_method(rb_cThreadPoolMonitor, "start", rb_cThreadPoolMonitor_start, 0);
|
|
813
|
+
rb_define_method(rb_cThreadPoolMonitor, "stop", rb_cThreadPoolMonitor_stop, 0);
|
|
768
814
|
rb_define_method(rb_cThreadPoolMonitor, "register_worker", rb_cThreadPoolMonitor_register_worker, 0);
|
|
769
815
|
rb_define_method(rb_cThreadPoolMonitor, "unregister_worker", rb_cThreadPoolMonitor_unregister_worker, 0);
|
|
770
816
|
rb_define_method(rb_cThreadPoolMonitor, "start_work", rb_cThreadPoolMonitor_start_work, 0);
|
|
@@ -125,6 +125,7 @@ module AtomicRuby
|
|
|
125
125
|
@autoscale_available = AtomicConditionVariable.new
|
|
126
126
|
@trim_requested = AtomicBoolean.new(false)
|
|
127
127
|
@thread_pool_monitor = ThreadPoolMonitor.new
|
|
128
|
+
@thread_pool_monitor.start
|
|
128
129
|
end
|
|
129
130
|
|
|
130
131
|
start
|
|
@@ -264,6 +265,7 @@ module AtomicRuby
|
|
|
264
265
|
@work_available.broadcast
|
|
265
266
|
@autoscaler&.join
|
|
266
267
|
@threads.each(&:join)
|
|
268
|
+
@thread_pool_monitor&.stop
|
|
267
269
|
end
|
|
268
270
|
|
|
269
271
|
private
|
data/lib/atomic-ruby/version.rb
CHANGED