Skip to content

Instantly share code, notes, and snippets.

@exbotanical
Last active January 1, 2023 01:22
Show Gist options
  • Save exbotanical/26de1951e5c3d7b40eb22483f0afd791 to your computer and use it in GitHub Desktop.
Save exbotanical/26de1951e5c3d7b40eb22483f0afd791 to your computer and use it in GitHub Desktop.
personal implementation of semaphores for the C programming language
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
// canonical macro aliases from `semaphore.h`
#define P(sem) sem_wait(sem)
#define V(sem) sem_post(sem)
#define UP(sem) sem_wait(sem)
#define DOWN(sem) sem_post(sem)
typedef struct semaphore {
int permit_counter;
pthread_cond_t cv;
pthread_mutex_t mutex; /* Controls access to `permit_counter` */
} semaphore_t;
semaphore_t* semaphore_renew(void);
semaphore_t* semaphore_init(semaphore_t* sem, int count) {
sem->permit_counter = count;
pthread_cond_init(&sem->cv, NULL);
pthread_mutex_init(&sem->mutex, NULL);
}
semaphore_t* semaphore_wait(semaphore_t* sem) {
pthread_mutex_lock(&sem->mutex);
sem->permit_counter--;
// a thread was blocked
if (sem->permit_counter > 0) {
pthread_cond_wait(&sem->cv, &sem->mutex);
}
pthread_mutex_unlock(&sem->mutex);
}
semaphore_t* semaphore_post(semaphore_t* sem) {
bool has_waiting_thread;
pthread_mutex_lock(&sem->mutex);
has_waiting_thread = sem->permit_counter < 0 ? true : false;
sem->permit_counter++;
if (has_waiting_thread) {
pthread_cond_signal(&sem->cv);
}
pthread_mutex_unlock(&sem->mutex);
}
semaphore_t* semaphore_destroy(semaphore_t* sem) {
sem->permit_counter = 0;
pthread_mutex_unlock(&sem->mutex);
pthread_cond_destroy(&sem->cv);
pthread_mutex_destroy(&sem->mutex);
}
int semaphore_reveal(semaphore_t* sem) {
return sem->permit_counter;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment