Make variable names more accurate
Make functions more functional Make comments more commentary
This commit is contained in:
parent
927b209cef
commit
478778841e
@ -1,4 +1,10 @@
|
|||||||
#define N 8
|
#define N 8
|
||||||
|
#define timescale 5
|
||||||
|
|
||||||
|
//function defines, renaming wait and signal
|
||||||
|
#define wait(x) sem_wait(&x)
|
||||||
|
#define signal(x) sem_post(&x)
|
||||||
|
|
||||||
// Shared memory through global variables
|
// Shared memory through global variables
|
||||||
// Create all of memory
|
// Create all of memory
|
||||||
extern block memory[N];
|
extern block memory[N];
|
||||||
@ -7,6 +13,8 @@ extern list lists[3];
|
|||||||
extern list *freelist, *list1, *list2;
|
extern list *freelist, *list1, *list2;
|
||||||
|
|
||||||
// count semaphores
|
// count semaphores
|
||||||
extern sem_t semfl, seml1, seml2;
|
extern sem_t sem_freelist, sem_list1, sem_list2;
|
||||||
// binary semaphores
|
// binary semaphores
|
||||||
extern sem_t mutfl, mutl1, mutl2;
|
extern sem_t mut_freelist, mut_list1, mut_list2;
|
||||||
|
// binary semaphores for reading/writing
|
||||||
|
extern sem_t mut_take, mut_give;
|
@ -14,7 +14,7 @@ struct list {
|
|||||||
|
|
||||||
// list operations:
|
// list operations:
|
||||||
// list_unlink: unlinks the last block in the list, and returns a pointer to it
|
// list_unlink: unlinks the last block in the list, and returns a pointer to it
|
||||||
block *list_unlink (list *l);
|
block* list_unlink (list* l, bool lastblock=0);
|
||||||
// list_link: links the block b onto the end of the list
|
// list_link: links the block b onto the end of the list
|
||||||
void list_link (list *l, block *b);
|
void list_link (list *l, block *b);
|
||||||
// list_init: links an array of blocks onto the end of a list
|
// list_init: links an array of blocks onto the end of a list
|
||||||
|
@ -1,29 +1,35 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp" // list implementation
|
||||||
#include "globals.hpp" // freelist list1 list2
|
#include "globals.hpp" // lists, sems, muts
|
||||||
#include "consumer.hpp"
|
#include "consumer.hpp"
|
||||||
|
|
||||||
|
#define unlink(x) list_unlink(x)
|
||||||
|
#define link(x) list_link(x)
|
||||||
|
|
||||||
int consume(block* c);
|
int consume(block* c);
|
||||||
|
|
||||||
void *consumer (void *) {
|
void *consumer (void *) {
|
||||||
while (true) {
|
while (true) {
|
||||||
sem_wait(&seml2); // decrease seml2
|
|
||||||
sem_wait(&mutl2);
|
wait(sem_list2);
|
||||||
|
wait(mut_list2);
|
||||||
block* c = list_unlink(list2);
|
block* c = list_unlink(list2);
|
||||||
sem_post(&mutl2);
|
signal(mut_list2);
|
||||||
|
|
||||||
//* consume information in block c
|
//* consume information in block c
|
||||||
consume(c);
|
consume(c);
|
||||||
sem_wait(&mutfl);
|
|
||||||
|
wait(mut_freelist);
|
||||||
list_link(freelist, c);
|
list_link(freelist, c);
|
||||||
sem_post(&mutfl);
|
signal(mut_freelist);
|
||||||
sem_post(&semfl); // increase freelist
|
signal(sem_freelist);
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int consume(block *c) {
|
int consume(block *c) {
|
||||||
c->data = -c->data;
|
usleep(75*timescale);
|
||||||
usleep(75);
|
return c->data;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
32
src/list.cpp
32
src/list.cpp
@ -1,8 +1,34 @@
|
|||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
// dequeue the first block
|
||||||
|
block* list_dequeue (list* l) {
|
||||||
|
// we need a list
|
||||||
|
if (!l) return nullptr;
|
||||||
|
block* b = l->start;
|
||||||
|
// can't unlink from an empty list
|
||||||
|
if (!b) return nullptr;
|
||||||
|
// remove b
|
||||||
|
if (b->next) {
|
||||||
|
// b is not the only element of the list
|
||||||
|
// chop of the head
|
||||||
|
l->start = b->next;
|
||||||
|
// bandage the wound
|
||||||
|
l->start->prev = nullptr;
|
||||||
|
// wrap the severed head
|
||||||
|
b->next = nullptr;
|
||||||
|
} else {
|
||||||
|
// b is the only element of the list
|
||||||
|
l->start = nullptr;
|
||||||
|
l->end = nullptr;
|
||||||
|
}
|
||||||
|
// if we get here, we've removed element b from the list
|
||||||
|
l->length--;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
// pop the last block
|
// pop the last block
|
||||||
block* list_unlink (list* l) {
|
block* list_pop (list* l) {
|
||||||
// we need a list
|
// we need a list
|
||||||
if (!l) return nullptr;
|
if (!l) return nullptr;
|
||||||
block* b = l->end;
|
block* b = l->end;
|
||||||
@ -27,6 +53,10 @@ block* list_unlink (list* l) {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block* list_unlink (list* l, bool lastblock) {
|
||||||
|
return (lastblock?list_pop:list_dequeue)(l);
|
||||||
|
}
|
||||||
|
|
||||||
// push a block
|
// push a block
|
||||||
void list_link (list* l, block* b) {
|
void list_link (list* l, block* b) {
|
||||||
// can't link to a nonexistent list
|
// can't link to a nonexistent list
|
||||||
|
25
src/main.cpp
25
src/main.cpp
@ -16,21 +16,27 @@ list lists[3] = {0};
|
|||||||
list *freelist = &lists[0], *list1 = &lists[1], *list2 = &lists[2];
|
list *freelist = &lists[0], *list1 = &lists[1], *list2 = &lists[2];
|
||||||
|
|
||||||
// count semaphores
|
// count semaphores
|
||||||
sem_t semfl, seml1, seml2;
|
sem_t sem_freelist, sem_list1, sem_list2;
|
||||||
// binary semaphores
|
// binary semaphores
|
||||||
sem_t mutfl, mutl1, mutl2;
|
sem_t mut_freelist, mut_list1, mut_list2;
|
||||||
|
// binary semaphores for reading/writing
|
||||||
|
sem_t mut_take, mut_give;
|
||||||
|
|
||||||
int main (int argc, char* argv[]) {
|
int main (int argc, char* argv[]) {
|
||||||
// initialize the freelist
|
// initialize the freelist
|
||||||
list_init(freelist, memory, N);
|
list_init(freelist, memory, N);
|
||||||
|
|
||||||
//TODO: Implement a semaphore solution to the problem
|
//TODO: Implement a semaphore solution to the problem
|
||||||
sem_init(&semfl, 0, freelist->length);
|
// counting semaphores measure the length
|
||||||
sem_init(&seml1, 0, 0);
|
sem_init(&sem_freelist, 0, freelist->length);
|
||||||
sem_init(&seml2, 0, 0);
|
sem_init(&sem_list1, 0, 0);
|
||||||
sem_init(&mutfl, 0, 1);
|
sem_init(&sem_list2, 0, 0);
|
||||||
sem_init(&mutl1, 0, 1);
|
// binary semaphores create mutual exclusion
|
||||||
sem_init(&mutl2, 0, 1);
|
sem_init(&mut_freelist, 0, 1);
|
||||||
|
sem_init(&mut_list1, 0, 1);
|
||||||
|
sem_init(&mut_list2, 0, 1);
|
||||||
|
sem_init(&mut_take, 0, 1);
|
||||||
|
sem_init(&mut_give, 0, 1);
|
||||||
|
|
||||||
//TODO: Use pthreads to split execution
|
//TODO: Use pthreads to split execution
|
||||||
// Make some pthreads
|
// Make some pthreads
|
||||||
@ -46,10 +52,11 @@ int main (int argc, char* argv[]) {
|
|||||||
pthread_create(&thread3, NULL, consumer, NULL);
|
pthread_create(&thread3, NULL, consumer, NULL);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
printf("\033c");
|
||||||
list_print(freelist);
|
list_print(freelist);
|
||||||
list_print(list1);
|
list_print(list1);
|
||||||
list_print(list2);
|
list_print(list2);
|
||||||
sleep(1);
|
usleep(100*timescale);
|
||||||
}
|
}
|
||||||
// Wait for them to finish
|
// Wait for them to finish
|
||||||
pthread_join(thread1, NULL);
|
pthread_join(thread1, NULL);
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp" // list implementation
|
||||||
#include "globals.hpp" // freelist list1 list2
|
#include "globals.hpp" // lists, sems, muts
|
||||||
#include "producer.hpp"
|
#include "producer.hpp"
|
||||||
|
|
||||||
#define wait(x) sem_wait(&x)
|
|
||||||
#define sgnl(x) sem_post(&x)
|
|
||||||
|
|
||||||
void produce(block* b);
|
void produce(block* b);
|
||||||
|
|
||||||
void *producer (void *) {
|
void *producer (void *) {
|
||||||
while (true) {
|
while (true) {
|
||||||
wait(semfl); // wait for freelist not empty
|
|
||||||
wait(mutfl); // lock freelist
|
wait(sem_freelist); // wait for freelist not empty
|
||||||
|
wait(mut_freelist); // lock freelist
|
||||||
block *b = list_unlink(freelist);
|
block *b = list_unlink(freelist);
|
||||||
sgnl(mutfl); // unlock freelist
|
signal(mut_freelist); // unlock freelist
|
||||||
|
|
||||||
//* Produce information in block b
|
//* Produce information in block b
|
||||||
produce(b);
|
produce(b);
|
||||||
wait(mutl1); // lock l1
|
|
||||||
|
wait(mut_list1); // lock l1
|
||||||
list_link(list1, b);
|
list_link(list1, b);
|
||||||
sgnl(mutl1); // unlock l1
|
signal(mut_list1); // unlock l1
|
||||||
sgnl(seml1);
|
signal(sem_list1);
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void produce(block *b) {
|
void produce(block *b) {
|
||||||
b->data++;
|
usleep(65*timescale);
|
||||||
usleep(65);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ list *freelist = &lists[0],
|
|||||||
*list2 = &lists[2];
|
*list2 = &lists[2];
|
||||||
|
|
||||||
// count semaphores
|
// count semaphores
|
||||||
sem_t semfl, seml1, seml2;
|
sem_t sem_freelist, sem_list1, sem_list2;
|
||||||
// binary semaphores
|
// binary semaphores
|
||||||
sem_t mutfl, mutl1, mutl2;
|
sem_t mut_freelist, mut_list1, mut_list2;
|
||||||
|
|
||||||
void producer_test();
|
void producer_test();
|
||||||
void transfer_test();
|
void transfer_test();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp" // list implementation
|
||||||
#include "globals.hpp" // freelist list1 list2
|
#include "globals.hpp" // lists, sems, muts
|
||||||
#include "transformer.hpp"
|
#include "transformer.hpp"
|
||||||
|
|
||||||
void transform(block* x, block* y);
|
void transform(block* x, block* y);
|
||||||
@ -9,36 +9,35 @@ void transform(block* x, block* y);
|
|||||||
void *transformer (void *) {
|
void *transformer (void *) {
|
||||||
block *x, *y;
|
block *x, *y;
|
||||||
while (true) {
|
while (true) {
|
||||||
sem_wait(&seml1); // decrease seml1
|
|
||||||
sem_wait(&mutl1);
|
|
||||||
x = list_unlink(list1);
|
|
||||||
sem_post(&mutl1);
|
|
||||||
|
|
||||||
sem_wait(&semfl); // decrease semfl
|
wait(sem_list1);
|
||||||
sem_wait(&mutfl);
|
wait(mut_list1);
|
||||||
|
x = list_unlink(list1);
|
||||||
|
signal(mut_list1);
|
||||||
|
|
||||||
|
wait(sem_freelist);
|
||||||
|
wait(mut_freelist);
|
||||||
y = list_unlink(freelist);
|
y = list_unlink(freelist);
|
||||||
sem_post(&mutfl);
|
signal(mut_freelist);
|
||||||
|
|
||||||
//* use block x to produce info in y
|
//* use block x to produce info in y
|
||||||
transform(x, y);
|
transform(x, y);
|
||||||
|
|
||||||
sem_wait(&mutfl);
|
wait(mut_freelist);
|
||||||
list_link(freelist, x);
|
list_link(freelist, x);
|
||||||
sem_post(&mutfl);
|
signal(mut_freelist);
|
||||||
sem_post(&semfl);
|
signal(sem_freelist);
|
||||||
|
|
||||||
sem_wait(&mutl2);
|
wait(mut_list2);
|
||||||
list_link(list2, y);
|
list_link(list2, y);
|
||||||
sem_post(&mutl2);
|
signal(mut_list2);
|
||||||
sem_post(&seml2);
|
signal(sem_list2);
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform(block *x, block *y) {
|
void transform(block *x, block *y) {
|
||||||
x->data ^= y->data;
|
usleep(55*timescale);
|
||||||
y->data ^= x->data;
|
|
||||||
x->data ^= y->data;
|
|
||||||
usleep(55);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user