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.
constcurrent_thread_storage = struct {
varkey: std.c.pthread_key_t = undefined;
varinit_mutex: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER;
varinit_done: bool = false;
/// Return a per thread ObjectArray with at least the expected index.pubfngetArray(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.
returnarray.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).
constsize = @max(16, index);
// create a new array and store it.constarray: *ObjectArray = ObjectArray.init(size);
current_thread_storage.setspecific(array);
returnarray;
}
/// Return casted thread specific value.fngetspecific() ?*ObjectArray {
return@ptrCast(@alignCast(std.c.pthread_getspecific(current_thread_storage.key)));
}
/// Set casted thread specific value.fnsetspecific(new: ?*ObjectArray) void {
if (std.c.pthread_setspecific(current_thread_storage.key, @ptrCast(new)) != 0) {
abort();
}
}
/// Initialize pthread_key_t.fninit() void {
if (@atomicLoad(bool, &init_done, .monotonic)) return;
_ = std.c.pthread_mutex_lock(&init_mutex);
if (std.c.pthread_key_create(¤t_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.fndeinit(arrayPtr: *anyopaque) callconv(.c) void {
vararray: *ObjectArray = @ptrCast(@alignCast(arrayPtr));
array.deinit();
}
}