Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

current_thread_storage

emutls.current_thread_storage
const current_thread_storage = struct

File

lib/compiler_rt/emutls.zig:149

Code

const current_thread_storage = struct {
    var key: std.c.pthread_key_t = undefined;
    var init_mutex: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER;
    var init_done: bool = false;

    /// Return a per thread ObjectArray with at least the expected index.
    pub fn getArray(index: usize) *ObjectArray {
        if (current_thread_storage.getspecific()) |array| {
            // we already have a specific. just ensure the array is
            // big enough for the wanted index.
            return array.ensureLength(index);
        }

        // no specific. we need to create a new array.

        // make it to contains at least 16 objects (to avoid too much
        // reallocation at startup).
        const size = @max(16, index);

        // create a new array and store it.
        const array: *ObjectArray = ObjectArray.init(size);
        current_thread_storage.setspecific(array);
        return array;
    }

    /// Return casted thread specific value.
    fn getspecific() ?*ObjectArray {
        return @ptrCast(@alignCast(std.c.pthread_getspecific(current_thread_storage.key)));
    }

    /// Set casted thread specific value.
    fn setspecific(new: ?*ObjectArray) void {
        if (std.c.pthread_setspecific(current_thread_storage.key, @ptrCast(new)) != 0) {
            abort();
        }
    }

    /// Initialize pthread_key_t.
    fn init() void {
        if (@atomicLoad(bool, &init_done, .monotonic)) return;
        _ = std.c.pthread_mutex_lock(&init_mutex);
        if (std.c.pthread_key_create(&current_thread_storage.key, current_thread_storage.deinit) != .SUCCESS) {
            abort();
        }
        @atomicStore(bool, &init_done, true, .release);
        _ = std.c.pthread_mutex_unlock(&init_mutex);
    }

    /// Invoked by pthread specific destructor. the passed argument is the ObjectArray pointer.
    fn deinit(arrayPtr: *anyopaque) callconv(.c) void {
        var array: *ObjectArray = @ptrCast(@alignCast(arrayPtr));
        array.deinit();
    }
}