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.
constemutls_control = externstruct {
// A emutls_control value is a global value across all
// threads. The threads shares the index of TLS variable. The data
// array (containing address of allocated variables) is thread
// specific and stored using pthread_setspecific().
// size of the object in bytes
size: gcc_word,
// alignment of the object in bytesalignment: gcc_word,
object: externunion {
// data[index-1] is the object address / 0 = uninitindex: usize,
// object address, when in single thread env (not used)address: *anyopaque,
},
// null or non-zero initial value for the objectdefault_value: ?*constanyopaque,
// global Mutex used to serialize control.index initialization.varmutex: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER;
// global counter for keeping track of requested indexes.
// access should be done with mutex held.
varnext_index: usize = 1;
/// Simple wrapper for global lock.fnlock() void {
if (std.c.pthread_mutex_lock(&emutls_control.mutex) != .SUCCESS) {
abort();
}
}
/// Simple wrapper for global unlock.fnunlock() void {
if (std.c.pthread_mutex_unlock(&emutls_control.mutex) != .SUCCESS) {
abort();
}
}
/// Helper to retrieve nad initialize global unique index per emutls variable.pubfngetIndex(self: *emutls_control) usize {
// Two threads could race against the same emutls_control.
// Use atomic for reading coherent value lockless.
constindex_lockless = @atomicLoad(usize, &self.object.index, .acquire);
if (index_lockless != 0) {
// index is already initialized, return it.returnindex_lockless;
}
// index is uninitialized: take global lock to avoid possible race.emutls_control.lock();
deferemutls_control.unlock();
constindex_locked = self.object.index;
if (index_locked != 0) {
// we lost a race, but index is already initialized: nothing particular to do.returnindex_locked;
}
// Store a new index atomically (for having coherent index_lockless reading).@atomicStore(usize, &self.object.index, emutls_control.next_index, .release);
// Increment the next available indexemutls_control.next_index += 1;
returnself.object.index;
}
/// Simple helper for testing purpose.pubfninit(comptimeT: type, default_value: ?*constT) emutls_control {
returnemutls_control{
.size = @sizeOf(T),
.alignment = @alignOf(T),
.object = .{ .index = 0 },
.default_value = @ptrCast(default_value),
};
}
/// Get the pointer on allocated storage for emutls variable.pubfngetPointer(self: *emutls_control) *anyopaque {
// ensure current_thread_storage initialization is donecurrent_thread_storage.init();
constindex = self.getIndex();
vararray = current_thread_storage.getArray(index);
returnarray.getPointer(index - 1, self);
}
/// Testing helper for retrieving typed pointer.pubfnget_typed_pointer(self: *emutls_control, comptimeT: type) *T {
assert(self.size == @sizeOf(T));
assert(self.alignment == @alignOf(T));
return@ptrCast(@alignCast(self.getPointer()));
}
}