class Crystal::EventLoop::Polling::Arena(T, BLOCK_BYTESIZE)

Overview

Generational Arena.

The arena allocates objects T at a predefined index. The object iself is uninitialized (outside of having its memory initialized to zero). The object can be allocated and later retrieved using the generation index (Arena::Index) that contains both the actual index (Int32) and the generation number (UInt32). Deallocating the object increases the generation number, which allows the object to be reallocated later on. Trying to retrieve the allocation using the generation index will fail if the generation number changed (it's a new allocation).

This arena isn't generic as it won't keep a list of free indexes. It assumes that something else will maintain the uniqueness of indexes and reuse indexes as much as possible instead of growing.

For example this arena is used to hold Crystal::EventLoop::Polling::PollDescriptor allocations for all the fd in a program, where the fd is used as the index. They're unique to the process and the OS always reuses the lowest fd numbers before growing.

Thread safety: the memory region is divided in blocks of size BLOCK_BYTESIZE allocated in the GC. Pointers are thus never invalidated. Mutating the blocks is protected by a mutual exclusion lock. Individual (de)allocations of objects are protected with a fine grained lock.

Guarantees: blocks' memory is initialized to zero, which means T objects are initialized to zero by default, then #free will also clear the memory, so the next allocation shall be initialized to zero, too.

Defined in:

crystal/event_loop/polling/arena.cr

Constant Summary

INVALID_INDEX = Index.new(-1, 0)

Constructors

Instance Method Summary

Instance methods inherited from class Reference

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other)
==
, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil)
same?
, to_s(io : IO) : Nil to_s

Constructor methods inherited from class Reference

new new, unsafe_construct(address : Pointer, *args, **opts) : self unsafe_construct

Class methods inherited from class Reference

pre_initialize(address : Pointer) pre_initialize

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash
hash
, in?(collection : Object) : Bool
in?(*values : Object) : Bool
in?
, inspect(io : IO) : Nil
inspect : String
inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil!
not_nil!
, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String
to_json
, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil
to_pretty_json
, to_s(io : IO) : Nil
to_s : String
to_s
, to_yaml(io : IO) : Nil
to_yaml : String
to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io, root : String)
from_json(string_or_io)
from_json
, from_yaml(string_or_io : String | IO) from_yaml

Macros inherited from class Object

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

Constructor Detail

def self.new(capacity : Int32) #

[View source]

Instance Method Detail

def allocate_at(index : Int32, & : Pointer(T), Index -> ) : Index | Nil #

Same as #allocate_at? but raises when already allocated.


[View source]
def allocate_at?(index : Int32, & : Pointer(T), Index -> ) : Index | Nil #

Allocates the object at index unless already allocated, then yields a pointer to the object at index and the current generation index to later retrieve and free the allocated object. Eventually returns the generation index.

Does nothing if the object has already been allocated and returns nil.

There are no generational checks. Raises if index is out of bounds.


[View source]
def each_index(&) : Nil #

Iterates all allocated objects, yields the actual index as well as the generation index.


[View source]
def free(index : Index, &) : Nil #

Yields the object previously allocated at index then releases it.

Does nothing if the object isn't allocated, the generation has changed or index is out of bounds.


[View source]
def get(index : Index, &) : Nil #

Yields a pointer to the object previously allocated at index.

Raises if the object isn't allocated, the generation has changed (i.e. the object has been freed then reallocated) or index is out of bounds.


[View source]
def get?(index : Index, &) : Bool #

Yields a pointer to the object previously allocated at index and returns true.

Does nothing if the object isn't allocated, the generation has changed or index is out of bounds.


[View source]