SafeTypes2
Loading...
Searching...
No Matches
Object System

Type Hierarchy

The "object" type (denoted by s2obj_t) is the base type for all externally-exposed types except a few (e.g. s2iter_t). It defines common interface for derived types.

Before 2025-02-17, all derived types defined by SafeTypes2 were incomplete (C language concept), as they're meant to be used from pointer handles. This is still the case - although you technically can declare a SafeTypes2 object either locally or statically, their interaction with the garbage collection, and even with regard to reference and kept counts when you're opting out of GC, are completely undefined.

The reason now they're being defined to be complete, is that the way they were defined were not compatible with C89 - a compatibility goal which @dannyniu would like to achieve to maximize the audience of the library; also, this make it easier for 3rd-party libraries and applications to create further derived types.

The internal data structures have tag names prefixed with "s2ctx_", whereas externally visible ones are defined as types and not prefixed as such.

Type Identifier Name Space.

Rules of composition:

  • 0x3000: container/plain/opaque type class flag mask.
  • 0x0xxx: plain type.
  • 0x10xx: container type.
  • 0x2xxx: opaque (application-defined) type.
    Note
    2024-11-05: type class had been re-specified as prefix-free codes.
  • if <plain type>:
    • 0x0f00: plain type class mask.
    • 0x0000: string/blob/misc.
    • 0x0100: integer type.
    • 0x0200: floating point type.
    • 0x0300: array type.
  • if <integer type> or <floating point type>:
    • 0x00c0: endianness mask - not applicable to strings and blobs.
    • 0x0000: host endianness.
    • 0x0040: little-endian.
    • 0x0080: big-endian.
    • 0x003f: plain type width mask.
  • if <array type>:
    • 0x00ff: array element length mask.
  • pre-defined values:
    • 0x0000: exact value for the null type.
    • 0x0001: exact value for the raw data type.
    • 0x0002: exact value for utf-8 string type.
    • 0x0003: exact value for 8-bit data type.

Resource Management and Garbage Collection.

The SafeTypes2 GC is threading-aware with the help of a reader-writer lock. In multi-threaded applications, threads obtain "reader" locks to prevent GC from operating on data structures that the threads may be using. When GC operates, the "writer" lock is locked, and all threads are stalled and prevented from operating on objects so that GC can safely traverse the graph of reachable objects, marking them and releasing unreachable objects as needed.

The "reader" lock is recursive - threads can invoke codes from 3rd-party libraries and not worry they interfere with the calling code; The "reader" lock is also "rewindable" - if while a "reader" lock is held by the calling thread, an acquire of the "writer" lock (implicitly invoked as part of s2gc_collect) automatically clears up whilest remembering the "reader" lock.

As such, when all involved threads requests "writer" lock, the GC would eventually operate, regardless of

  • which threads first requested GC,
  • how many threads are holding the "reader" lock,
  • how many level of recursion the "reader" locks are in,

As long as all threads that had held any "reader" lock eventually calls s2gc_collect.

This mechanism applies to the GC, and not the rest of the application - threads still need to prevent threading conflict using explicit synchronization.