mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 07:08:48 +00:00
thread_pool.cpp: fix with 1 thread; gb.h: remove buggy /proc/cpuinfo code
This commit is contained in:
+3
-63
@@ -3785,74 +3785,14 @@ isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(GB_SYSTEM_LINUX)
|
#elif defined(GB_SYSTEM_LINUX)
|
||||||
// IMPORTANT TODO(bill): This gbAffinity stuff for linux needs be improved a lot!
|
|
||||||
// NOTE(zangent): I have to read /proc/cpuinfo to get the number of threads per core.
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void gb_affinity_init(gbAffinity *a) {
|
void gb_affinity_init(gbAffinity *a) {
|
||||||
b32 accurate = true;
|
|
||||||
isize threads = 0;
|
|
||||||
|
|
||||||
a->thread_count = 1;
|
|
||||||
a->core_count = sysconf(_SC_NPROCESSORS_ONLN);
|
a->core_count = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
a->threads_per_core = 1;
|
a->threads_per_core = 1;
|
||||||
|
a->is_accurate = a->core_count > 0;
|
||||||
|
a->core_count = a->is_accurate ? a->core_count : 1;
|
||||||
if(a->core_count <= 0) {
|
a->thread_count = a->core_count;
|
||||||
a->core_count = 1;
|
|
||||||
accurate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parsing /proc/cpuinfo to get the number of threads per core.
|
|
||||||
// NOTE(zangent): This calls the CPU's threads "cores", although the wording
|
|
||||||
// is kind of weird. This should be right, though.
|
|
||||||
|
|
||||||
FILE* cpu_info = fopen("/proc/cpuinfo", "r");
|
|
||||||
|
|
||||||
if (cpu_info != NULL) {
|
|
||||||
for (;;) {
|
|
||||||
// The 'temporary char'. Everything goes into this char,
|
|
||||||
// so that we can check against EOF at the end of this loop.
|
|
||||||
int c;
|
|
||||||
|
|
||||||
#define AF__CHECK(letter) ((c = getc(cpu_info)) == letter)
|
|
||||||
if (AF__CHECK('c') && AF__CHECK('p') && AF__CHECK('u') && AF__CHECK(' ') &&
|
|
||||||
AF__CHECK('c') && AF__CHECK('o') && AF__CHECK('r') && AF__CHECK('e') && AF__CHECK('s')) {
|
|
||||||
// We're on a CPU info line.
|
|
||||||
while (!AF__CHECK(EOF)) {
|
|
||||||
if (c == '\n') {
|
|
||||||
break;
|
|
||||||
} else if (c < '0' || '9' > c) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
threads = threads * 10 + (c - '0');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
while (!AF__CHECK('\n')) {
|
|
||||||
if (c==EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c == EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#undef AF__CHECK
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(cpu_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (threads == 0) {
|
|
||||||
threads = 1;
|
|
||||||
accurate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->threads_per_core = threads;
|
|
||||||
a->thread_count = a->threads_per_core * a->core_count;
|
|
||||||
a->is_accurate = accurate;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gb_affinity_destroy(gbAffinity *a) {
|
void gb_affinity_destroy(gbAffinity *a) {
|
||||||
|
|||||||
+16
-22
@@ -11,30 +11,27 @@ struct WorkerTask {
|
|||||||
|
|
||||||
struct ThreadPool {
|
struct ThreadPool {
|
||||||
std::atomic<isize> outstanding_task_count;
|
std::atomic<isize> outstanding_task_count;
|
||||||
WorkerTask *next_task;
|
WorkerTask *volatile next_task;
|
||||||
BlockingMutex task_list_mutex;
|
BlockingMutex task_list_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_prefix = nullptr);
|
|
||||||
void thread_pool_destroy(ThreadPool *pool);
|
|
||||||
void thread_pool_wait(ThreadPool *pool);
|
|
||||||
void thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data);
|
|
||||||
void worker_thread_internal();
|
|
||||||
|
|
||||||
void thread_pool_thread_entry(ThreadPool *pool) {
|
void thread_pool_thread_entry(ThreadPool *pool) {
|
||||||
while (pool->outstanding_task_count) {
|
while (pool->outstanding_task_count) {
|
||||||
mutex_lock(&pool->task_list_mutex);
|
if (!pool->next_task) {
|
||||||
|
yield(); // No need to grab the mutex.
|
||||||
if (pool->next_task) {
|
|
||||||
WorkerTask *task = pool->next_task;
|
|
||||||
pool->next_task = task->next_task;
|
|
||||||
mutex_unlock(&pool->task_list_mutex);
|
|
||||||
task->do_work(task->data);
|
|
||||||
pool->outstanding_task_count.fetch_sub(1);
|
|
||||||
gb_free(heap_allocator(), task);
|
|
||||||
} else {
|
} else {
|
||||||
mutex_unlock(&pool->task_list_mutex);
|
mutex_lock(&pool->task_list_mutex);
|
||||||
yield();
|
|
||||||
|
if (pool->next_task) {
|
||||||
|
WorkerTask *task = pool->next_task;
|
||||||
|
pool->next_task = task->next_task;
|
||||||
|
mutex_unlock(&pool->task_list_mutex);
|
||||||
|
task->do_work(task->data);
|
||||||
|
pool->outstanding_task_count.fetch_sub(1);
|
||||||
|
gb_free(heap_allocator(), task);
|
||||||
|
} else {
|
||||||
|
mutex_unlock(&pool->task_list_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,10 +74,7 @@ void thread_pool_destroy(ThreadPool *pool) {
|
|||||||
|
|
||||||
void thread_pool_wait(ThreadPool *pool) {
|
void thread_pool_wait(ThreadPool *pool) {
|
||||||
pool->outstanding_task_count.fetch_sub(1);
|
pool->outstanding_task_count.fetch_sub(1);
|
||||||
|
thread_pool_thread_entry(pool);
|
||||||
while (pool->outstanding_task_count.load() != 0) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
|
void thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
|
||||||
|
|||||||
Reference in New Issue
Block a user