Cleanup base layer
This commit is contained in:
+12
-141
@@ -106,7 +106,7 @@ DN_API DN_JSONBuilder DN_JSONBuilder_Init(DN_Arena *arena, int spaces_per_indent
|
||||
|
||||
DN_API DN_Str8 DN_JSONBuilder_Build(DN_JSONBuilder const *builder, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8Builder_Build(&builder->string_builder, arena);
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&builder->string_builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -142,18 +142,18 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
int spaces = builder->indent_level * spaces_per_indent;
|
||||
|
||||
if (key.size)
|
||||
DN_Str8Builder_AppendF(&builder->string_builder,
|
||||
DN_Str8BuilderAppendF(&builder->string_builder,
|
||||
"%.*s%*c\"%.*s\": %.*s",
|
||||
prefix_size,
|
||||
prefix,
|
||||
spaces,
|
||||
' ',
|
||||
DN_STR_FMT(key),
|
||||
DN_STR_FMT(value));
|
||||
DN_Str8PrintFmt(key),
|
||||
DN_Str8PrintFmt(value));
|
||||
else if (spaces == 0)
|
||||
DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_STR_FMT(value));
|
||||
DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_Str8PrintFmt(value));
|
||||
else
|
||||
DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_STR_FMT(value));
|
||||
DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_Str8PrintFmt(value));
|
||||
|
||||
if (item == DN_JSONBuilderItem_OpenContainer)
|
||||
builder->indent_level++;
|
||||
@@ -164,7 +164,7 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(builder->string_builder.arena);
|
||||
DN_Str8 value = DN_Str8_FromFV(tmem.arena, value_fmt, args);
|
||||
DN_Str8 value = DN_Str8FromFmtVArena(tmem.arena, value_fmt, args);
|
||||
DN_JSONBuilder_KeyValue(builder, key, value);
|
||||
}
|
||||
|
||||
@@ -178,22 +178,22 @@ DN_API void DN_JSONBuilder_KeyValueF(DN_JSONBuilder *builder, DN_Str8 key, char
|
||||
|
||||
DN_API void DN_JSONBuilder_ObjectBeginNamed(DN_JSONBuilder *builder, DN_Str8 name)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_STR8("{"));
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("{"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ObjectEnd(DN_JSONBuilder *builder)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("}"));
|
||||
DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("}"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ArrayBeginNamed(DN_JSONBuilder *builder, DN_Str8 name)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_STR8("["));
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("["));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ArrayEnd(DN_JSONBuilder *builder)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("]"));
|
||||
DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("]"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_Str8Named(DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value)
|
||||
@@ -239,136 +239,7 @@ DN_API void DN_JSONBuilder_F64Named(DN_JSONBuilder *builder, DN_Str8 key, double
|
||||
|
||||
DN_API void DN_JSONBuilder_BoolNamed(DN_JSONBuilder *builder, DN_Str8 key, bool value)
|
||||
{
|
||||
DN_Str8 value_string = value ? DN_STR8("true") : DN_STR8("false");
|
||||
DN_Str8 value_string = value ? DN_Str8Lit("true") : DN_Str8Lit("false");
|
||||
DN_JSONBuilder_KeyValueF(builder, key, "%.*s", value_string.size, value_string.data);
|
||||
}
|
||||
#endif // !defined(DN_NO_JSON_BUILDER)
|
||||
|
||||
// NOTE: DN_JobQueue ///////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_JobQueueSPMC DN_OS_JobQueueSPMCInit()
|
||||
{
|
||||
DN_JobQueueSPMC result = {};
|
||||
result.thread_wait_for_job_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.wait_for_completion_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.complete_queue_write_semaphore = DN_OS_SemaphoreInit(DN_ArrayCountU(result.complete_queue));
|
||||
result.mutex = DN_OS_MutexInit();
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCCanAdd(DN_JobQueueSPMC const *queue, uint32_t count)
|
||||
{
|
||||
uint32_t read_index = queue->read_index;
|
||||
uint32_t write_index = queue->write_index;
|
||||
uint32_t size = write_index - read_index;
|
||||
bool result = (size + count) <= DN_ArrayCountU(queue->jobs);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCAddArray(DN_JobQueueSPMC *queue, DN_Job *jobs, uint32_t count)
|
||||
{
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
uint32_t read_index = queue->read_index;
|
||||
uint32_t write_index = queue->write_index;
|
||||
uint32_t size = write_index - read_index;
|
||||
|
||||
if ((size + count) > DN_ArrayCountU(queue->jobs))
|
||||
return false;
|
||||
|
||||
for (size_t offset = 0; offset < count; offset++) {
|
||||
uint32_t wrapped_write_index = (write_index + offset) & pot_mask;
|
||||
queue->jobs[wrapped_write_index] = jobs[offset];
|
||||
}
|
||||
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->write_index += count;
|
||||
DN_OS_SemaphoreIncrement(&queue->thread_wait_for_job_semaphore, count);
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCAdd(DN_JobQueueSPMC *queue, DN_Job job)
|
||||
{
|
||||
bool result = DN_OS_JobQueueSPMCAddArray(queue, &job, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API int32_t DN_OS_JobQueueSPMCThread(DN_OSThread *thread)
|
||||
{
|
||||
DN_JobQueueSPMC *queue = DN_CAST(DN_JobQueueSPMC *) thread->user_context;
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
static_assert(DN_ArrayCountU(queue->jobs) == DN_ArrayCountU(queue->complete_queue), "PoT mask is used to mask access to both arrays");
|
||||
|
||||
for (;;) {
|
||||
DN_OS_SemaphoreWait(&queue->thread_wait_for_job_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
if (queue->quit)
|
||||
break;
|
||||
|
||||
DN_Assert(queue->read_index != queue->write_index);
|
||||
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
uint32_t wrapped_read_index = queue->read_index & pot_mask;
|
||||
DN_Job job = queue->jobs[wrapped_read_index];
|
||||
queue->read_index += 1;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
job.elapsed_tsc -= DN_CPUGetTSC();
|
||||
job.func(thread, job.user_context);
|
||||
job.elapsed_tsc += DN_CPUGetTSC();
|
||||
|
||||
if (job.add_to_completion_queue) {
|
||||
DN_OS_SemaphoreWait(&queue->complete_queue_write_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->complete_queue[(queue->complete_write_index++ & pot_mask)] = job;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
DN_OS_SemaphoreIncrement(&queue->complete_queue_write_semaphore, 1);
|
||||
}
|
||||
|
||||
// NOTE: Update finish counter
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->finish_index += 1;
|
||||
|
||||
// NOTE: If all jobs are finished and we have another thread who is
|
||||
// blocked via `WaitForCompletion` for this job queue, we will go
|
||||
// release the semaphore to wake them all up.
|
||||
bool all_jobs_finished = queue->finish_index == queue->write_index;
|
||||
if (all_jobs_finished && queue->threads_waiting_for_completion) {
|
||||
DN_OS_SemaphoreIncrement(&queue->wait_for_completion_semaphore,
|
||||
queue->threads_waiting_for_completion);
|
||||
queue->threads_waiting_for_completion = 0;
|
||||
}
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
}
|
||||
|
||||
return queue->quit_exit_code;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_JobQueueSPMCWaitForCompletion(DN_JobQueueSPMC *queue)
|
||||
{
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
if (queue->finish_index == queue->write_index) {
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
return;
|
||||
}
|
||||
queue->threads_waiting_for_completion++;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
DN_OS_SemaphoreWait(&queue->wait_for_completion_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_OS_JobQueueSPMCGetFinishedJobs(DN_JobQueueSPMC *queue, DN_Job *jobs, DN_USize jobs_size)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
if (!queue || !jobs || jobs_size <= 0)
|
||||
return result;
|
||||
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
while (queue->complete_read_index < queue->complete_write_index && result < jobs_size)
|
||||
jobs[result++] = queue->complete_queue[(queue->complete_read_index++ & pot_mask)];
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user