@@ -0,0 +1,84 @@
//
// Created by Yogesh Swami on 2/24/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
//
// clang -Wall -Wextra -Wall -o mach_semaphore mach_semaphore.c
//
// using mach semaphore for mutually signalling between two threads.
// Since mach semaphores are essentially mach_ports, once can
// send receive rights to the semaphore to another process
// run exactly the same operations done using threads in this example.
//
#include <stdio.h>
#include <string.h>
#include <mach/mach_init.h>
#include <mach/task.h>
#include <mach/semaphore.h>
#include <mach/sync_policy.h>
#include <mach/mach_error.h>
#include <mach/clock_types.h>
#include <pthread.h>
mach_timespec_t semaWait = { .tv_sec = 1 ,
.tv_nsec = (clock_res_t )0
};
semaphore_t sema_one ;
semaphore_t sema_two ;
void * child_entry_point (void * sema ){
semaphore_t s_one = * ((semaphore_t * )sema );
semaphore_t s_two = (s_one == sema_one )? sema_two : sema_one ;
char * name = (s_one == sema_one )? "main " :"child" ;
int counter = 5 ;
kern_return_t result ;
fprintf (stdout , "---------- %s entry point ---------\n" , name );
// Let the child begin first, this way we don't need to do
// pthread_detach()
if (s_one == sema_one )
semaphore_wait (s_one );
do {
fprintf (stdout , "%s > counter = %d. Will sleep for one second.\n" , name , counter );
/* let semaphore one know we are waiting. */
result = semaphore_timedwait_signal (s_one , s_two , semaWait );
} while ((counter -- > 0 ) && ((result == KERN_OPERATION_TIMED_OUT ) || (result == KERN_SUCCESS )));
if (counter > 0 ){
fprintf (stderr , "%s > Error with semaphore: <%d %s>\n" , name , result , mach_error_string (result ));
}else {
fprintf (stdout , "%s > Exiting ...\n" , name );
}
return NULL ;
}
int main (__unused int argc , __unused char * argv []) {
char * main_t = "main" , * child_t = "child" ;
pthread_t tid ;
kern_return_t ret ;
mach_port_t self = mach_task_self ();
int result ;
ret = semaphore_create (self , & sema_one , SYNC_POLICY_FIFO , 0 );
if (ret != KERN_SUCCESS ){
fprintf (stderr , "semaphore create failed. Error <%d, %s>" , ret , mach_error_string (ret ));
return ret ;
}
ret = semaphore_create (self , & sema_two , SYNC_POLICY_FIFO , 0 );
if (ret != KERN_SUCCESS ){
fprintf (stderr , "semaphore create failed. Error <%d, %s>" , ret , mach_error_string (ret ));
return ret ;
}
result = pthread_create (& tid , NULL , child_entry_point , (void * )& sema_two );
child_entry_point ((void * )& sema_one );
return ret ;
}