Add initial shared memory object functions

This commit is contained in:
Ivaylo Ivanov 2019-01-11 16:44:38 +01:00
parent 435eb6dba6
commit 9a652f4d4e
5 changed files with 139 additions and 4 deletions

2
.gitignore vendored
View File

@ -8,3 +8,5 @@ http/client
http/server
mygrep/mygrep
cpair/cpair
fb_arc_set/supervisor
fb_arc_set/generator

View File

@ -5,16 +5,16 @@ TARGET_2 = supervisor
all: $(TARGET_1).c $(TARGET_2).c
$(CC) $(CFLAGS) $(TARGET_1).c $(TARGET_2).c
$(CC) $(TARGET_1).o -o $(TARGET_1)
$(CC) $(TARGET_2).o -o $(TARGET_2)
$(CC) $(TARGET_1).o -o $(TARGET_1) -lrt
$(CC) $(TARGET_2).o -o $(TARGET_2) -lrt
generator: $(TARGET_1).c
$(CC) $(CFLAGS) $(TARGET_1).c
$(CC) $(TARGET_1).o -o $(TARGET_1)
$(CC) $(TARGET_1).o -o $(TARGET_1) -lrt
supervisor: $(TARGET_2).c
$(CC) $(CFLAGS) $(TARGET_2).c
$(CC) $(TARGET_2).o -o $(TARGET_2)
$(CC) $(TARGET_2).o -o $(TARGET_2) -lrt
install:
cp $(TARGET_1) /usr/local/bin/graph-$(TARGET_1)

View File

@ -0,0 +1,44 @@
/**
* @file generator.c
* @author Ivaylo Ivanov 11777707
* @date 11.01.2018
*
* @brief Generator program module.
*
* The generator program takes a graph as input. The program repeatedly generates a random solution
* to the problem as described on the first page and writes its result to the circular buffer. It repeats this
* procedure until it is notified by the supervisor to terminate.
* The generator program takes as arguments the set of edges of the graph.
* Each positional argument is one edge; at least one edge must be given. An edge is specified by a string,
* with the indices of the two nodes it connects separated by a -. Since the graph is directed, the edge starts
* at the first node and leads to the second node. Note that the number of nodes of the graph is implicitly
* provided through the indices in the edges. In the example above the generator program is called with
* the graph shown on the first page.
* The generator uses the algorithm described on the first page to generate random feedback arc sets for the
* given graph. It writes these feedback arc sets to the circular buffer, one at a time; therefore a feedback
* arc set is a single element of the circular buffer. The generator may produce debug output, describing
* the feedback arc sets which it writes to the circular buffer.
*
* SYNOPSIS
* generator EDGE1 EDGE2 ...
*
* EXAMPLE
* generator 0-1 1-2 1-3 1-4 2-4 3-6 4-3 4-5 6-0
*
**/
#include "shared/shm.c"
int main(int argc, char *argv[]) {
if(argc > 1) {
fprintf(stderr, "ERROR: Command takes no arguments");
exit(EXIT_FAILURE);
}
void* terminate_shm = open_shm(TERMINATE_SHM, TERMINATE_SHM_SIZE);
write_to_shm(terminate_shm, "1", TERMINATE_SHM_SIZE);
puts(terminate_shm);
close_shm(terminate_shm, TERMINATE_SHM_SIZE);
destroy_shm(TERMINATE_SHM);
}

52
fb_arc_set/shared/shm.c Normal file
View File

@ -0,0 +1,52 @@
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define TERMINATE_SHM "/terminate"
#define TERMINATE_SHM_SIZE 8
void* open_shm(char *shm_name, size_t shm_size) {
int shmfd = shm_open(shm_name, O_RDWR | O_CREAT, 0600);
if(shmfd == -1) {
fprintf(stderr, "ERROR: Failed creating shared memory object");
exit(EXIT_FAILURE);
}
if(ftruncate(shmfd, shm_size) < 0) {
fprintf(stderr, "ERROR: Failed truncating shared memory object");
exit(EXIT_FAILURE);
}
void* shm;
shm = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
if(shm == MAP_FAILED) {
fprintf(stderr, "ERROR: Failed mapping shared memory object");
exit(EXIT_FAILURE);
}
return shm;
}
void write_to_shm(void* shm, char *message, size_t message_size) {
memcpy(shm, message, message_size);
}
void close_shm(void* shm, size_t shm_size) {
if (munmap(shm, shm_size) == -1) {
fprintf(stderr, "ERROR: Failed unmapping shared memory object");
exit(EXIT_FAILURE);
}
}
void destroy_shm(char *shm_name) {
if (shm_unlink(shm_name) == -1) {
fprintf(stderr, "ERROR: Failed unlinking shared memory object");
exit(EXIT_FAILURE);
}
}

View File

@ -0,0 +1,37 @@
/**
* @file supervisor.c
* @author Ivaylo Ivanov 11777707
* @date 11.01.2018
*
* @brief Supervisor program module.
*
* The supervisor sets up the shared memory and the semaphores and initializes the circular buffer required
* for the communication with the generators. It then waits for the generators to write solutions to the
* circular buffer.
* The supervisor program takes no arguments.
* Once initialization is complete, the supervisor reads the solutions from the circular buffer and remembers the best solution so far, i.e. the solution with the least edges. Every time a better solution than the
* previous best solution is found, the supervisor writes the new solution to standard output. If a generator
* writes a solution with 0 edges to the circular buffer, then the graph is acyclic and the supervisor terminates. Otherwise the supervisor keeps reading results from the circular buffer until it receives a SIGINT
* or a SIGTERM signal.
* Before terminating, the supervisor notifies all generators that they should terminate as well. This can
* be done by setting a variable in the shared memory, which is checked by the generator processes before
* writing to the buffer. The supervisor then unlinks all shared resources and exits.
*
* SYNOPSIS
* supervisor
*
**/
#include "shared/shm.c"
int main(int argc, char *argv[]) {
if(argc > 1) {
fprintf(stderr, "ERROR: Command takes no arguments");
exit(EXIT_FAILURE);
}
void* terminate_shm = open_shm(TERMINATE_SHM, TERMINATE_SHM_SIZE);
write_to_shm(terminate_shm, "1", TERMINATE_SHM_SIZE);
close_shm(terminate_shm, TERMINATE_SHM_SIZE);
destroy_shm(TERMINATE_SHM);
}