Add documentation, signal handling, initial supervisor and semaphor functions
This commit is contained in:
@@ -7,16 +7,25 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <semaphore.h> ///< For semaphores
|
||||
|
||||
#define FREE_SEM_NAME "/11777707_free"
|
||||
#define USED_SEM_NAME "/11777707_used"
|
||||
#define USE_SEM_NAME "/11777707_used"
|
||||
#define MUTEX_NAME "/11777707_mutex"
|
||||
|
||||
static sem_t *free_sem;
|
||||
static sem_t *used_sem;
|
||||
static sem_t *use_sem;
|
||||
static sem_t *mutex;
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_open(3) and does error handling.
|
||||
* @details The function executes sem_open(3), giving it a semaphor name and size as parameters,
|
||||
* and handles the errors if any. The same behaviour as sem_open(3) should be expected.
|
||||
* Returns a new semaphore
|
||||
* @param sem_name, sem_size
|
||||
* @return res
|
||||
**/
|
||||
sem_t * open_sem(char *sem_name, size_t sem_size) {
|
||||
sem_t *res = sem_open(sem_name, O_CREAT | O_EXCL, 0600, sem_size);
|
||||
if(res == SEM_FAILED) {
|
||||
@@ -26,6 +35,60 @@ sem_t * open_sem(char *sem_name, size_t sem_size) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_getvalue(3) and does error handling.
|
||||
* @details The function executes sem_getvalue(3), giving it a semaphor and size as parameters,
|
||||
* and handles the errors if any. The same behaviour as sem_getvalue(3) should be expected.
|
||||
* Writes the value of a semaphore to a chosen pointer
|
||||
* @param sem, rem
|
||||
* @return none
|
||||
**/
|
||||
void getval_sem(sem_t *sem, int *res) {
|
||||
if(sem_getvalue(sem, res) == -1) {
|
||||
fprintf(stderr, "ERROR: Failed getting semaphore value\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_wait(3) and does error handling.
|
||||
* @details The function executes sem_wait(3), giving it a semaphor as a parameter,
|
||||
* and handles the errors if any. The same behaviour as sem_wait(3) should be expected.
|
||||
* If the process was terminated, the function exits
|
||||
* @param sem
|
||||
* @return none
|
||||
**/
|
||||
void wait_sem(sem_t *sem) {
|
||||
if(sem_wait(sem) == -1) {
|
||||
if(errno == EINTR) {
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "ERROR: Failed locking semaphore\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_post(3) and does error handling.
|
||||
* @details The function executes sem_post(3), giving it a semaphor as a parameter,
|
||||
* and handles the errors if any. The same behaviour as sem_post(3) should be expected.
|
||||
* @param sem
|
||||
* @return none
|
||||
**/
|
||||
void post_sem(sem_t *sem) {
|
||||
if(sem_post(sem) == -1) {
|
||||
fprintf(stderr, "ERROR: Failed unlocking semaphore\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_close(3) and does error handling.
|
||||
* @details The function executes sem_close(3), giving it a semaphor as a parameter,
|
||||
* and handles the errors if any. The same behaviour as sem_close(3) should be expected.
|
||||
* @param sem
|
||||
* @return none
|
||||
**/
|
||||
void close_sem(sem_t *sem) {
|
||||
if(sem_close(sem) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed closing semaphore\n");
|
||||
@@ -33,6 +96,13 @@ void close_sem(sem_t *sem) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes sem_unlink(3) and does error handling.
|
||||
* @details The function executes sem_unlink(3), giving it a semaphor name as a parameter,
|
||||
* and handles the errors if any. The same behaviour as sem_unlink(3) should be expected.
|
||||
* @param sem_name
|
||||
* @return none
|
||||
**/
|
||||
void destroy_sem(char *sem_name) {
|
||||
if(sem_unlink(sem_name) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed closing semaphore\n");
|
||||
|
@@ -11,8 +11,16 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define BUFFER_SHM_NAME "/11777707_buff"
|
||||
#define BUFF_SHM_NAME "/11777707_buff"
|
||||
|
||||
/**
|
||||
* @brief Function that executes shm_open(3) and does error handling.
|
||||
* @details The function executes shm_open(3), giving it a name as a param,
|
||||
* and handles the errors if any. The same behaviour as shm_open(3) should be expected.
|
||||
* Returns a shared memory object file descriptor
|
||||
* @param shm_name
|
||||
* @return shmfd
|
||||
**/
|
||||
int create_shmfd(char *shm_name) {
|
||||
int shmfd = shm_open(shm_name, O_RDWR | O_CREAT, 0600);
|
||||
if(shmfd == -1) {
|
||||
@@ -22,6 +30,13 @@ int create_shmfd(char *shm_name) {
|
||||
return shmfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes ftruncate(2) and does error handling.
|
||||
* @details The function executes ftruncate(2), giving it a file descriptor and size as parameters,
|
||||
* and handles the errors if any. The same behaviour as ftruncate(2) should be expected.
|
||||
* @param shmfd, shm_size
|
||||
* @return none
|
||||
**/
|
||||
void truncate_shm(int shmfd, size_t shm_size) {
|
||||
if(ftruncate(shmfd, shm_size) < 0) {
|
||||
fprintf(stderr, "ERROR: Failed truncating shared memory object\n");
|
||||
@@ -29,6 +44,14 @@ void truncate_shm(int shmfd, size_t shm_size) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes mmap(2) and does error handling.
|
||||
* @details The function executes mmap(2), giving it a file descriptor and size as parameters,
|
||||
* and handles the errors if any. The same behaviour as mmap(2) should be expected.
|
||||
* Returns a mapped shared memory object
|
||||
* @param shmfd, shm_size
|
||||
* @return shm
|
||||
**/
|
||||
void* open_shm(int shmfd, size_t shm_size) {
|
||||
void* shm;
|
||||
shm = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
|
||||
@@ -41,10 +64,24 @@ void* open_shm(int shmfd, size_t shm_size) {
|
||||
return shm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to write a value to shared memory object
|
||||
* @details The functions copies the value of a string with a specified size to a shared memory object
|
||||
* @param shm, message, message_size
|
||||
* @return none
|
||||
**/
|
||||
void write_to_shm(void* shm, char *message, size_t message_size) {
|
||||
memcpy(shm, message, message_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes munmap(2) and does error handling.
|
||||
* @details The function executes munmap(2), giving it a shared memory object and size as parameters,
|
||||
* and handles the errors if any. The same behaviour as munmap(2) should be expected.
|
||||
* Returns a mapped shared memory object
|
||||
* @param shmfd, shm_size
|
||||
* @return none
|
||||
**/
|
||||
void close_shm(void* shm, size_t shm_size) {
|
||||
if (munmap(shm, shm_size) == -1) {
|
||||
fprintf(stderr, "ERROR: Failed unmapping shared memory object\n");
|
||||
@@ -52,6 +89,14 @@ void close_shm(void* shm, size_t shm_size) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that executes shm_unlink(3) and close(2) and does error handling.
|
||||
* @details The function executes shm_unlink(3) and close(2), giving them a shared memory object name
|
||||
* and a file descriptor respectively, and handles the errors if any.
|
||||
* The same behaviour as shm_unlink(3) and close(2) should be expected.
|
||||
* @param shm_name, shmfd
|
||||
* @return none
|
||||
**/
|
||||
void destroy_shm(char *shm_name, int shmfd) {
|
||||
if (shm_unlink(shm_name) == -1) {
|
||||
fprintf(stderr, "ERROR: Failed unlinking shared memory object\n");
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include <stdbool.h> ///< For boolean constants
|
||||
#include <signal.h>
|
||||
|
||||
#define BUFF_SIZE 8
|
||||
#define SET_MAX_SIZE 8
|
||||
@@ -9,15 +10,44 @@ typedef struct edge {
|
||||
} edge_t;
|
||||
|
||||
/// Struct for the feedback arc set
|
||||
typedef struct fb_set {
|
||||
typedef struct fb_arc_set {
|
||||
bool valid;
|
||||
int edge_num;
|
||||
edge_t edges[SET_MAX_SIZE];
|
||||
} fb_set_t;
|
||||
} fb_arc_set_t;
|
||||
|
||||
/// Struct for the circular buffer
|
||||
typedef struct buffer {
|
||||
bool terminate;
|
||||
fb_set_t sets[BUFF_SIZE];
|
||||
bool finished;
|
||||
short best_arc_len;
|
||||
fb_arc_set_t sets[BUFF_SIZE];
|
||||
} buffer_t;
|
||||
|
||||
static bool terminate = false;
|
||||
|
||||
/**
|
||||
* @brief Function to execute when the program gets a signal
|
||||
* @details flips the terminate variable to true
|
||||
* @param none
|
||||
* @return none
|
||||
**/
|
||||
static void signal_handler() {
|
||||
terminate = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to process the signals passed by the user
|
||||
* @details creates a new sigaction structure
|
||||
* and changes the behaviour of the SIGINT and SIGTERM signals
|
||||
* @param none
|
||||
* @return none
|
||||
**/
|
||||
static void process_signal(void){
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = signal_handler;
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
}
|
||||
|
||||
static buffer_t *circ_buffer;
|
||||
|
Reference in New Issue
Block a user