int execute_all_nodes(node_t* nodes, int num) { int totalNodes = num; int numNodesFinished = 0; int i; int j; while(numNodesFinished < totalNodes) { //check if parents are done, then change state to ready for(i = 0; i < num ; i++ ) { if (nodes[i].status == INELIGIBLE) { if (nodes[i].num_parents_finished == nodes[i].num_parents) nodes[i].status = READY; } } //For them to fork concurrently first before waiting for(i = 0; i<num;i++) { if (nodes[i].status == READY) { pid_t child_pid; child_pid = fork(); if (child_pid < 0) { perror("There was an error forking the process!"); return -1; } if (child_pid == 0) { //is child if (execute_node(nodes[i]) < 0) { perror("There was an error running execute_node."); return -1; } } else { //main thread has child_pid, pid for the child. nodes[i].status = RUNNING; nodes[i].pid = child_pid; } } } for(i = 0; i<num;i++) { if (nodes[i].status == RUNNING ) { if (wait(NULL) == -1) { perror("There was an error waiting for the process to end!"); return -1; } else { //successfully waited for forked child to complete nodes[i].status = FINISHED; numNodesFinished++; //update nodes's childs for(j=0;j < nodes[i].num_children; j++) { nodes[nodes[i].children[j]].num_parents_finished++; } } } } } return 0; }
void execute_parallel(command_stream_t commandStream) { graphnode_list_t adjList = create_list(); command_t cmd; while ((cmd = read_command_stream (commandStream))) { string_list_t readList = create_list(); string_list_t writeList = create_list(); build_io_lists(cmd, readList, writeList); add_to_graph(adjList, cmd, readList, writeList); } int adjListSize = size(adjList); sharedFinished = mmap(NULL, adjListSize * sizeof(bool), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); int i; for (i = 0; i < adjListSize; i++) { sharedFinished[i] = false; } unsigned int numStartedProcesses = 0; i = 0; node_t currNode = adjList->head; while (currNode) { graphnode_t currGraphNode = currNode->item; currGraphNode->aid = i; if (numStartedProcesses >= MAX_PROCS) { // wait for a spot to open up wait(NULL); } pid_t p = fork(); if (p == 0) { execute_node(currGraphNode); } else if (p > 0) { numStartedProcesses++; currNode = currNode->next; } i++; } while (true) { int status; pid_t done = wait(&status); if (done == -1 && errno == ECHILD) { break; } } }