/* * Simple semaphore implementation, P() and V(). * * Copyright (C) 2011-2014 Simon Ruderich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sem.h" #include #include struct SEM { pthread_mutex_t mutex; pthread_cond_t condition; int value; }; SEM *sem_init(int init_value) { SEM *sem = malloc(sizeof(*sem)); if (sem == NULL) { return NULL; } if (pthread_mutex_init(&sem->mutex, NULL) != 0) { free(sem); return NULL; } if (pthread_cond_init(&sem->condition, NULL) != 0) { pthread_mutex_destroy(&sem->mutex); free(sem); return NULL; } sem->value = init_value; return sem; } int sem_del(SEM *sem) { if (sem == NULL) { return 0; } if (pthread_mutex_destroy(&sem->mutex) != 0) { free(sem); return -1; } if (pthread_cond_destroy(&sem->condition) != 0) { free(sem); return -1; } free(sem); return 0; } void P(SEM *sem) { pthread_mutex_lock(&sem->mutex); while (sem->value <= 0) { pthread_cond_wait(&sem->condition, &sem->mutex); } sem->value--; pthread_mutex_unlock(&sem->mutex); } void V(SEM *sem) { pthread_mutex_lock(&sem->mutex); sem->value++; pthread_cond_broadcast(&sem->condition); pthread_mutex_unlock(&sem->mutex); }