#define _GNU_SOURCE /* See feature_test_macros(7) */ #include /* Obtain O_* constant definitions */ #include #include #include #include #include #include "pa3.h" #include "dist.h" #include "child.h" #include "parent.h" #include "common.h" static char* app_name; void usage( FILE* output ) { fprintf(output, "usage: %s [--mutexl] -p \n", app_name); fprintf(output, "`X` must be int between 1 and %d\n", MAX_X); } int main(int argc, char* argv[]) { uint8_t i; int opt; dist_info_t info; app_name = argv[0]; struct option long_options[] = { {"mutexl", no_argument, &info.mutex, 1}, {0, 0, 0, 0} }; int option_index; info.x = 0; while ((opt = getopt_long(argc, argv, "p:", long_options, &option_index)) != -1) { switch (opt) { case 0: break; case 'p': info.x = atoi(optarg); break; default: /* '?' */ usage(stdout); exit(EXIT_FAILURE); } } if( info.x <= 0 || info.x > MAX_X ) { usage(stdout); exit(EXIT_FAILURE); } info.proccnt = info.x + 1; info.workers = info.x; info.parent_pid = getpid(); info.events_log = fopen( events_log, "w" ); info.pipes_log = fopen( pipes_log, "w" ); if( !info.pipes_log || !info.events_log ) { fprintf( stderr, "Events log or pipes log can't be open" ); return 1; } // open all (N * (N-1)) pipes for a full mesh topology for( i = 0; i < info.proccnt * (info.proccnt - 1); i++ ) { pipe2( info.pipes[i], O_NONBLOCK ); fprintf( info.pipes_log, "Opened pipe #%d (%d;%d)\n", i, info.pipes[i][0], info.pipes[i][1] ); } fclose( info.pipes_log ); for( i = 1; i < info.proccnt; i++ ) { pid_t pid = fork(); switch(pid) { case 0: /* Child branch */ child_workflow( &info, i ); exit(0); break; case -1: /* Error */ perror("fork"); return 1; default: break; } } parent_workflow( &info ); return 0; }