//------------------------------------------------------------------------------ /** @file "Pthreads/C/Primer 7 - monitor/mps.h" @brief Definisanje struktura Semafor i Monitor. @author Miloš Gligorić @author Andrija Bosnjaković */ //------------------------------------------------------------------------------ #ifndef _mps_h_ #define _mps_h_ //------------------------------------------------------------------------------ #include //------------------------------------------------------------------------------ /** @brief Struktura za predstavljanje semafora */ typedef struct { /** @property val @brief Trenutna vrednost semafora. */ int val; /** @property mutex @brief Obezbedjivanje atomičnosti operacija nad semaforom */ pthread_mutex_t mutex; /** @property cond @brief Blokiranje na semaforu. */ pthread_cond_t cond; } pthread_sem_t; /** @brief Inicijalizacija semafora. @param sem Promenljiva koja se inicijalizuje. @param val Pocetna vrednost semafora. */ void pthread_sem_init(pthread_sem_t *sem, int val) { sem->val = val; pthread_mutex_init(&sem->mutex, NULL); pthread_cond_init(&sem->cond, NULL); } /** @brief Oslobadjanje semafora. @param sem Promenljiva koja se oslobadja. */ void pthread_sem_destroy(pthread_sem_t *sem) { pthread_mutex_destroy(&sem->mutex); pthread_cond_destroy(&sem->cond); } /** @brief Blokira proces ukoliko je vrednost == 0. @param sem Semafor nad kojim se poziva wait. Dekrementira vrednost semafora, pod uslovom da vrednost semafora zadovoljava uslov val > 0; pozivajući proces zatim nastavlja sa radom. Ako uslov val > 0 nije zadovoljen, pozivajući proces se blokira dok se taj uslov ne ispuni. */ void pthread_sem_wait(pthread_sem_t *sem) { pthread_mutex_lock(&sem->mutex); while (sem->val == 0) pthread_cond_wait(&sem->cond, &sem->mutex); sem->val--; pthread_mutex_unlock(&sem->mutex); } /** @brief Signaliziranje na semaforu. @param sem Semafor nad kojim se signalizira. Inkrementira vrednost semafora. Ukoliko ima blokiranih procesa vrši deblokiranje jednog od njih. */ void pthread_sem_signal(pthread_sem_t *sem) { pthread_mutex_lock(&sem->mutex); sem->val++; if (sem->val == 1) pthread_cond_signal(&sem->cond); pthread_mutex_unlock(&sem->mutex); } //------------------------------------------------------------------------------ /** @brief Struktura za predstavljanje monitora (signal and continue disciplina) */ typedef struct { /** @property data @brief Podaci monitora. */ void *data; /** @property mutex @brief Medjusobno isključenje operacija nad monitorom */ pthread_mutex_t mutex; /** @property cond @brief Uslovna promenljiva monitora */ pthread_cond_t cond; } pthread_monitor_t; /** @brief Inicijalizacija monitora. @param monitor Promenljiva koja se inicijalizuje. @param data Podaci monitora. */ void pthread_monitor_init(pthread_monitor_t *monitor, void *data) { monitor->data = data; pthread_mutex_init(&monitor->mutex, NULL); pthread_cond_init(&monitor->cond, NULL); } /** @brief Oslobadjanje monitora. @param monitor Promenljiva koja se oslobadja. */ void pthread_monitor_destroy(pthread_monitor_t *monitor) { pthread_mutex_destroy(&monitor->mutex); pthread_cond_destroy(&monitor->cond); } /** @brief Sinhroni poziv "metode" (funkcije) monitora. @param monitor Promenljiva nad kojom se izvršava metoda @param f Funkcija koja će biti pozvana sinhrono za navedeni monitor @param args Argumenti funkcije koja će biti izvršena Ekvivalentno synchronized u Javi. Funkcija f pozvaće se za monitor sa argumentima args. */ void pthread_monitor_sync(pthread_monitor_t *monitor, void (*f)(pthread_monitor_t*, void*, void*), void* args) { pthread_mutex_lock(&monitor->mutex); (*f)(monitor, args, monitor->data); pthread_mutex_unlock(&monitor->mutex); } /** @brief Asinhroni poziv "metode" (funkcije) monitora. @param monitor Promenljiva nad kojom se izvršava metoda @param f Funkcija koja će biti pozvana asinhrono za navedeni monitor @param args Argumenti funkcije koja će biti izvršena Ekvivalentno metodi monitora u Javi. Funkcija f pozvaće se za monitor sa argumentima args. */ void pthread_monitor_nonsync(pthread_monitor_t *monitor, void (*f)(pthread_monitor_t*, void*, void*), void* args) { (*f)(monitor, args, monitor->data); } /** @brief Bezuslovno blokira proces i stavlja ga u red čekanja @param monitor Monitor u čiji se red stavlja proces. Nakon sto je jedan proces pozvao ovu metodu, drugi procesi stekli su mogucnost za koriscenje ovog monitora. Ekvivaletno wait() u Javi. */ void pthread_monitor_wait(pthread_monitor_t *monitor) { pthread_cond_wait(&monitor->cond, &monitor->mutex); } /** @brief Šalje notifikaciju niti na wait(). @param monitor Notifikacija za ovaj monitor Šalje notifikaciju niti koja čeka da pristupi monitoru pomoću funkcije wait(). Ekvivalentno sa notify() u Javi. */ void pthread_monitor_signal(pthread_monitor_t *monitor) { pthread_cond_signal(&monitor->cond); } /** @brief Šalje notifikaciju svim nitima. @param monitor Notifikacija za ovaj monitor Šalje notifikaciju svim nitima koje čekaju da da pristupe monitoru pomoću operacije wait(). Ako ima više takvih niti, bira se jedna, a ostale opet čekaju. Ekvivalentno notifyAll() u Javi. */ void pthread_monitor_broadcast(pthread_monitor_t *monitor) { pthread_cond_broadcast(&monitor->cond); } //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------