Start semaphoring out

This commit is contained in:
John 2022-04-04 20:12:40 -05:00
parent 31a7583074
commit 927b209cef
12 changed files with 205 additions and 53 deletions

View File

@ -4,7 +4,7 @@ CFLAGS = -Iinc -pthread -lrt
VPATH = src
OBJECTS := %.o list.o producer.o transformer.o consumer.o
EXECUTE := main.out test.out
EXECUTE := main.out #test.out
.PHONY: all clean

View File

@ -1,2 +1,8 @@
void consumer ();
/*
consumer:
Unlinks blocks from list2,
Consumes them,
Links them to freelist
*/
void *consumer (void *);

View File

@ -5,3 +5,8 @@ extern block memory[N];
// create the three lists
extern list lists[3];
extern list *freelist, *list1, *list2;
// count semaphores
extern sem_t semfl, seml1, seml2;
// binary semaphores
extern sem_t mutfl, mutl1, mutl2;

View File

@ -20,5 +20,4 @@ void list_link (list *l, block *b);
// list_init: links an array of blocks onto the end of a list
void list_init (list *l, block *m, int size);
// list_print: prints a list
void list_print (list *l);
void list_concise(list *l);
void list_print(list *l, bool verbose = false);

View File

@ -1,2 +1,8 @@
void producer ();
/*
producer:
Unlinks blocks from freelist,
Produces them,
Links them to list1
*/
void *producer (void *);

View File

@ -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 *);

View File

@ -1,9 +1,29 @@
#include <semaphore.h>
#include <unistd.h>
#include "list.hpp"
#include "globals.hpp"
#include "globals.hpp" // freelist list1 list2
#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);
//TODO: consume information in block c
sem_post(&mutl2);
//* consume information in block c
consume(c);
sem_wait(&mutfl);
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;
}

View File

@ -60,7 +60,8 @@ void list_init (list *l, block *m, int size) {
}
// YAML-like, because I like YAML
void list_print(list *l) {
void print_verbose(list *l) {
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);
block* b = l->start;
@ -73,17 +74,21 @@ void list_print(list *l) {
std::printf(" []\n");
}
}
void list_concise (list *l) {
// l_[addr]{size}: {element:value, ...}
void print_concise(list *l) {
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;
if (b) {
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);
std::printf("\b\b} \n");
} else {
std::printf("}\n");
}
}
void list_print(list *l, bool verbose) {
(verbose?print_verbose:print_concise)(l);
}

View File

@ -1,8 +1,13 @@
#include <cstdint>
#include <cstdio>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include "list.hpp"
#include "globals.hpp"
#include "producer.hpp"
#include "consumer.hpp"
#include "transformer.hpp"
// Create all of memory
block memory[N] = {0};
@ -10,9 +15,45 @@ block memory[N] = {0};
list lists[3] = {0};
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[]) {
// initialize the freelist
list_init(freelist, memory, N);
//TODO: Use pthreads to split execution
//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);
}

View File

@ -1,9 +1,32 @@
#include <semaphore.h>
#include <unistd.h>
#include "list.hpp"
#include "globals.hpp"
#include "globals.hpp" // freelist list1 list2
#include "producer.hpp"
void producer () {
block* b = list_unlink(freelist);
//TODO: Produce information in block b
#define wait(x) sem_wait(&x)
#define sgnl(x) sem_post(&x)
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);
sgnl(mutl1); // unlock l1
sgnl(seml1);
}
return nullptr;
}
void produce(block *b) {
b->data++;
usleep(65);
return;
}

View File

@ -1,5 +1,6 @@
#include <cstdint>
#include <cstdio>
#include <semaphore.h>
#include <stdint.h>
#include <stdio.h>
#include "list.hpp"
#include "globals.hpp"
#include "producer.hpp"
@ -14,42 +15,47 @@ list *freelist = &lists[0],
*list1 = &lists[1],
*list2 = &lists[2];
// count semaphores
sem_t semfl, seml1, seml2;
// binary semaphores
sem_t mutfl, mutl1, mutl2;
void producer_test();
void transfer_test();
void consumer_test();
int main(int argc, char *argv[]) {
list_init(freelist, memory, N);
list_concise(freelist);
producer_test();
transfer_test();
consumer_test();
list_print(freelist);
//producer_test();
//transfer_test();
//consumer_test();
}
void producer_test() {
printf("Starting producer_test:\n");\
producer();
list_concise(freelist);
list_concise(list1);
list_concise(list2);
producer(NULL);
list_print(freelist);
list_print(list1);
list_print(list2);
printf("Ending producer_test\n");
}
void transfer_test() {
printf("Starting transfer_test:\n");
transformer();
list_concise(freelist);
list_concise(list1);
list_concise(list2);
transformer(NULL);
list_print(freelist);
list_print(list1);
list_print(list2);
printf("Ending transfer_test\n");
}
void consumer_test() {
printf("Starting consumer_test:\n");
consumer();
list_concise(freelist);
list_concise(list1);
list_concise(list2);
consumer(NULL);
list_print(freelist);
list_print(list1);
list_print(list2);
printf("Ending consumer_test\n");
}

View File

@ -1,11 +1,44 @@
#include <semaphore.h>
#include <unistd.h>
#include "list.hpp"
#include "globals.hpp"
#include "globals.hpp" // freelist list1 list2
#include "transformer.hpp"
void transformer () {
block* x = list_unlink(list1);
block* y = list_unlink(freelist);
//TODO: use block x to produce info in y
void transform(block* x, block* y);
void *transformer (void *) {
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);
sem_post(&mutfl);
sem_post(&semfl);
sem_wait(&mutl2);
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;
}