Last active
February 12, 2021 22:34
-
-
Save ProfAvery/efff2b2f7f5292c9ee35627e9fedd3c3 to your computer and use it in GitHub Desktop.
In-class exercise: Resource Allocation Graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.o | |
resource-allocation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CXXFLAGS = -g -std=c++17 -Wall -Wextra -Wpedantic -pthread | |
TARGETS = resource-allocation | |
.PHONY: test clean | |
all: $(TARGETS) | |
resource-allocation: resource-allocation.o sync.o | |
$(CXX) $(CXXFLAGS) -o $@ $^ | |
test: $(TARGETS) | |
./try.sh ./resource-allocation 1000 | |
clean: | |
rm -f *.o $(TARGETS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdlib> | |
#include <iostream> | |
#include <tuple> | |
#include <pthread.h> | |
#include <semaphore.h> | |
#include "sync.h" | |
using std::cout; | |
using std::endl; | |
using std::ignore; | |
Semaphore r1, r2(2), r3; | |
void *do_t1(void *); | |
void *do_t2(void *); | |
void *do_t3(void *); | |
int main() | |
{ | |
Thread t1, t2, t3; | |
t1.create(do_t1); | |
t2.create(do_t2); | |
t3.create(do_t3); | |
t1.join(); | |
t2.join(); | |
t3.join(); | |
return EXIT_SUCCESS; | |
} | |
void *do_t1(void *param) | |
{ | |
ignore = param; | |
r2.wait(); | |
r1.wait(); | |
cout << "I am t1" << endl; | |
r1.post(); | |
r2.post(); | |
pthread_exit(NULL); | |
} | |
void *do_t2(void *param) | |
{ | |
ignore = param; | |
r1.wait(); | |
r2.wait(); | |
r3.wait(); | |
cout << "I am t2" << endl; | |
r3.post(); | |
r2.post(); | |
r1.post(); | |
pthread_exit(NULL); | |
} | |
void *do_t3(void *param) | |
{ | |
ignore = param; | |
r3.wait(); | |
r2.wait(); | |
cout << "I am t3" << endl; | |
r2.post(); | |
r3.post(); | |
pthread_exit(NULL); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdlib> | |
#include <iostream> | |
#include <string> | |
#include <tuple> | |
#include <sys/stat.h> | |
#include <pthread.h> | |
#include "sync.h" | |
void Thread::create(void *(*routine)(void *), void *arg) | |
{ | |
errno = pthread_create(&tid, NULL, routine, arg); | |
if (errno != 0) { | |
perror("pthread_create"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void Thread::join() | |
{ | |
errno = pthread_join(tid, NULL); | |
if (errno != 0) { | |
perror("pthread_join"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
Mutex::Mutex() | |
{ | |
errno = pthread_mutex_init(&mutex, NULL); | |
if (errno != 0) { | |
perror("pthread_mutex_init"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
Mutex::~Mutex() | |
{ | |
errno = pthread_mutex_destroy(&mutex); | |
if (errno != 0) { | |
perror("pthread_mutex_destroy"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void Mutex::lock() | |
{ | |
errno = pthread_mutex_lock(&mutex); | |
if (errno != 0) { | |
perror("pthread_mutex_lock"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void Mutex::unlock() | |
{ | |
errno = pthread_mutex_unlock(&mutex); | |
if (errno != 0) { | |
perror("pthread_mutex_unlock"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
Semaphore::Semaphore(int value) | |
{ | |
auto ok = sem_init(&sem, 0, value); | |
if (ok < 0) { | |
perror("sem_init"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
Semaphore::~Semaphore() | |
{ | |
auto ok = sem_destroy(&sem); | |
if (ok < 0) { | |
perror("sem_destroy"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void Semaphore::wait() | |
{ | |
auto ok = sem_wait(&sem); | |
if (ok < 0) { | |
perror("sem_wait"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void Semaphore::post() | |
{ | |
auto ok = sem_post(&sem); | |
if (ok < 0) { | |
perror("sem_post"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
NamedSemaphore::NamedSemaphore(std::string name, int oflag, mode_t mode, int value) | |
{ | |
psem = sem_open(name.c_str(), oflag, mode, value); | |
if (psem == SEM_FAILED) { | |
perror("sem_open"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
NamedSemaphore::~NamedSemaphore() | |
{ | |
auto ok = sem_close(psem); | |
if (ok < 0) { | |
perror("sem_destroy"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void NamedSemaphore::wait() | |
{ | |
auto ok = sem_wait(psem); | |
if (ok < 0) { | |
perror("sem_wait"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void NamedSemaphore::post() | |
{ | |
auto ok = sem_post(psem); | |
if (ok < 0) { | |
perror("sem_post"); | |
exit(EXIT_FAILURE); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SYNC_H | |
#define SYNC_H | |
#include <semaphore.h> | |
#include <sys/stat.h> | |
const auto DEFAULT_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; | |
class Thread { | |
public: | |
void create(void *(*thread)(void *), void *arg = NULL); | |
void join(); | |
private: | |
pthread_t tid; | |
}; | |
class Mutex { | |
public: | |
Mutex(); | |
~Mutex(); | |
void lock(); | |
void unlock(); | |
private: | |
pthread_mutex_t mutex; | |
}; | |
class Semaphore { | |
public: | |
Semaphore(int = 1); | |
~Semaphore(); | |
void wait(); | |
void post(); | |
private: | |
sem_t sem; | |
}; | |
class NamedSemaphore { | |
public: | |
NamedSemaphore(std::string, int, mode_t = DEFAULT_MODE, int = 1); | |
~NamedSemaphore(); | |
void wait(); | |
void post(); | |
private: | |
sem_t *psem; | |
std::string name; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
executable="$1" | |
shift; | |
echo Will we lock up? | |
for i in $(seq 1 10000); do | |
timeout 5s "./$executable" "$@" > /dev/null | |
if [ $? -eq 124 ]; then | |
echo Hung on try "$i". | |
exit | |
fi | |
done | |
echo Apparently not. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment