Start semaphoring out
This commit is contained in:
parent
31a7583074
commit
927b209cef
2
Makefile
2
Makefile
@ -4,7 +4,7 @@ CFLAGS = -Iinc -pthread -lrt
|
|||||||
VPATH = src
|
VPATH = src
|
||||||
|
|
||||||
OBJECTS := %.o list.o producer.o transformer.o consumer.o
|
OBJECTS := %.o list.o producer.o transformer.o consumer.o
|
||||||
EXECUTE := main.out test.out
|
EXECUTE := main.out #test.out
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
|
|
||||||
void consumer ();
|
/*
|
||||||
|
consumer:
|
||||||
|
Unlinks blocks from list2,
|
||||||
|
Consumes them,
|
||||||
|
Links them to freelist
|
||||||
|
*/
|
||||||
|
void *consumer (void *);
|
@ -5,3 +5,8 @@ extern block memory[N];
|
|||||||
// create the three lists
|
// create the three lists
|
||||||
extern list lists[3];
|
extern list lists[3];
|
||||||
extern list *freelist, *list1, *list2;
|
extern list *freelist, *list1, *list2;
|
||||||
|
|
||||||
|
// count semaphores
|
||||||
|
extern sem_t semfl, seml1, seml2;
|
||||||
|
// binary semaphores
|
||||||
|
extern sem_t mutfl, mutl1, mutl2;
|
@ -20,5 +20,4 @@ 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
|
||||||
void list_init (list *l, block *m, int size);
|
void list_init (list *l, block *m, int size);
|
||||||
// list_print: prints a list
|
// list_print: prints a list
|
||||||
void list_print (list *l);
|
void list_print(list *l, bool verbose = false);
|
||||||
void list_concise(list *l);
|
|
@ -1,2 +1,8 @@
|
|||||||
|
|
||||||
void producer ();
|
/*
|
||||||
|
producer:
|
||||||
|
Unlinks blocks from freelist,
|
||||||
|
Produces them,
|
||||||
|
Links them to list1
|
||||||
|
*/
|
||||||
|
void *producer (void *);
|
@ -1,2 +1,10 @@
|
|||||||
|
|
||||||
void transformer ();
|
/*
|
||||||
|
transformer:
|
||||||
|
Unlinks block x from list1
|
||||||
|
Unlinks block y from freelist
|
||||||
|
Uses block x to generate block y's data
|
||||||
|
Links block x to freelist
|
||||||
|
Links block y to list2
|
||||||
|
*/
|
||||||
|
void *transformer (void *);
|
@ -1,9 +1,29 @@
|
|||||||
|
#include <semaphore.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp" // freelist list1 list2
|
||||||
#include "consumer.hpp"
|
#include "consumer.hpp"
|
||||||
|
|
||||||
void consumer () {
|
int consume(block* c);
|
||||||
|
|
||||||
|
void *consumer (void *) {
|
||||||
|
while (true) {
|
||||||
|
sem_wait(&seml2); // decrease seml2
|
||||||
|
sem_wait(&mutl2);
|
||||||
block* c = list_unlink(list2);
|
block* c = list_unlink(list2);
|
||||||
//TODO: consume information in block c
|
sem_post(&mutl2);
|
||||||
|
//* consume information in block c
|
||||||
|
consume(c);
|
||||||
|
sem_wait(&mutfl);
|
||||||
list_link(freelist, c);
|
list_link(freelist, c);
|
||||||
|
sem_post(&mutfl);
|
||||||
|
sem_post(&semfl); // increase freelist
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int consume(block *c) {
|
||||||
|
c->data = -c->data;
|
||||||
|
usleep(75);
|
||||||
|
return 0;
|
||||||
}
|
}
|
15
src/list.cpp
15
src/list.cpp
@ -60,7 +60,8 @@ void list_init (list *l, block *m, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// YAML-like, because I like YAML
|
// YAML-like, because I like YAML
|
||||||
void list_print(list *l) {
|
|
||||||
|
void print_verbose(list *l) {
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
std::printf("l_%p:\n - start: '%p',\n - end: '%p',\n - length: '%d',\n - blocks:",l,l->start,l->end,l->length);
|
std::printf("l_%p:\n - start: '%p',\n - end: '%p',\n - length: '%d',\n - blocks:",l,l->start,l->end,l->length);
|
||||||
block* b = l->start;
|
block* b = l->start;
|
||||||
@ -73,17 +74,21 @@ void list_print(list *l) {
|
|||||||
std::printf(" []\n");
|
std::printf(" []\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// l_[addr]{size}: {element:value, ...}
|
||||||
void list_concise (list *l) {
|
void print_concise(list *l) {
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
std::printf("%lx: {", (__uint64_t)l&0xffff);
|
std::printf("l_%lx{%d}: {", (long int)l&0xffff, l->length);
|
||||||
block *b = l->start;
|
block *b = l->start;
|
||||||
if (b) {
|
if (b) {
|
||||||
do {
|
do {
|
||||||
std::printf("%lx:%d, ", (__uint64_t)b&0xfff, b->data);
|
std::printf("%lx:%d, ", (long int)b&0xfff, b->data);
|
||||||
} while (b = b->next);
|
} while (b = b->next);
|
||||||
std::printf("\b\b} \n");
|
std::printf("\b\b} \n");
|
||||||
} else {
|
} else {
|
||||||
std::printf("}\n");
|
std::printf("}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void list_print(list *l, bool verbose) {
|
||||||
|
(verbose?print_verbose:print_concise)(l);
|
||||||
|
}
|
47
src/main.cpp
47
src/main.cpp
@ -1,8 +1,13 @@
|
|||||||
#include <cstdint>
|
#include <semaphore.h>
|
||||||
#include <cstdio>
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "producer.hpp"
|
#include "producer.hpp"
|
||||||
|
#include "consumer.hpp"
|
||||||
|
#include "transformer.hpp"
|
||||||
|
|
||||||
// Create all of memory
|
// Create all of memory
|
||||||
block memory[N] = {0};
|
block memory[N] = {0};
|
||||||
@ -10,9 +15,45 @@ block memory[N] = {0};
|
|||||||
list lists[3] = {0};
|
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
|
||||||
|
sem_t semfl, seml1, seml2;
|
||||||
|
// binary semaphores
|
||||||
|
sem_t mutfl, mutl1, mutl2;
|
||||||
|
|
||||||
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: Use pthreads to split execution
|
|
||||||
//TODO: Implement a semaphore solution to the problem
|
//TODO: Implement a semaphore solution to the problem
|
||||||
|
sem_init(&semfl, 0, freelist->length);
|
||||||
|
sem_init(&seml1, 0, 0);
|
||||||
|
sem_init(&seml2, 0, 0);
|
||||||
|
sem_init(&mutfl, 0, 1);
|
||||||
|
sem_init(&mutl1, 0, 1);
|
||||||
|
sem_init(&mutl2, 0, 1);
|
||||||
|
|
||||||
|
//TODO: Use pthreads to split execution
|
||||||
|
// Make some pthreads
|
||||||
|
pthread_t thread1, thread2, thread3;
|
||||||
|
|
||||||
|
// Create thread1 as producer
|
||||||
|
pthread_create(&thread1, NULL, producer, NULL);
|
||||||
|
|
||||||
|
// Create thread2 as transformer
|
||||||
|
pthread_create(&thread2, NULL, transformer, NULL);
|
||||||
|
|
||||||
|
// Create thread3 as consumer
|
||||||
|
pthread_create(&thread3, NULL, consumer, NULL);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
list_print(freelist);
|
||||||
|
list_print(list1);
|
||||||
|
list_print(list2);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
// Wait for them to finish
|
||||||
|
pthread_join(thread1, NULL);
|
||||||
|
pthread_join(thread2, NULL);
|
||||||
|
pthread_join(thread3, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,32 @@
|
|||||||
|
#include <semaphore.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp" // freelist list1 list2
|
||||||
#include "producer.hpp"
|
#include "producer.hpp"
|
||||||
|
|
||||||
void producer () {
|
#define wait(x) sem_wait(&x)
|
||||||
block* b = list_unlink(freelist);
|
#define sgnl(x) sem_post(&x)
|
||||||
//TODO: Produce information in block b
|
|
||||||
|
void produce(block* b);
|
||||||
|
|
||||||
|
void *producer (void *) {
|
||||||
|
while (true) {
|
||||||
|
wait(semfl); // wait for freelist not empty
|
||||||
|
wait(mutfl); // lock freelist
|
||||||
|
block *b = list_unlink(freelist);
|
||||||
|
sgnl(mutfl); // unlock freelist
|
||||||
|
//* Produce information in block b
|
||||||
|
produce(b);
|
||||||
|
wait(mutl1); // lock l1
|
||||||
list_link(list1, b);
|
list_link(list1, b);
|
||||||
|
sgnl(mutl1); // unlock l1
|
||||||
|
sgnl(seml1);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void produce(block *b) {
|
||||||
|
b->data++;
|
||||||
|
usleep(65);
|
||||||
|
return;
|
||||||
}
|
}
|
42
src/test.cpp
42
src/test.cpp
@ -1,5 +1,6 @@
|
|||||||
#include <cstdint>
|
#include <semaphore.h>
|
||||||
#include <cstdio>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "producer.hpp"
|
#include "producer.hpp"
|
||||||
@ -14,42 +15,47 @@ list *freelist = &lists[0],
|
|||||||
*list1 = &lists[1],
|
*list1 = &lists[1],
|
||||||
*list2 = &lists[2];
|
*list2 = &lists[2];
|
||||||
|
|
||||||
|
// count semaphores
|
||||||
|
sem_t semfl, seml1, seml2;
|
||||||
|
// binary semaphores
|
||||||
|
sem_t mutfl, mutl1, mutl2;
|
||||||
|
|
||||||
void producer_test();
|
void producer_test();
|
||||||
void transfer_test();
|
void transfer_test();
|
||||||
void consumer_test();
|
void consumer_test();
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
list_init(freelist, memory, N);
|
list_init(freelist, memory, N);
|
||||||
list_concise(freelist);
|
list_print(freelist);
|
||||||
producer_test();
|
//producer_test();
|
||||||
transfer_test();
|
//transfer_test();
|
||||||
consumer_test();
|
//consumer_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
void producer_test() {
|
void producer_test() {
|
||||||
printf("Starting producer_test:\n");\
|
printf("Starting producer_test:\n");\
|
||||||
producer();
|
producer(NULL);
|
||||||
list_concise(freelist);
|
list_print(freelist);
|
||||||
list_concise(list1);
|
list_print(list1);
|
||||||
list_concise(list2);
|
list_print(list2);
|
||||||
printf("Ending producer_test\n");
|
printf("Ending producer_test\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void transfer_test() {
|
void transfer_test() {
|
||||||
printf("Starting transfer_test:\n");
|
printf("Starting transfer_test:\n");
|
||||||
transformer();
|
transformer(NULL);
|
||||||
list_concise(freelist);
|
list_print(freelist);
|
||||||
list_concise(list1);
|
list_print(list1);
|
||||||
list_concise(list2);
|
list_print(list2);
|
||||||
printf("Ending transfer_test\n");
|
printf("Ending transfer_test\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void consumer_test() {
|
void consumer_test() {
|
||||||
printf("Starting consumer_test:\n");
|
printf("Starting consumer_test:\n");
|
||||||
consumer();
|
consumer(NULL);
|
||||||
list_concise(freelist);
|
list_print(freelist);
|
||||||
list_concise(list1);
|
list_print(list1);
|
||||||
list_concise(list2);
|
list_print(list2);
|
||||||
printf("Ending consumer_test\n");
|
printf("Ending consumer_test\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,44 @@
|
|||||||
|
#include <semaphore.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp" // freelist list1 list2
|
||||||
#include "transformer.hpp"
|
#include "transformer.hpp"
|
||||||
|
|
||||||
void transformer () {
|
void transform(block* x, block* y);
|
||||||
block* x = list_unlink(list1);
|
|
||||||
block* y = list_unlink(freelist);
|
void *transformer (void *) {
|
||||||
//TODO: use block x to produce info in y
|
block *x, *y;
|
||||||
|
while (true) {
|
||||||
|
sem_wait(&seml1); // decrease seml1
|
||||||
|
sem_wait(&mutl1);
|
||||||
|
x = list_unlink(list1);
|
||||||
|
sem_post(&mutl1);
|
||||||
|
|
||||||
|
sem_wait(&semfl); // decrease semfl
|
||||||
|
sem_wait(&mutfl);
|
||||||
|
y = list_unlink(freelist);
|
||||||
|
sem_post(&mutfl);
|
||||||
|
|
||||||
|
//* use block x to produce info in y
|
||||||
|
transform(x, y);
|
||||||
|
|
||||||
|
sem_wait(&mutfl);
|
||||||
list_link(freelist, x);
|
list_link(freelist, x);
|
||||||
|
sem_post(&mutfl);
|
||||||
|
sem_post(&semfl);
|
||||||
|
|
||||||
|
sem_wait(&mutl2);
|
||||||
list_link(list2, y);
|
list_link(list2, y);
|
||||||
|
sem_post(&mutl2);
|
||||||
|
sem_post(&seml2);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform(block *x, block *y) {
|
||||||
|
x->data ^= y->data;
|
||||||
|
y->data ^= x->data;
|
||||||
|
x->data ^= y->data;
|
||||||
|
usleep(55);
|
||||||
|
return;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user