#include <pthread.h>
#include <semaphore.h>
#include "os_base.h"
sem_t p1_p2;
sem_t p2_p3p5;
sem_t p3_p4;
sem_t p4p5_p6;
void* P1(void *args)
{
OS_WORK();
OS_SEM_UP(p1_p2);
}
void* P2(void *args)
{
OS_SEM_DOWN(p1_p2);
OS_WORK();
OS_SEM_UP(p2_p3p5);
OS_SEM_UP(p2_p3p5);
}
void* P3(void *args)
{
OS_SEM_DOWN(p2_p3p5);
OS_CS_WORK();
OS_SEM_UP(p3_p4);
}
void* P4(void *args)
{
OS_SEM_DOWN(p3_p4);
OS_CS_WORK();
OS_SEM_UP(p4p5_p6);
}
void* P5(void *args)
{
OS_SEM_DOWN(p2_p3p5);
OS_CS_WORK();
OS_SEM_UP(p4p5_p6);
}
void* P6(void *args)
{
OS_SEM_DOWN(p4p5_p6);
OS_SEM_DOWN(p4p5_p6);
OS_WORK();
}
int main (int argc, char * argv[])
{
pthread_t p1, p2, p3, p4, p5, p6;
os_base_init(TRUE, TRUE);
OS_SEM_INIT(p1_p2, 0);
OS_SEM_INIT(p2_p3p5, 0);
OS_SEM_INIT(p3_p4, 0);
OS_SEM_INIT(p4p5_p6, 0);
pthread_create(&p6, NULL, P6, NULL);
pthread_create(&p5, NULL, P5, NULL);
pthread_create(&p4, NULL, P4, NULL);
pthread_create(&p3, NULL, P3, NULL);
pthread_create(&p2, NULL, P2, NULL);
pthread_create(&p1, NULL, P1, NULL);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(p3, NULL);
pthread_join(p4, NULL);
pthread_join(p5, NULL);
pthread_join(p6, NULL);
OS_SEM_DESTROY(p1_p2);
OS_SEM_DESTROY(p2_p3p5);
OS_SEM_DESTROY(p3_p4);
OS_SEM_DESTROY(p4p5_p6);
os_base_destroy();
return 0;
}
os_base.h
#include <stdbool.h>
#define FALSE 0
#define TRUE 1
//wrapers
#define OS_SEM_INIT(pSem, cnt) \
sem_init(&pSem, FALSE, cnt)
#define OS_SEM_DOWN(pSem) \
os_sem_down(&pSem, #pSem, __FUNCTION__)
#define OS_SEM_UP(pSem) \
os_sem_up(&pSem, #pSem, __FUNCTION__)
#define OS_SEM_DESTROY(pSem) \
sem_destroy(&pSem)
#define OS_WORK() \
os_work(__FUNCTION__)
#define OS_CS_WORK() \
os_cs_work(__FUNCTION__)
/*
* init internal printing semaphore and watchDog thread
*/
void os_base_init(bool enableWatchDog, bool asThread);
/*
* destroy watchDog thread and printing semaphore
*/
void os_base_destroy();
/*
* wrapers around posix sem_wait() sem_post() functions.
* this prints info which semaphore was touched and who touched it.
*/
void os_sem_down(sem_t * pSem, const char * semName, const char * threadName);
void os_sem_up(sem_t * pSem, const char * semName, const char * threadName);
/*
* functions simulating some work
* function execution can take at least one second
* os_cs_work checks whether more threads enetered the function
*/
void os_work(const char * threadName);
void os_cs_work(const char * threadName);
xgalchyn@xgalchyn:/public/priklady/procesy$