Skip to content

Commit

Permalink
Merge pull request #12 from uyjulian/named_semaphores
Browse files Browse the repository at this point in the history
Replace macOS Grand Central Dispatch support with named semaphores
  • Loading branch information
AKuHAK authored Feb 5, 2020
2 parents e28d1e8 + 4d05cbd commit 8cf0a0c
Showing 1 changed file with 48 additions and 35 deletions.
83 changes: 48 additions & 35 deletions thd_iin.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#if defined (__MACH__)
#define USE_NAMED_SEMAPHORES
#endif

#if defined (_BUILD_WIN32)
# include <windows.h>
# include "sema.h" /* POSIX semaphores for win32 */
#else
# include <pthread.h>
#if defined (__MACH__)
# include <dispatch/dispatch.h>
#else
# include <semaphore.h>
#endif
#if defined (USE_NAMED_SEMAPHORES)
#include <unistd.h>
#include <limits.h>
#endif
#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -67,8 +71,8 @@ typedef struct threaded_decorator_type
job_t job;

/* both are exclusive => at any moment only one is acquirable */
#if defined (__MACH__)
dispatch_semaphore_t worker_lock, master_lock;
#ifdef USE_NAMED_SEMAPHORES
sem_t *worker_lock, *master_lock;
#else
sem_t worker_lock, master_lock;
#endif
Expand All @@ -93,8 +97,8 @@ thd_loop (void *p)

do
{
#if defined(__MACH__)
int result = dispatch_semaphore_wait (thd->worker_lock, DISPATCH_TIME_FOREVER);
#if defined(USE_NAMED_SEMAPHORES)
int result = sem_wait (thd->worker_lock);
#else
int result = sem_wait (&thd->worker_lock);
#endif
Expand All @@ -116,8 +120,8 @@ thd_loop (void *p)
dest->num_sectors = job->num_sectors;

/* unlock master */
#if defined(__MACH__)
dispatch_semaphore_signal (thd->master_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->master_lock);
#else
sem_post (&thd->master_lock);
#endif
Expand All @@ -126,8 +130,8 @@ thd_loop (void *p)
while (!thd->done);

/* notify master */
#if defined(__MACH__)
dispatch_semaphore_signal (thd->master_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->master_lock);
#else
sem_post (&thd->master_lock);
#endif
Expand All @@ -148,8 +152,8 @@ thd_read (iin_t *iin,

do
{
#if defined(__MACH__)
result = dispatch_semaphore_wait (thd->master_lock, DISPATCH_TIME_FOREVER);
#if defined(USE_NAMED_SEMAPHORES)
result = sem_wait (thd->master_lock);
#else
result = sem_wait (&thd->master_lock);
#endif
Expand All @@ -169,8 +173,8 @@ thd_read (iin_t *iin,
thd->job.start_sector = start_sector;
thd->job.num_sectors = num_sectors;
thd->job.dest = thd->buf + (thd->active_buf % 2);
#if defined(__MACH__)
dispatch_semaphore_signal (thd->worker_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->worker_lock);
#else
sem_post (&thd->worker_lock);
#endif
Expand All @@ -186,17 +190,17 @@ thd_read (iin_t *iin,
thd->job.start_sector = start_sector + num_sectors;
thd->job.num_sectors = IIN_NUM_SECTORS;
thd->job.dest = thd->buf + (++thd->active_buf % 2);
#if defined(__MACH__)
dispatch_semaphore_signal (thd->worker_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->worker_lock);
#else
sem_post (&thd->worker_lock);
#endif
}
else
/* since there is no pre-fetch scheduled,
unlock master or the next read call would block forever */
#if defined(__MACH__)
dispatch_semaphore_signal (thd->master_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->master_lock);
#else
sem_post (&thd->master_lock);
#endif
Expand Down Expand Up @@ -226,24 +230,24 @@ thd_close (iin_t *iin)
int result;

/* wait for worker to finish... */
#if defined(__MACH__)
dispatch_semaphore_wait (thd->master_lock, DISPATCH_TIME_FOREVER);
#if defined(USE_NAMED_SEMAPHORES)
sem_wait (thd->master_lock);
#else
sem_wait (&thd->master_lock);
#endif
thd->done = 1;
#if defined(__MACH__)
dispatch_semaphore_signal (thd->worker_lock);
dispatch_semaphore_wait (thd->master_lock, DISPATCH_TIME_FOREVER);
#if defined(USE_NAMED_SEMAPHORES)
sem_post (thd->worker_lock);
sem_wait (thd->master_lock);
#else
sem_post (&thd->worker_lock);
sem_wait (&thd->master_lock);
#endif

/* clean-up */
#if defined(__MACH__)
dispatch_release (thd->worker_lock);
dispatch_release (thd->master_lock);
#if defined(USE_NAMED_SEMAPHORES)
sem_close (thd->worker_lock);
sem_close (thd->master_lock);
#else
sem_destroy (&thd->worker_lock);
sem_destroy (&thd->master_lock);
Expand Down Expand Up @@ -281,6 +285,9 @@ thd_create (iin_t *worker)
{
u_int32_t total_sectors, sector_size;
threaded_decorator_t *thd;
#if defined(USE_NAMED_SEMAPHORES)
char sema_name_buf[NAME_MAX - 4];
#endif

if (worker->stat (worker, &sector_size, &total_sectors) != RET_OK)
return (NULL);
Expand All @@ -303,20 +310,26 @@ thd_create (iin_t *worker)
thd->done = 0;

/* master is unlocked, worker is locked; would run on 1st need */
#if defined(__MACH__)
thd->worker_lock = dispatch_semaphore_create(0);
#if defined(USE_NAMED_SEMAPHORES)
snprintf (sema_name_buf, sizeof(sema_name_buf), "hdl_dump%x_%i", getpid (), 0);
thd->worker_lock = sem_open ((const char *)sema_name_buf, O_CREAT);
if (thd->worker_lock != NULL)
#else
if (sem_init (&thd->worker_lock, 0, 0) == 0)
#endif
{
#if defined(__MACH__)
thd->master_lock = dispatch_semaphore_create(1);
#if defined(USE_NAMED_SEMAPHORES)
sem_unlink ((const char *)sema_name_buf);
snprintf (sema_name_buf, sizeof(sema_name_buf), "hdl_dump%x_%i", getpid (), 1);
thd->master_lock = sem_open ((const char *)sema_name_buf, O_CREAT);
if (thd->master_lock != NULL)
#else
if (sem_init (&thd->master_lock, 0, 1) == 0)
#endif
{
#if defined(USE_NAMED_SEMAPHORES)
sem_unlink ((const char *)sema_name_buf);
#endif
#if defined (_BUILD_WIN32)
DWORD thread_id = 0;
HANDLE h = CreateThread (NULL, 0, &thd_loop, thd, 0, &thread_id);
Expand All @@ -329,14 +342,14 @@ thd_create (iin_t *worker)
return ((iin_t*) thd); /* unix: success */
#endif

#if defined(__MACH__)
dispatch_release (thd->master_lock);
#if defined(USE_NAMED_SEMAPHORES)
(void) sem_close (thd->master_lock);
#else
(void) sem_destroy (&thd->master_lock);
#endif
}
#if defined(__MACH__)
dispatch_release (thd->worker_lock);
#if defined(USE_NAMED_SEMAPHORES)
(void) sem_close (thd->worker_lock);
#else
(void) sem_destroy (&thd->worker_lock);
#endif
Expand Down

0 comments on commit 8cf0a0c

Please sign in to comment.