/** * @file supervisor.c * @date 2018-05-21 * * @brief Server program which reads solutions and orders them. */ #include "common.h" static const char *pname; struct circ_buf *shared; struct sigaction sa; static int bestSolution[MAX_ITEMS]; static volatile sig_atomic_t quit = 0; static void sig_handler(int signum) { quit = 1; } void usage(void) { fprintf(stderr, "SYNOPSIS\n" "\tsupervisor\n"); exit(EXIT_FAILURE); } void initCircBuf() { shared->quit = 0; for (int i = 0; i < CIRC_BUF_SIZE; i++) { shared->data[i] = -1; } return; } void getSolution(sem_t sUsedSpace, sem_t sFreeSpace, int *solution) { for (int i = 0; i < MAX_ITEMS; i++) { solution[i] = -1; } if (shared->head == -1) { sem_wait(&sUsedSpace); shared->head = (shared->head + 1) % MAX_ITEMS; sem_post(&sFreeSpace); } else { int i = 0; while (shared->head != -1) { sem_wait(&sUsedSpace); solution[i] = shared->head; shared->head = (shared->head + 1) % MAX_ITEMS; sem_post(&sFreeSpace); i++; } } // Code for testing if new solution is better than old int bestSolutionLength = 0; int newSolutionLength = 0; for (int i = 0; i < MAX_ITEMS; i++) { if ((bestSolution[i] == -1) && (i != 0)) { bestSolutionLength = i+1; break; } } for (int i = 0; i < MAX_ITEMS; i++) { if ((solution[i] == -1) && (i != 0)) { newSolutionLength = i+1; break; } } if (newSolutionLength == 0) { printf("[%s] The graph is acyclic!\n", pname); return; } if (newSolutionLength < bestSolutionLength) { // Set all entries of bestSolution to -1 for (int i = 0; i < bestSolutionLength; i++) { bestSolution[i] = -1; } // Copy all entries from solution to bestSolution for (int i = 0; i < newSolutionLength; i++) { bestSolution[i] = solution[i]; } printf("[%s] Solution with %d edges:", pname, newSolutionLength/2); for (int i = 0; i < newSolutionLength; i += 2) { printf(" %d-%d", bestSolution[i], bestSolution[i+1]); } printf("\n"); } } int main(int argc, char *argv[]) { if (argc != 1) usage(); pname = argv[0]; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_handler; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); int shmfd = shm_open(SHM_NAME, O_RDWR | O_CREAT, PERMISSION); if (shmfd == -1) { perror(pname); exit(EXIT_FAILURE); } if (ftruncate(shmfd, sizeof(*shared)) == -1) { perror(pname); exit(EXIT_FAILURE); } shared = mmap(NULL, sizeof(*shared), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); if (shared == MAP_FAILED) { perror(pname); exit(EXIT_FAILURE); } sem_t *sFreeSpace = sem_open(SEM_FREE_SPACE, O_CREAT | O_EXCL, PERMISSION, MAX_ITEMS); sem_t *sUsedSpace = sem_open(SEM_USED_SPACE, O_CREAT | O_EXCL, PERMISSION, 0); initCircBuf(); while (quit == 0) { int solution[MAX_ITEMS]; getSolution(*sUsedSpace, *sFreeSpace, solution); } shared->quit = 1; if (munmap(shared, sizeof(*shared)) == -1) { perror("munmap"); exit(EXIT_FAILURE); } close(shmfd); if (shm_unlink(SHM_NAME) == -1) { perror("shm_unlink"); exit(EXIT_FAILURE); } sem_close(sUsedSpace); sem_close(sFreeSpace); sem_unlink(SEM_USED_SPACE); sem_unlink(SEM_FREE_SPACE); return 0; }