Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/sdl/tv.cr
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ColorMaker
end

def make_alpha_color(multiplier)
rand = Random::DEFAULT.next_int
rand = Random.default.next_int
r = ((rand >> 16) % 256).to_i
g = ((rand >> 8) % 256).to_i
b = (rand % 256).to_i
Expand Down
2 changes: 1 addition & 1 deletion spec/std/file_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe "File" do

rbuf = Bytes.new(5120)
wbuf = Bytes.new(5120)
Random::DEFAULT.random_bytes(wbuf)
Random.default.random_bytes(wbuf)

File.open(path, "r") do |reader|
# opened fifo for read: wait for thread to open for write
Expand Down
2 changes: 1 addition & 1 deletion spec/std/random_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ describe "Random" do
end

it "gets a random bool" do
Random::DEFAULT.next_bool.should be_a(Bool)
Random.default.next_bool.should be_a(Bool)
end

it "generates by accumulation" do
Expand Down
2 changes: 1 addition & 1 deletion spec/std/spec/context_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe Spec::ExampleGroup do
root = build_spec("f.cr", count: 20)

before_randomize = all_spec_descriptions(root)
root.randomize(Random::DEFAULT)
root.randomize(Random.default)
after_randomize = all_spec_descriptions(root)

after_randomize.should_not eq before_randomize
Expand Down
2 changes: 1 addition & 1 deletion src/array.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,7 @@ class Array(T)

# Returns an array with all the elements in the collection randomized
# using the given *random* number generator.
def shuffle(random : Random = Random::DEFAULT) : Array(T)
def shuffle(random : Random = Random.default) : Array(T)
dup.shuffle!(random)
end

Expand Down
2 changes: 1 addition & 1 deletion src/colorize.cr
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
# ```
# require "colorize"
#
# "foo".colorize(Random::DEFAULT.next_bool ? :green : :default)
# "foo".colorize(Random.default.next_bool ? :green : :default)
# ```
#
# Available colors are:
Expand Down
2 changes: 1 addition & 1 deletion src/crystal/system/file.cr
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module Crystal::System::File

LOWER_ALPHANUM = "0123456789abcdefghijklmnopqrstuvwxyz".to_slice

def self.mktemp(prefix : String?, suffix : String?, dir : String, random : ::Random = ::Random::DEFAULT) : {FileDescriptor::Handle, String, Bool}
def self.mktemp(prefix : String?, suffix : String?, dir : String, random : ::Random = ::Random.default) : {FileDescriptor::Handle, String, Bool}
flags = LibC::O_RDWR | LibC::O_CREAT | LibC::O_EXCL
perm = ::File::Permissions.new(0o600)

Expand Down
2 changes: 2 additions & 0 deletions src/crystal/system/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ end
{% raise "Thread not supported" %}
{% end %}

require "./thread_local_storage"

# :nodoc:
class Thread
include Crystal::System::Thread
Expand Down
41 changes: 0 additions & 41 deletions src/crystal/system/thread_local.cr

This file was deleted.

119 changes: 119 additions & 0 deletions src/crystal/system/thread_local_storage.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{% if flag?(:win32) && flag?(:gnu) %}
require "c/fibersapi"
{% end %}

# :nodoc:
class Thread
# :nodoc:
#
# The GC can't access the local storage, so we must keep a pointer to the
# table on the Thread local that is reachable for as long as the thread is
# alive.
#
# We could spare this pointer if the table was uncollectible: the GC allocates
# the memory, always scans it (even without explicit references) and never
# collects it until it's explicitly told to be freed.
protected property local_storage : LocalStorage?

# :nodoc:
class LocalStorage
# FIXME: we should be able to use @[ThreadLocal] on every target: the
# compiler needs to set the llvm::TargetOptions::EmulatedLTS option for
# Android < 29, MinGW and OpenBSD, though mostly for overall consistency
# since it might be set by default for some targets already.

{% if flag?(:android) || flag?(:openbsd) %}
@@key = uninitialized LibC::PthreadKeyT
err = LibC.pthread_key_create(pointerof(@@key), nil)
raise RuntimeError.from_os_error("pthread_key_create", Errno.new(err)) unless err == 0

def self.local_table? : LocalStorage?
ptr = LibC.pthread_getspecific(@@key)
ptr.as(LocalStorage) unless ptr.null?
end

def self.local_table=(local_table : LocalStorage)
err = LibC.pthread_setspecific(@@key, local_table.as(Void*))
raise RuntimeError.from_os_error("pthread_setspecific", Errno.new(err)) unless err == 0
Thread.current.local_storage = local_table
end
{% elsif flag?(:win32) && flag?(:gnu) %}
@@key = uninitialized LibC::DWORD
@@key = LibC.FlsAlloc(nil)
raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if @@key == LibC::FLS_OUT_OF_INDEXES

def self.local_table? : LocalStorage?
ptr = LibC.FlsGetValue(@@key)
ptr.as(LocalStorage) unless ptr.null?
end

