online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <stdio.h> #include <stdbool.h> #include <unistd.h> #include <stdlib.h> #include <assert.h> #include "synch.h" #define NUM_PIRATES 5 enum pirate_state { ARGUING, HUNGRY, EATING }; struct lock *table_lock; struct cv *pirate_jab[NUM_PIRATES]; volatile enum pirate_state state[NUM_PIRATES]; volatile bool royal_navy = false; pthread_t pirate_thread[NUM_PIRATES]; void rand_sleep(void) { usleep(100000 + (rand() % 200000)); /* Sleep for 100-250 ms */ } void pirate_maybe_escape(int pirate_id) { if (royal_navy) { printf("Pirate %d be seein' the Royal Navy and be escapin'!\n", pirate_id); lock_release(table_lock); pthread_exit(NULL); } } #define left(i) ((i + NUM_PIRATES - 1) % NUM_PIRATES) #define right(i) ((i + 1) % NUM_PIRATES) bool should_eat(int i) { return state[i] == HUNGRY && state[left(i)] != EATING && state[right(i)] != EATING; } void take_cutlasses(int pirate_id) { lock_acquire(table_lock); pirate_maybe_escape(pirate_id); state[pirate_id] = HUNGRY; printf("Pirate %d be hungry and eyein' the cutlasses...\n", pirate_id); while (!should_eat(pirate_id)) { printf("Pirate %d be waitin' for cutlasses...\n", pirate_id); cv_wait(pirate_jab[pirate_id], table_lock); printf("Pirate %d be wakin' up and eyein' the cutlasses...\n", pirate_id); pirate_maybe_escape(pirate_id); } state[pirate_id] = EATING; printf("Pirate %d be eatin' with both cutlasses!\n", pirate_id); lock_release(table_lock); } void drop_cutlasses(int pirate_id) { lock_acquire(table_lock); state[pirate_id] = ARGUING; printf("Pirate %d be done eatin' and ready to argue again!\n", pirate_id); cv_signal(pirate_jab[left(pirate_id)], table_lock); cv_signal(pirate_jab[right(pirate_id)], table_lock); pirate_maybe_escape(pirate_id); lock_release(table_lock); } void * pirate(void *arg) { int pirate_id = *(int *) arg; while (1) { /* Argue about treasure */ printf("Pirate %d be arguin' about the treasure...\n", pirate_id); rand_sleep(); take_cutlasses(pirate_id); /* Eat and swing cutlasses */ rand_sleep(); drop_cutlasses(pirate_id); } return NULL; } int main(void) { int i; int pirate_ids[NUM_PIRATES]; /* Initialize the table lock */ table_lock = lock_create("table_lock"); /* Initialize the condition variables and states */ for (i = 0; i < NUM_PIRATES; i++) { char cv_name[20]; snprintf(cv_name, sizeof(cv_name), "pirate_cv_%d", i); pirate_jab[i] = cv_create(cv_name); state[i] = ARGUING; } /* Create the pirate threads */ for (i = 0; i < NUM_PIRATES; i++) { pirate_ids[i] = i; if (pthread_create(&pirate_thread[i], NULL, pirate, &pirate_ids[i]) != 0) { fprintf(stderr, "Failed to create thread for pirate %d\n", i); exit(1); } } /* Allow ten seconds of pirate fun... */ sleep(10); printf("Avast, ye scurvy dogs! The Royal Navy be here! Arrr!\n"); /* Alert the pirates that the Royal Navy is here */ lock_acquire(table_lock); royal_navy = true; lock_release(table_lock); /* Wait for the threads to finish */ for (i = 0; i < NUM_PIRATES; i++) { pthread_join(pirate_thread[i], NULL); } lock_destroy(table_lock); for (i = 0; i < NUM_PIRATES; i++) { cv_destroy(pirate_jab[i]); } return 0; }
#ifndef SYNCH_H #define SYNCH_H #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define ERR_CHECK(result, msg, ...) \ if (result != 0) { \ fprintf(stderr, "Error: " msg ": %s\n", ##__VA_ARGS__, \ strerror(result)); \ exit(1); \ } #define COND_CHECK(cond, msg, ...) \ if (!(cond)) { \ fprintf(stderr, "Error: " msg "\n", ##__VA_ARGS__); \ exit(1); \ } struct lock { const char *name; pthread_mutex_t posix_mutex; pthread_t lock_owner; }; struct lock * lock_create(const char *name) { struct lock *lock = malloc(sizeof(struct lock)); COND_CHECK(lock != NULL, "Failed to allocate memory for lock"); lock->name = name; int result = pthread_mutex_init(&(lock->posix_mutex), NULL); ERR_CHECK(result, "Failed to initialize mutex"); lock->lock_owner = (pthread_t) 0; return lock; } int lock_do_i_hold(struct lock *lock) { COND_CHECK(lock != NULL, "Attempted to check NULL lock"); return pthread_self() == lock->lock_owner; } void lock_acquire(struct lock *lock) { COND_CHECK(lock != NULL, "Attempted to acquire NULL lock"); int result = pthread_mutex_lock(&(lock->posix_mutex)); ERR_CHECK(result, "Failed to acquire lock %s", lock->name); lock->lock_owner = pthread_self(); } void lock_release(struct lock *lock) { COND_CHECK(lock != NULL, "Attempted to release NULL lock"); COND_CHECK(lock_do_i_hold(lock), "Attempted to release lock %s not held by current thread", lock->name); lock->lock_owner = (pthread_t) 0; int result = pthread_mutex_unlock(&(lock->posix_mutex)); ERR_CHECK(result, "Failed to release lock %s", lock->name); } void lock_destroy(struct lock *lock) { COND_CHECK(lock != NULL, "Attempted to destroy NULL lock"); int result = pthread_mutex_destroy(&(lock->posix_mutex)); ERR_CHECK(result, "Failed to destroy lock %s", lock->name); free(lock); } /* --- CONDITION VARIABLES ----------------------------------------------- */ struct cv { const char *name; pthread_cond_t posix_cv; }; struct cv * cv_create(const char *name) { struct cv *cv = malloc(sizeof(struct cv)); COND_CHECK(cv != NULL, "Failed to allocate memory for cv %s", name); int result = pthread_cond_init(&(cv->posix_cv), NULL); ERR_CHECK(result, "Failed to initialize condition variable %s", name); cv->name = name; return cv; } void cv_wait(struct cv *cv, struct lock *lock) { COND_CHECK(cv != NULL, "Attempted to wait on NULL cv"); COND_CHECK(lock != NULL, "Attempted to wait on NULL lock"); COND_CHECK(lock_do_i_hold(lock), "Attempted to wait on cv %s without holding lock %s", cv->name, lock->name); lock->lock_owner = (pthread_t) 0; int result = pthread_cond_wait(&(cv->posix_cv), &(lock->posix_mutex)); ERR_CHECK(result, "Failed to wait on cv %s", cv->name); lock->lock_owner = pthread_self(); } void cv_signal(struct cv *cv, struct lock *lock) { COND_CHECK(cv != NULL, "Attempted to signal NULL cv"); COND_CHECK(lock != NULL, "Attempted to signal on NULL lock"); COND_CHECK(lock_do_i_hold(lock), "Attempted to signal cv %s without holding lock %s", cv->name, lock->name); int result = pthread_cond_signal(&(cv->posix_cv)); ERR_CHECK(result, "Failed to signal cv %s", cv->name); } void cv_broadcast(struct cv *cv, struct lock *lock) { COND_CHECK(cv != NULL, "Attempted to broadcast NULL cv"); COND_CHECK(lock != NULL, "Attempted to broadcast on NULL lock"); COND_CHECK(lock_do_i_hold(lock), "Attempted to broadcast cv %s without holding lock %s", cv->name, lock->name); int result = pthread_cond_broadcast(&(cv->posix_cv)); ERR_CHECK(result, "Failed to broadcast cv %s", cv->name); } void cv_destroy(struct cv *cv) { COND_CHECK(cv != NULL, "Attempted to destroy NULL cv"); int result = pthread_cond_destroy(&(cv->posix_cv)); ERR_CHECK(result, "Failed to destroy cv %s", cv->name); free(cv); } #endif // SYNCH_H

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue