online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include "synch.h" #define NUM_PIRATES 5 struct lock *cutlass[NUM_PIRATES]; pthread_t pirate_thread[NUM_PIRATES]; void rand_sleep(void) { usleep(100000 + (rand() % 200000)); /* Sleep for 100-250 ms */ } void * pirate(void *arg) { int i = *(int *)arg; int left = i; int right = (i + 1) % NUM_PIRATES; while (1) { /* Argue about treasure */ printf("Pirate %d be arguin' about the treasure...\n", i); rand_sleep(); printf("Pirate %d be eyein' the cutlasses...\n", i); /* Grab the left cutlass */ lock_acquire(cutlass[left]); printf("Pirate %d grabbed the left cutlass %d!\n", i, left); /* Momentary confusion from too much grog */ rand_sleep(); /* Grab the right cutlass */ lock_acquire(cutlass[right]); printf("Pirate %d grabbed the right cutlass %d!\n", i, right); /* Use both cutlasses */ printf("Pirate %d be eatin', swingin' both cutlasses!\n", i); rand_sleep(); /* Release the cutlasses */ lock_release(cutlass[right]); lock_release(cutlass[left]); } return NULL; } int main(void) { int i; int pirate_ids[NUM_PIRATES]; /* Initialize the locks */ for (i = 0; i < NUM_PIRATES; i++) { char lock_name[20]; snprintf(lock_name, sizeof(lock_name), "cutlass_%d", i); cutlass[i] = lock_create(lock_name); if (cutlass[i] == NULL) { fprintf(stderr, "Failed to create lock for cutlass %d\n", i); exit(1); } } /* 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); /* ...then kill the fun in case you leave it running in OnlineGDB or the CS 134 server */ printf("Avast, ye scurvy dogs! The Royal Navy be here! The pirates be done for!\n"); /* We won't clean up since we're might be deadlocked, just exit */ 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