Created
October 6, 2012 00:52
-
-
Save kazupon/3843288 to your computer and use it in GitHub Desktop.
Using mach_semaphore on Mac OS X to mutually signaling between two threads. This could be extended to work with different processes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment