This repository has been archived by the owner on Dec 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
3,082 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Bool has only two possible values: `true` and `false`. They are constructed using these literals: | ||
# | ||
# ``` | ||
# true # A Bool that is true | ||
# false # A Bool that is false | ||
# ``` | ||
struct Bool | ||
# Bitwise OR. Returns `true` if this bool or *other* is `true`, otherwise returns `false`. | ||
# | ||
# ``` | ||
# false | false # => false | ||
# false | true # => true | ||
# true | false # => true | ||
# true | true # => true | ||
# ``` | ||
def |(other : Bool) | ||
self ? true : other | ||
end | ||
|
||
# Bitwise AND. Returns `true` if this bool and *other* are `true`, otherwise returns `false`. | ||
# | ||
# ``` | ||
# false & false # => false | ||
# false & true # => false | ||
# true & false # => false | ||
# true & true # => true | ||
# ``` | ||
def &(other : Bool) | ||
self ? other : false | ||
end | ||
|
||
# Exclusive OR. Returns `true` if this bool is different from *other*, otherwise returns `false`. | ||
# | ||
# ``` | ||
# false ^ false # => false | ||
# false ^ true # => true | ||
# true ^ false # => true | ||
# true ^ true # => false | ||
# ``` | ||
def ^(other : Bool) | ||
self != other | ||
end | ||
|
||
# Returns a hash value for this boolean: 0 for `false`, 1 for `true`. | ||
def hash | ||
self ? 1 : 0 | ||
end | ||
|
||
# Returns `"true"` for `true` and `"false"` for `false`. | ||
def to_s | ||
self ? "true" : "false" | ||
end | ||
|
||
# Appends `"true"` for `true` and `"false"` for `false` to the given IO. | ||
# def to_s(io) | ||
# io << to_s | ||
# end | ||
|
||
def clone | ||
self | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# The `Comparable` mixin is used by classes whose objects may be ordered. | ||
# | ||
# Including types must provide an `<=>` method, which compares the receiver against | ||
# another object, returning `-1`, `0`, or `+1` depending on whether the receiver is less than, | ||
# equal to, or greater than the other object. | ||
# | ||
# `Comparable` uses `<=>` to implement the conventional comparison operators (`<`, `<=`, `==`, `>=`, and `>`). | ||
module Comparable(T) | ||
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `-1`. | ||
def <(other : T) | ||
(self <=> other) < 0 | ||
end | ||
|
||
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `-1` or `0`. | ||
def <=(other : T) | ||
(self <=> other) <= 0 | ||
end | ||
|
||
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `0`. | ||
# Also returns `true` if this and *other* are the same object. | ||
def ==(other : T) | ||
if self.is_a?(Reference) | ||
# Need to do two different comparisons because the compiler doesn't yet | ||
# restrict something like `other.is_a?(Reference) || other.is_a?(Nil)`. | ||
# See #2461 | ||
return true if other.is_a?(Reference) && self.same?(other) | ||
return true if other.is_a?(Nil) && self.same?(other) | ||
end | ||
|
||
(self <=> other) == 0 | ||
end | ||
|
||
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `1`. | ||
def >(other : T) | ||
(self <=> other) > 0 | ||
end | ||
|
||
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `1` or `0`. | ||
def >=(other : T) | ||
(self <=> other) >= 0 | ||
end | ||
|
||
# Comparison operator. Returns `0` if the two objects are equal, | ||
# a negative number if this object is considered less than *other*, | ||
# or a positive number otherwise. | ||
# | ||
# Subclasses define this method to provide class-specific ordering. | ||
# | ||
# ``` | ||
# # Sort in a descending way | ||
# [4, 7, 2].sort { |x, y| y <=> x } # => [7, 4, 2] | ||
# ``` | ||
abstract def <=>(other : T) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module GC | ||
def self.malloc(size : Int) | ||
__crystal_malloc(size.to_u32) | ||
end | ||
|
||
def self.malloc_atomic(size : Int) | ||
__crystal_malloc_atomic(size.to_u32) | ||
end | ||
|
||
def self.realloc(pointer : Void*, size : Int) | ||
__crystal_realloc(pointer, size.to_u32) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# @[Link("pthread")] | ||
# {% if flag?(:freebsd) %} | ||
# @[Link("gc-threaded")] | ||
# {% else %} | ||
# @[Link("gc")] | ||
# {% end %} | ||
|
||
lib LibGC | ||
alias Int = LibCR::Int | ||
alias SizeT = LibCR::SizeT | ||
alias Word = LibCR::ULong | ||
|
||
fun init = GC_init | ||
fun malloc = GC_malloc(size : SizeT) : Void* | ||
fun malloc_atomic = GC_malloc_atomic(size : SizeT) : Void* | ||
fun realloc = GC_realloc(ptr : Void*, size : SizeT) : Void* | ||
fun free = GC_free(ptr : Void*) | ||
fun collect_a_little = GC_collect_a_little : Int | ||
fun collect = GC_gcollect | ||
fun add_roots = GC_add_roots(low : Void*, high : Void*) | ||
fun enable = GC_enable | ||
fun disable = GC_disable | ||
fun set_handle_fork = GC_set_handle_fork(value : Int) | ||
|
||
fun base = GC_base(displaced_pointer : Void*) : Void* | ||
fun is_heap_ptr = GC_is_heap_ptr(pointer : Void*) : Int | ||
fun general_register_disappearing_link = GC_general_register_disappearing_link(link : Void**, obj : Void*) : Int | ||
|
||
type Finalizer = Void*, Void* -> | ||
fun register_finalizer = GC_register_finalizer(obj : Void*, fn : Finalizer, cd : Void*, ofn : Finalizer*, ocd : Void**) | ||
fun register_finalizer_ignore_self = GC_register_finalizer_ignore_self(obj : Void*, fn : Finalizer, cd : Void*, ofn : Finalizer*, ocd : Void**) | ||
fun invoke_finalizers = GC_invoke_finalizers : Int | ||
|
||
fun get_heap_usage_safe = GC_get_heap_usage_safe(heap_size : Word*, free_bytes : Word*, unmapped_bytes : Word*, bytes_since_gc : Word*, total_bytes : Word*) | ||
fun set_max_heap_size = GC_set_max_heap_size(Word) | ||
|
||
fun get_start_callback = GC_get_start_callback : Void* | ||
fun set_start_callback = GC_set_start_callback(callback : ->) | ||
|
||
fun set_push_other_roots = GC_set_push_other_roots(proc : ->) | ||
fun get_push_other_roots = GC_get_push_other_roots : -> | ||
|
||
fun push_all_eager = GC_push_all_eager(bottom : Void*, top : Void*) | ||
|
||
$stackbottom = GC_stackbottom : Void* | ||
|
||
fun set_on_collection_event = GC_set_on_collection_event(cb : ->) | ||
|
||
$gc_no = GC_gc_no : LibCR::ULong | ||
$bytes_found = GC_bytes_found : LibCR::Long | ||
# GC_on_collection_event isn't exported. Can't collect totals without it. | ||
# bytes_allocd, heap_size, unmapped_bytes are macros | ||
|
||
fun size = GC_size(addr : Void*) : LibCR::SizeT | ||
|
||
# Boehm GC requires to use GC_pthread_create and GC_pthread_join instead of pthread_create and pthread_join | ||
fun pthread_create = GC_pthread_create(thread : LibCR::PthreadT*, attr : Void*, start : Void* ->, arg : Void*) : LibCR::Int | ||
fun pthread_join = GC_pthread_join(thread : LibCR::PthreadT, value : Void**) : LibCR::Int | ||
fun pthread_detach = GC_pthread_detach(thread : LibCR::PthreadT) : LibCR::Int | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc(size : UInt32) : Void* | ||
LibGC.malloc(size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc_atomic(size : UInt32) : Void* | ||
LibGC.malloc_atomic(size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_realloc(ptr : Void*, size : UInt32) : Void* | ||
LibGC.realloc(ptr, size) | ||
end | ||
|
||
module GC | ||
def self.init | ||
LibGC.set_handle_fork(1) | ||
LibGC.init | ||
end | ||
|
||
def self.collect | ||
LibGC.collect | ||
end | ||
|
||
def self.enable | ||
LibGC.enable | ||
end | ||
|
||
def self.disable | ||
LibGC.disable | ||
end | ||
|
||
def self.free(pointer : Void*) | ||
LibGC.free(pointer) | ||
end | ||
|
||
def self.add_finalizer(object : Reference) | ||
add_finalizer_impl(object) | ||
end | ||
|
||
def self.add_finalizer(object) | ||
# Nothing | ||
end | ||
|
||
private def self.add_finalizer_impl(object : T) forall T | ||
LibGC.register_finalizer_ignore_self(object.as(Void*), | ||
->(obj, data) { obj.as(T).finalize }, | ||
nil, nil, nil) | ||
nil | ||
end | ||
|
||
def self.add_root(object : Reference) | ||
roots = @@roots ||= [] of Pointer(Void) | ||
roots << Pointer(Void).new(object.object_id) | ||
end | ||
|
||
def self.register_disappearing_link(pointer : Void**) | ||
base = LibGC.base(pointer.value) | ||
LibGC.general_register_disappearing_link(pointer, base) | ||
end | ||
|
||
def self.is_heap_ptr(pointer : Void*) | ||
LibGC.is_heap_ptr(pointer) != 0 | ||
end | ||
|
||
record Stats, | ||
# collections : LibCR::ULong, | ||
# bytes_found : LibCR::Long, | ||
heap_size : LibCR::ULong, | ||
free_bytes : LibCR::ULong, | ||
unmapped_bytes : LibCR::ULong, | ||
bytes_since_gc : LibCR::ULong, | ||
total_bytes : LibCR::ULong | ||
|
||
def self.stats | ||
LibGC.get_heap_usage_safe(out heap_size, out free_bytes, out unmapped_bytes, out bytes_since_gc, out total_bytes) | ||
# collections = LibGC.gc_no - 1 | ||
# bytes_found = LibGC.bytes_found | ||
|
||
Stats.new( | ||
# collections: collections, | ||
# bytes_found: bytes_found, | ||
heap_size: heap_size, | ||
free_bytes: free_bytes, | ||
unmapped_bytes: unmapped_bytes, | ||
bytes_since_gc: bytes_since_gc, | ||
total_bytes: total_bytes | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
lib LibCR | ||
alias Int8T = SChar | ||
alias Int16T = Short | ||
alias Int32T = Int | ||
alias Int64T = Long | ||
alias UInt8T = Char | ||
alias UInt16T = UShort | ||
alias UInt32T = UInt | ||
alias UInt64T = ULong | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
require "../stddef" | ||
require "../stdint" | ||
|
||
lib LibCR | ||
alias BlkcntT = Long | ||
alias BlksizeT = Long | ||
alias ClockT = Long | ||
alias ClockidT = Int | ||
alias DevT = ULong | ||
alias GidT = UInt | ||
alias IdT = UInt | ||
alias InoT = ULong | ||
alias ModeT = UInt | ||
alias NlinkT = ULong | ||
alias OffT = Long | ||
alias PidT = Int | ||
|
||
union PthreadAttrTU | ||
__i : StaticArray(Int, 14) | ||
__vi : StaticArray(Int, 14) | ||
__s : StaticArray(ULong, 7) | ||
end | ||
|
||
struct PthreadAttrT | ||
__u : PthreadAttrTU | ||
end | ||
|
||
union PthreadCondTU | ||
__i : StaticArray(Int, 12) | ||
__vi : StaticArray(Int, 12) | ||
__p : StaticArray(Void*, 6) | ||
end | ||
|
||
struct PthreadCondT | ||
__u : PthreadCondTU | ||
end | ||
|
||
struct PthreadCondattrT | ||
__attr : UInt | ||
end | ||
|
||
union PthreadMutexTU | ||
__i : StaticArray(Int, 10) | ||
__vi : StaticArray(Int, 10) | ||
__p : StaticArray(Void*, 5) | ||
end | ||
|
||
struct PthreadMutexT | ||
__u : PthreadMutexTU | ||
end | ||
|
||
struct PthreadMutexattrT | ||
__attr : UInt | ||
end | ||
|
||
type PthreadT = Void* | ||
alias SSizeT = Long | ||
alias SusecondsT = Long | ||
alias TimeT = Long | ||
alias UidT = UInt | ||
end |
Oops, something went wrong.