def self.local_table=(local_table : LocalStorage)
ret = LibC.FlsSetValue(@@key, local_table.as(Void*))
raise RuntimeError.from_winerror("FlsSetValue") if ret == 0
Thread.current.local_storage = local_table
end
{% else %}
@[ThreadLocal]
@@local_table : LocalStorage?

def self.local_table? : LocalStorage?
@@local_table
end

def self.local_table=(@@local_table : LocalStorage)
Thread.current.local_storage = local_table
end
{% end %}

def self.local_table : LocalStorage
local_table? || self.local_table = LocalStorage.new
end

def finalize
{% for var, index in @type.class_vars %}
{% if var.name.starts_with?("__destructor") %}
@@{{var.name}}.try(&.call(self)) rescue nil
{% end %}
{% end %}
end
end

macro thread_local(decl, destructor = nil)
{% raise "Expected TypeDeclaration" unless decl.is_a?(TypeDeclaration) %}

protected def self.{{decl.var.id}}(&block : -> {{decl.type}}) : {{decl.type}}
table = ::Thread::LocalStorage.local_table
if (value = table.%var).nil?
{% if destructor %}
::Thread::LocalStorage.__set_destructor%var
{% end %}
table.%var = yield
else
value
end
end

class ::Thread::LocalStorage
property %var : {{decl.type}} | Nil

{% if destructor %}
@@__destructor%var = uninitialized Proc(self, Nil)
@@__once_destructor%var = Atomic(Bool).new(false)

# delay setting the destructor to when we need it, to avoid extra
# dependencies just because we declared a TLS but don't use it (for
# example libpcre2)
def self.__set_destructor%var
return if @@__once_destructor%var.swap(true, :relaxed)

@@__destructor%var = ->(table : self) {
if value = table.%var
{{destructor}}.call(value)
end
nil
}
end
{% end %}
end
end
end
34 changes: 0 additions & 34 deletions src/crystal/system/unix/thread_local.cr

This file was deleted.

21 changes: 0 additions & 21 deletions src/crystal/system/wasi/thread_local.cr

This file was deleted.

34 changes: 0 additions & 34 deletions src/crystal/system/win32/thread_local.cr

This file was deleted.

4 changes: 2 additions & 2 deletions src/enumerable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ module Enumerable(T)
# {1, 2, 3, 4, 5}.sample(2) # => [3, 4]
# {1, 2, 3, 4, 5}.sample(2, Random.new(1)) # => [1, 5]
# ```
def sample(n : Int, random : Random = Random::DEFAULT) : Array(T)
def sample(n : Int, random : Random = Random.default) : Array(T)
raise ArgumentError.new("Can't sample negative number of elements") if n < 0

# Unweighted reservoir sampling:
Expand Down Expand Up @@ -1613,7 +1613,7 @@ module Enumerable(T)
# a.sample # => 1
# a.sample(Random.new(1)) # => 3
# ```
def sample(random : Random = Random::DEFAULT) : T
def sample(random : Random = Random.default) : T
value = uninitialized T
found = false

Expand Down
2 changes: 1 addition & 1 deletion src/http/web_socket/protocol.cr
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class HTTP::WebSocket::Protocol
private def write_payload(data)
return @io.write(data) unless @masked

key = Random::DEFAULT.next_int
key = Random.default.next_int
mask_array = key.unsafe_as(StaticArray(UInt8, 4))
@io.write mask_array.to_slice

Expand Down
4 changes: 2 additions & 2 deletions src/indexable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ module Indexable(T)
# a.sample # => 1
# a.sample(Random.new(1)) # => 2
# ```
def sample(random : Random = Random::DEFAULT)
def sample(random : Random = Random.default)
raise IndexError.new("Can't sample empty collection") if size == 0
unsafe_fetch(random.rand(size))
end
Expand All @@ -964,7 +964,7 @@ module Indexable(T)
# If `self` is not empty and `n` is equal to 1, calls `sample(random)` exactly
# once. Thus, *random* will be left in a different state compared to the
# implementation in `Enumerable`.
def sample(n : Int, random : Random = Random::DEFAULT) : Array(T)
def sample(n : Int, random : Random = Random.default) : Array(T)
return super unless n == 1

if empty?
Expand Down
2 changes: 1 addition & 1 deletion src/indexable/mutable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ module Indexable::Mutable(T)
# a.shuffle!(Random.new(42)) # => [3, 2, 4, 5, 1]
# a # => [3, 2, 4, 5, 1]
# ```
def shuffle!(random : Random = Random::DEFAULT) : self
def shuffle!(random : Random = Random.default) : self
(size - 1).downto(1) do |i|
j = random.rand(i + 1)
swap(i, j)
Expand Down
1 change: 1 addition & 0 deletions src/kernel.cr
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ end

# additional reinitialization
->Random::DEFAULT.new_seed,
-> { Random.default.new_seed },
] of -> Nil
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/pointer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ struct Pointer(T)
# ptr.shuffle!(4)
# ptr # [3, 4, 1, 2]
# ```
def shuffle!(count : Int, random = Random::DEFAULT)
def shuffle!(count : Int, random = Random.default)
(count - 1).downto(1) do |i|
j = random.rand(i + 1)
swap(i, j)
Expand Down
Loading