diff --git a/Makefile b/Makefile index 84ab7bc..3881ea6 100644 --- a/Makefile +++ b/Makefile @@ -30,9 +30,6 @@ test: pvs-studio-analyzer analyze plog-converter -a '64:1,2,3;GA:1,2,3;OP:1,2,3' -t tasklist -o report.tasks PVS-Studio.log cppcheck --quiet --enable=all --force --inconclusive . - valgrind --leak-check=full --track-origins=yes ./solve HardTest/*.cnf > valgrindSolve.output 2>&1 - ./solve HardTest/*.cnf | valgrind --leak-check=full --show-leak-kinds=all ./view > valgrindView.output 2>&1 - valgrind --leak-check=full ./slave > valgrindSlave.output 2>&1 < Test/*.cnf .PHONY: all clean test diff --git a/README.md b/README.md index 333cd97..aa3496a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Debe instalar minisat. Este se encuentra disponible en el repositorio de la vast Debian/Ubuntu: `apt install minisat`\ macOS (con [homebrew](https://brew.sh/)): `brew install minisat` -Si tiene otra distribución consulte cómo hacerlo. +Si tiene otra distribución consulte cómo hacerlo. De todos modos, puede construirlo desde la [fuente](https://github.com/niklasso/minisat). ## Compilación @@ -60,12 +60,18 @@ Además, dispondrá de 5 segundos para correr el programa `view`. ## Testeos -En orden de realizar los testeos usted debe tener instalado [valgrind](https://valgrind.org/), [cppcheck](http://cppcheck.net/) y [pvs-studio](https://pvs-studio.com/). Luego, puede correr los testeos con: +En orden de realizar un análisis estático del sistema usted debe tener instalado [cppcheck](http://cppcheck.net/) y [pvs-studio](https://pvs-studio.com/). Luego, puede correrlos con: ```bash make test ``` +Por último, si quiere hacer un análisis dinámico (usando [valgrind](https://valgrind.org/)) debe ejecutar el programa `valAnalysis.sh` pasandole como argumento la carpeta con los archivos `.cnf` o directamente los archivos: + +```bash +./valAnalysis.sh $(CNF_FILES) +``` + # Autores - Barmasch, Juan Martín (61033) - Bellver, Ezequiel (61268) diff --git a/master.c b/master.c index 86a04eb..d9050e8 100644 --- a/master.c +++ b/master.c @@ -3,7 +3,6 @@ This is a personal academic project. Dear PVS-Studio, please check it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com */ #define _SVID_SOURCE 1 -//#define _DEFAULT_SOURCE 1 #define _XOPEN_SOURCE 500 #define _POSIX_C_SOURCE 2 @@ -39,7 +38,7 @@ int main(int argc, char *argv[]) { char * shmPointer, * shmStart; int totalSize = (argc - 1) * MAX_OUTPUT_SIZE; - int shmFd = createShm(totalSize); + int shmFd; printf("%d\n%d\n", argc - 1, getpid()); @@ -48,6 +47,7 @@ int main(int argc, char *argv[]) { blockSignal(); if (viewLinked) { + shmFd = createShm(totalSize); mapShm(&shmPointer, totalSize, shmFd); shmStart = shmPointer; } @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) { fd_set pipesOutputSet; FD_ZERO(&pipesOutputSet); - char buf[MAX_SIZE], flag; + char buf[MAX_SIZE], notFinished; int r, readBytes, count; if (tasks < slaveNum) { for (int k = tasks - 1; k < slaveNum; k++) { @@ -72,25 +72,25 @@ int main(int argc, char *argv[]) { } } do { - flag = 0; + notFinished = 0; FD_ZERO(&pipesOutputSet); for (int n = 0; n < slaveNum; n++) { if (pipesOutput[n][0] != -1) { FD_SET(pipesOutput[n][0], &pipesOutputSet); - flag = 1; + notFinished = 1; } } - if (flag) { + if (notFinished) { if ((count = select(pipesOutput[slaveNum - 1][1] + 1, &pipesOutputSet, NULL, NULL, NULL)) <= 0) printSystemError("select() -- ERROR"); for (r = 0; r < slaveNum && count > 0; r++) { if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet) && pipesOutput[r][0] != -1) { - if ((readBytes = read(pipesOutput[r][0], buf, MAX_SIZE)) < 0) + if ((readBytes = read(pipesOutput[r][0], buf, MAX_SIZE - 1)) < 0) printSystemError("read() -- ERROR"); buf[readBytes] = '\0'; - shmPointer += writeOutput(buf, outputFile, shmPointer, r); + shmPointer += writeOutput(buf, outputFile, shmPointer); count--; if (tasks < argc) { @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) { } } } - } while (flag); + } while (notFinished); if (fclose(outputFile) == EOF) printSystemError("fclose() -- ERROR"); @@ -110,7 +110,6 @@ int main(int argc, char *argv[]) { if (viewLinked) { waitForSignal(); terminateShm(SHM_NAME, shmFd, shmStart, totalSize); - closeSem(); } return EXIT_SUCCESS; @@ -135,7 +134,7 @@ char sendTask(char * fileName, int pipesInput[slaveNum][2], int slave) { } void closePipes(int pipesInput[][2], int pipesOutput[][2], int slave, fd_set * set) { -// FD_CLR(pipesOutput[slave][0], set); + FD_CLR(pipesOutput[slave][0], set); if (close(pipesOutput[slave][0]) < 0) printSystemError("close1() -- ERROR"); @@ -146,7 +145,7 @@ void closePipes(int pipesInput[][2], int pipesOutput[][2], int slave, fd_set * s pipesInput[slave][0] = -1; } -int writeOutput(char * output, FILE * outputFile, char * shmPointer, int i) { +int writeOutput(char * output, FILE * outputFile, char * shmPointer) { int length = strlen(output); if (fwrite(output, sizeof(char), length, outputFile) != length) diff --git a/master.h b/master.h index 7a0a944..74e9394 100644 --- a/master.h +++ b/master.h @@ -8,7 +8,7 @@ #define OUTPUT_NAME "outputFile.txt" void createPipesAndSlaves(int pipesOutput[][2], int pipesInput[][2]); -int writeOutput(char * output, FILE * outputFile, char * shmPointers, int cacaDeEzequiel); +int writeOutput(char * output, FILE * outputFile, char * shmPointers); void closePipes(int pipesInput[][2], int pipesOutput[][2], int slave, fd_set * set); char sendTask(char * fileName, int pipesInput[][2], int slave); void changeViewFlag(); diff --git a/shr_mem.c b/shr_mem.c index 480c8e9..fdf3938 100644 --- a/shr_mem.c +++ b/shr_mem.c @@ -15,13 +15,33 @@ PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include #include "shr_mem.h" -sem_t * sem = NULL; +sem_t * semEmpty = NULL; +sem_t * semOpen = NULL; + +void openSem(char * semName, sem_t ** sem) { + if (* sem == NULL) { + if ((* sem = sem_open(semName, O_CREAT | O_RDWR, S_IRWXU, 0)) == SEM_FAILED) + printSystemError("sem_open() -- ERROR"); + } +} + +void closeSem(char * semName, sem_t ** sem) { + if (sem_close(* sem) < 0) + printSystemError("sem_close() -- ERROR"); + if (sem_unlink(semName) < 0) + printSystemError("sem_unlink() -- ERROR"); +} int createShm(int totalSize) { + openSem(SEM_OPEN_NAME, &semOpen); + int fd; if ((fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRWXU)) < 0) printSystemError("shm_open() -- ERROR"); ftruncate(fd, totalSize); + + if (sem_post(semOpen) < 0) + printSystemError("sem_post() -- ERROR"); return fd; } @@ -31,12 +51,12 @@ void mapShm(char ** shmPointer, int totalSize, int fd) { } void writeShm(char * shmPointer, char * str, int len) { - openSem(); + openSem(SEM_EMPTY_NAME, &semEmpty); if (memcpy(shmPointer, str, len) == NULL) printError("memcpy() -- ERROR"); - if (sem_post(sem) < 0) + if (sem_post(semEmpty) < 0) printSystemError("sem_post() -- ERROR"); } @@ -47,20 +67,8 @@ void terminateShm(const char * name, int fd, char * shmPointer, int totalSize) { printSystemError("shm_unlink() -- ERROR"); if (close(fd) == -1) printSystemError("close() -- ERROR"); -} - -void openSem() { - if (sem == NULL) { - if ((sem = sem_open(SEM_NAME, O_CREAT | O_RDWR, S_IRWXU, 0)) == SEM_FAILED) - printSystemError("sem_open() -- ERROR"); - } -} - -void closeSem() { - if (sem_close(sem) < 0) - printSystemError("sem_close() -- ERROR"); - if (sem_unlink(SEM_NAME) < 0) - printSystemError("sem_unlink() -- ERROR"); + closeSem(SEM_OPEN_NAME, &semOpen); + closeSem(SEM_EMPTY_NAME, &semEmpty); } int copyShm(char * destPointer, char * srcPointer, int len) { @@ -74,15 +82,19 @@ int copyShm(char * destPointer, char * srcPointer, int len) { } int readShm(char * shmPointer, char * str, int len) { - openSem(); + openSem(SEM_EMPTY_NAME, &semEmpty); - if (sem_wait(sem) < 0) + if (sem_wait(semEmpty) < 0) printSystemError("sem_wait() -- ERROR"); return copyShm(str, shmPointer, len); } int openCreatedShm(char ** shmPointer, int totalSize) { + openSem(SEM_OPEN_NAME, &semOpen); + if (sem_wait(semOpen) < 0) + printSystemError("sem_wait() -- ERROR"); + int fd; if ((fd = shm_open(SHM_NAME, O_RDONLY, S_IRUSR)) < 0) printSystemError("shm_open() -- ERROR"); @@ -90,6 +102,7 @@ int openCreatedShm(char ** shmPointer, int totalSize) { if ((* shmPointer = mmap(0, totalSize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED){ printSystemError("mmap() -- ERROR"); } + return fd; } @@ -98,4 +111,6 @@ void closeCreatedShm(char * shmPointer, int totalSize, int fd) { printSystemError("munmap() -- ERROR"); if (close(fd) < 0) printSystemError("close() -- ERROR"); + closeSem(SEM_EMPTY_NAME, &semEmpty); + closeSem(SEM_OPEN_NAME, &semOpen); } diff --git a/shr_mem.h b/shr_mem.h index 6497bd1..61679ea 100644 --- a/shr_mem.h +++ b/shr_mem.h @@ -2,15 +2,14 @@ #define SHR_MEM #define SHM_NAME "/BottlerSHM" -#define SEM_NAME "/EmptySEM" +#define SEM_EMPTY_NAME "/EmptySEM" +#define SEM_OPEN_NAME "/OpenSEM" int createShm(int totalSize); void mapShm(char ** shmPointer, int totalSize, int fd); void writeShm(char * address, char * str, int len); int readShm(char * address, char * str, int len); void terminateShm(const char * name, int fd, char * shmPointer, int totalSize); -void openSem(); -void closeSem(); int openCreatedShm(char ** shmPointer, int totalSize); void closeCreatedShm(char * shmPointer, int totalSize, int fd); diff --git a/siglib.c b/siglib.c index b20f4ac..0fc839c 100644 --- a/siglib.c +++ b/siglib.c @@ -14,21 +14,19 @@ void addSignalHandler(void (*changeViewFlag)()) { sigAct.sa_handler = changeViewFlag; sigAct.sa_flags = 0; - if (sigaction(SIGUSR1, &sigAct, NULL) == -1) + if (sigaction(SIGSTART, &sigAct, NULL) == -1) printSystemError("sigaction() -- ERROR"); } -// Podríamos de última hacer que devuelvan el sigset para no tener dos distintos... - void blockSignal() { sigset_t blockedSet = {{0}}; - sigaddset(&blockedSet, SIGUSR1); + sigaddset(&blockedSet, SIGSTART); sigprocmask(SIG_BLOCK, &blockedSet, NULL); } void waitForSignal() { sigset_t set; - sigaddset(&set, SIGUSR2); + sigaddset(&set, SIGEND); int temp; sigwait(&set, &temp); } @@ -39,9 +37,9 @@ void sendSignal(int pid, int sig) { } void sendStartSignal(int pid) { - sendSignal(pid, SIGUSR1); + sendSignal(pid, SIGSTART); } void sendFinishSignal(int pid) { - sendSignal(pid, SIGUSR2); + sendSignal(pid, SIGEND); } diff --git a/siglib.h b/siglib.h index 3805199..06f4bf8 100644 --- a/siglib.h +++ b/siglib.h @@ -1,6 +1,9 @@ #ifndef SIGLIB_H #define SIGLIB_H +#define SIGSTART SIGUSR1 +#define SIGEND SIGUSR2 + void addSignalHandler(void (*changeViewFlag)()); void blockSignal(); void waitForSignal(); diff --git a/slave.c b/slave.c index 9db0a8d..f18ecab 100644 --- a/slave.c +++ b/slave.c @@ -23,7 +23,7 @@ int main(int argc, char *argv[]) { char output[MAX_SIZE], input[MAX_SIZE]; int readChars; - while ((readChars = read(STDIN_FILENO, input, MAX_SIZE)) != 0) { + while ((readChars = read(STDIN_FILENO, input, MAX_SIZE - 1)) != 0) { if (readChars < 0) printSystemError("slave.c -- read()"); input[readChars] = '\0'; @@ -45,9 +45,9 @@ void runCommand(char * inputLine, char * output) { // Pequeña ayuda para popen: https://stackoverflow.com/questions/646241/c-run-a-system-command-and-get-output FILE * fp = popen(command, "r"); if (fp == NULL) - printSystemError("slave.c -- popen()"); + printSystemError("slave.c -- popen()"); - size_t outputLength = fread(output, sizeof(char), MAX_SIZE, fp); + size_t outputLength = fread(output, sizeof(char), MAX_SIZE - 1, fp); output[outputLength] = '\0'; if (ferror(fp)) diff --git a/valAnalysis.sh b/valAnalysis.sh new file mode 100755 index 0000000..eb7ab3e --- /dev/null +++ b/valAnalysis.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if [ "$#" -lt 1 ]; then + echo "You must enter at least one CNF file or the folder that contains them!" && exit +fi + +firstParam="${1}" +filesCNF="${*}" + +if [ -d "$firstParam" ]; then + filesCNF="${firstParam}/*.cnf" + prevLastCharacter=$(echo -n "${firstParam}" | tail -c 1) + if [ "$prevLastCharacter" = "/" ]; then + filesCNF="${firstParam}*.cnf" + fi +fi + +valgrind --leak-check=full --track-origins=yes ./solve ${filesCNF} > valgrindSolve.output 2>&1 +./solve ${filesCNF} | valgrind --leak-check=full --show-leak-kinds=all ./view > valgrindView.output 2>&1 +ls ${filesCNF} | valgrind --leak-check=full ./slave.o > valgrindSlave.output 2>&1 diff --git a/view.c b/view.c index 9f04c1f..c4ee8d1 100644 --- a/view.c +++ b/view.c @@ -55,7 +55,6 @@ int main(int argc, char * argv[]) { closeCreatedShm(shmStart, totalSize, fd); sendFinishSignal(mPid); - closeSem(); return EXIT_SUCCESS; }