medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e02b61f6a26bb3c5e2717f81e6249453386abd7d
parent b4d3bef024b2a4a3d56ddf532c6b324942d2d5cc
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sun Aug 16 11:22:00 +0200

Add platform independant semaphore interface

Diffstat:
Makefile | 2+-
darwin_semaphore.cc | 15+++++++++++++++
linux_semaphore.cc | 19+++++++++++++++++++
platform_semaphore.h | 25+++++++++++++++++++++++++
work_queue.cc | 24+++++-------------------
work_queue.h | 6++----
6 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ all: medfall hm.so pp OBJS = main.o gl.o BSPOBJS = bsp.o bsp_renderer.o gl.o -HMOBJS = hm.o heightmap.o terrain_manager.o work_queue.o stb_image.o stb_perlin.o +HMOBJS = hm.o heightmap.o terrain_manager.o work_queue.o stb_image.o stb_perlin.o darwin_semaphore.o PPOBJS = pp.o stb_image.o stb_image_write.o WARNINGS = -Wall -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-write-strings diff --git a/darwin_semaphore.cc b/darwin_semaphore.cc @@ -0,0 +1,15 @@ +#include <dispatch/dispatch.h> + +#include "platform_semaphore.h" + +void semaphore_init( Semaphore * const sem ) { + sem->sem = dispatch_semaphore_create( 0 ); +} + +void semaphore_signal( Semaphore * const sem ) { + dispatch_semaphore_signal( sem->sem ); +} + +void semaphore_wait( Semaphore * const sem ) { + dispatch_semaphore_wait( sem->sem, DISPATCH_TIME_FOREVER ); +} diff --git a/linux_semaphore.cc b/linux_semaphore.cc @@ -0,0 +1,19 @@ +#include <err.h> +#include <semaphore.h> + +#include "platform_semaphore.h" + +void semaphore_init( Semaphore * const sem ) { + const int ok = sem_init( &sem->sem, 0, 0 ); + if( ok == -1 ) { + err( 1, "sem_init failed" ); + } +} + +void semaphore_signal( Semaphore * const sem ) { + sem_post( sem->sem ); +} + +void semaphore_wait( Semaphore * const sem ) { + sem_wait( sem->sem ); +} diff --git a/platform_semaphore.h b/platform_semaphore.h @@ -0,0 +1,25 @@ +// TODO: platform_concurrency.h? +#ifndef _PLATFORM_SEMAPHORE_H_ +#define _PLATFORM_SEMAPHORE_H_ + +#ifdef __APPLE__ +#include <dispatch/dispatch.h> + +struct Semaphore { + dispatch_semaphore_t sem; +}; +#endif + +#ifdef __linux__ // this is wrong +#include <semaphore.h> + +struct Semaphore { + sem_t * sem; +}; +#endif + +void semaphore_init( Semaphore * const sem ); +void semaphore_signal( Semaphore * const sem ); +void semaphore_wait( Semaphore * const sem ); + +#endif // _PLATFORM_SEMAPHORE_H_ diff --git a/work_queue.cc b/work_queue.cc @@ -1,21 +1,15 @@ #include <err.h> #include <pthread.h> -// #include <semaphore.h> -#include <dispatch/dispatch.h> #include "intrinsics.h" #include "work_queue.h" +#include "platform_barrier.h" +#include "platform_semaphore.h" -#define read_barrier() asm volatile ( "" ::: "memory" ) -#define write_barrier() asm volatile ( "" ::: "memory" ) - -#include <stdio.h> static bool workqueue_step( WorkQueue * const queue ) { const u16 current_head = queue->head; const u16 new_head = ( current_head + 1 ) % array_count( queue->jobs ); - // read_barrier(); TODO: - if( current_head != queue->tail ) { if( __sync_bool_compare_and_swap( &queue->head, current_head, new_head ) ) { const Job & job = queue->jobs[ current_head ]; @@ -36,11 +30,8 @@ static void * workqueue_worker( void * data ) { for( ;; ) { if( !workqueue_step( queue ) ) { - // sem_wait( queue->sem ); - dispatch_semaphore_wait( queue->sem, DISPATCH_TIME_FOREVER ); + semaphore_wait( &queue->sem ); } - - // pthread_testcancel(); } return nullptr; @@ -48,11 +39,7 @@ static void * workqueue_worker( void * data ) { void workqueue_init( WorkQueue * const queue, const u32 num_threads ) { *queue = { }; - - // if( sem_init( queue->sem, 0, 0 ) == -1 ) { - // err( 1, "can't create semaphore" ); - // } - queue->sem = dispatch_semaphore_create( 0 ); + semaphore_init( &queue->sem ); for( u32 i = 0; i < num_threads; i++ ) { pthread_t thread; @@ -71,8 +58,7 @@ void workqueue_enqueue( WorkQueue * const queue, WorkQueueCallback * const callb write_barrier(); queue->tail = ( queue->tail + 1 ) % array_count( queue->jobs ); - // sem_post( queue->sem ); - dispatch_semaphore_signal( queue->sem ); + semaphore_signal( &queue->sem ); } void workqueue_exhaust( WorkQueue * const queue ) { diff --git a/work_queue.h b/work_queue.h @@ -1,9 +1,8 @@ #ifndef _WORK_QUEUE_H_ #define _WORK_QUEUE_H_ -// #include <semaphore.h> -#include <dispatch/dispatch.h> #include "intrinsics.h" +#include "platform_semaphore.h" #define WORK_QUEUE_CALLBACK( name ) void name( void * const data ) typedef WORK_QUEUE_CALLBACK( WorkQueueCallback ); @@ -16,8 +15,7 @@ struct Job { struct WorkQueue { Job jobs[ 256 ]; - // sem_t * sem; - dispatch_semaphore_t sem; + Semaphore sem; // using head/length means we need to an atomic pair which is a pain volatile u16 head;