A constant is assigned a value once. Only the constant itself is immutable (can't replace its value for another one). The value isn't immutable.
For example FOO = [] of String declares an array that will remain the same
| lib LibGC | |
| GC_DS_LENGTH = 0 | |
| fun GC_new_free_list : Void** | |
| fun GC_new_kind(freelist : Void**, descr : GC_word, adjust : Int, clear : Int) : UInt | |
| fun GC_generic_malloc(SizeT, knd : UInt) : Void* | |
| end | |
| module GC | |
| UNINITIALIZED_OBJ_KIND = LibGC.GC_new_kind(LibGC.GC_new_free_list, descr: LibGC::GC_DS_LENGTH, adjust: 1, clear: 0) |
The use-case is multiple threads trying to submit operations to an io_uring SQ
ring, using a rwlock, a local sq_tail to be synchronized with the tail shared
with the kernel (sq_ktail).
Maybe we can submit to the SQ ring from multiple threads with reduced contentions
using a rwlock instead of a mutex. The read lock would protect incrementing the
local sq_tail (updated with a CAS) and preparing the SQE, while the write lock
would protect updates to the sq_ktail shared with the kernel (updated with a
| require "crystal/spin_lock" | |
| require "crystal/pointer_linked_list" | |
| # Synchronize execution of concurrently running fibers. | |
| # | |
| # This can be used to replace polling with a waiting list that can be resumed | |
| # when resources are available, while still behaving inside a mutually exclusive | |
| # context: when a waiting fiber is resumed, the mutex will be relocked. | |
| # | |
| # Can also be used as a notification system without a mutex. |
| diff --git a/src/compiler/crystal/codegen/ast.cr b/src/compiler/crystal/codegen/ast.cr | |
| index ab4fa76d4..ed3465be1 100644 | |
| --- a/src/compiler/crystal/codegen/ast.cr | |
| +++ b/src/compiler/crystal/codegen/ast.cr | |
| @@ -72,6 +72,10 @@ module Crystal | |
| nil | |
| end | |
| + def linkage | |
| + nil |
| # Crystal port of the mutex from the "nsync" library. | |
| # | |
| # Copyright 2016 Google Inc. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # |
Each test creates N items (not measured) and shuffles them (unless said otherwise) then measures how long the operation(s) take to complete. The test repeats itself 10 times. The average time per operation of all runs is eventually printed.
| diff --git a/src/compiler/crystal/compiler.cr b/src/compiler/crystal/compiler.cr | |
| index 38880ee9e..966e2f954 100644 | |
| --- a/src/compiler/crystal/compiler.cr | |
| +++ b/src/compiler/crystal/compiler.cr | |
| @@ -523,13 +523,17 @@ module Crystal | |
| private def fork_codegen(units, n_threads) | |
| workers = fork_workers(n_threads) do |input, output| | |
| while i = input.gets(chomp: true).presence | |
| + Crystal::System.print_error "CODEGEN pid=#{LibC.getpid} STDIN => #{i}\n" | |
| unit = units[i.to_i] |
| class STW | |
| def initialize | |
| @running = true | |
| @started = Atomic(Int32).new(0) | |
| @count = Atomic(Int32).new(0) | |
| @threads = [] of Thread | |
| end | |
| def start_thread | |
| @threads << Thread.new do |