Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // @Note(tkap, 02/01/2024): Returns true if semaphore got signaled. False otherwise
- func b8 acquire_semaphore(s_thread_pool* thread_pool, DWORD timeout_ms)
- {
- DWORD result = WaitForSingleObjectEx(thread_pool->semaphore, timeout_ms, FALSE);
- return result == WAIT_OBJECT_0;
- }
- // @Note(tkap, 10/08/2023): Bug when "b" wraps around (u32 max)
- func s_maybe_do_work maybe_do_work(s_thread_pool* thread_pool)
- {
- s_maybe_do_work result = zero;
- u32 max_work = thread_pool->max_work;
- u32 current_work = thread_pool->current_work;
- if(thread_pool->work_completed < max_work) {
- result.is_there_work_left_to_do = true;
- if(current_work < max_work) {
- u32 foo = InterlockedCompareExchange((LONG volatile*)&thread_pool->current_work, current_work + 1, current_work);
- if(current_work == foo) {
- u32 index = foo % c_max_thread_queue_elements;
- s_work_data data = thread_pool->work[index];
- ((void_func)data.func_ptr)(data.arg);
- result.did_work = true;
- _WriteBarrier();
- _mm_sfence();
- InterlockedIncrement((LONG volatile*)&thread_pool->work_completed);
- }
- }
- }
- return result;
- }
- #ifdef m_platform
- DWORD WINAPI thread_proc(void* param)
- {
- s_thread_data thread_data = *(s_thread_data*)param;
- g_thread_id = thread_data.id;
- while(true) {
- acquire_semaphore(thread_data.thread_pool, INFINITE);
- while(true) {
- s_maybe_do_work data = maybe_do_work(thread_data.thread_pool);
- if(data.did_work) { break; }
- }
- }
- return 0;
- }
- func int get_thread_id()
- {
- return g_thread_id;
- }
- #else // m_platform
- func void add_work(s_thread_pool* thread_pool, void* func_ptr, void* arg)
- {
- int temp = thread_pool->max_work;
- temp %= c_max_thread_queue_elements;
- thread_pool->work[temp].func_ptr = func_ptr;
- thread_pool->work[temp].arg = arg;
- _WriteBarrier();
- _mm_sfence();
- InterlockedIncrement((LONG volatile*)&thread_pool->max_work);
- _WriteBarrier();
- _mm_sfence();
- BOOL result = ReleaseSemaphore(thread_pool->semaphore, 1, null);
- unreferenced(result);
- assert(result);
- }
- func void do_work_until_completed(s_thread_pool* thread_pool)
- {
- while(acquire_semaphore(thread_pool, 0)) {
- while(true) {
- s_maybe_do_work data = maybe_do_work(thread_pool);
- if(data.did_work) { break; }
- }
- }
- while(thread_pool->work_completed < thread_pool->max_work) {}
- reset_thread_arenas_thread_id();
- }
- #endif // m_platform
- // EXAMPLE USAGE
- // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv TOWER STATS START vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- {
- int start = towers->index_data.lowest_index;
- int count = get_how_many_entities_to_process_per_call(towers->index_data);
- s_generic_entity_thread_data* data = (s_generic_entity_thread_data*)la_get_zero(frame_arena, sizeof(s_generic_entity_thread_data) * g_num_threads_including_main);
- for(int thread_i = 0; thread_i < g_num_threads_including_main && count > 0; thread_i += 1) {
- data[thread_i].start = start;
- data[thread_i].count = count;
- data[thread_i].frame_arena = &g_thread_arenas[thread_i];
- add_work(thread_pool, set_tower_stats, &data[thread_i]);
- if(!advance_entity_start(&start, &count, towers->index_data.max_index_plus_one)) { break; }
- }
- do_work_until_completed(thread_pool);
- }
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TOWER STATS END ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement