95 lines
1.6 KiB
C
95 lines
1.6 KiB
C
#include <assert.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "pingpong.h"
|
|
|
|
typedef struct pparg {
|
|
sem_t *sem_ping; // Tell ping to wake up
|
|
sem_t *sem_pong; // Tell pong to wake up
|
|
size_t *shared;
|
|
} ppargs_t;
|
|
|
|
void *
|
|
pong (void * _args)
|
|
{
|
|
ppargs_t *args = (ppargs_t *) _args;
|
|
|
|
while (1)
|
|
{
|
|
sem_wait (args->sem_pong);
|
|
|
|
printf ("PONG!\n");
|
|
|
|
if (*(args->shared) == 0)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
sem_post (args->sem_ping);
|
|
}
|
|
}
|
|
|
|
printf ("PONG: Game over\n");
|
|
pthread_exit (NULL);
|
|
}
|
|
|
|
void
|
|
ping (size_t *count)
|
|
{
|
|
pthread_t pong_thread;
|
|
sem_t sem_ping;
|
|
sem_t sem_pong;
|
|
|
|
if (sem_init (&sem_ping, 0, 1) != 0)
|
|
{
|
|
perror ("sem_init sem_ping");
|
|
return;
|
|
}
|
|
if (sem_init (&sem_pong, 0, 0) != 0)
|
|
{
|
|
perror ("sem_init sem_pong");
|
|
sem_destroy (&sem_ping);
|
|
return;
|
|
}
|
|
|
|
ppargs_t args;
|
|
args.sem_ping = &sem_ping;
|
|
args.sem_pong = &sem_pong;
|
|
args.shared = count;
|
|
|
|
if (pthread_create (&pong_thread, NULL, pong, (void *)&args) != 0)
|
|
{
|
|
perror ("pthread_create");
|
|
sem_destroy (&sem_ping);
|
|
sem_destroy (&sem_pong);
|
|
return;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
sem_wait (&sem_ping);
|
|
|
|
(*count)--;
|
|
printf ("PING!\n");
|
|
|
|
sem_post (&sem_pong);
|
|
|
|
if (*count == 0)
|
|
break;
|
|
}
|
|
|
|
// After PONG prints game over and exits, do the same for PING
|
|
pthread_join (pong_thread, NULL);
|
|
printf ("PING: Game over\n");
|
|
|
|
sem_destroy (&sem_ping);
|
|
sem_destroy (&sem_pong);
|
|
}
|