#include #include #include #include #include #include #include #include #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); }