void tt_cmd_analysis(command_t c, int cmd_num) // tt stand for time travel, analyze a command with its io { // this piece of code should go to next function initialize_dependent_array(); // create new cmd node command_list_t new_cmd = checked_malloc(sizeof(struct command_list)); new_cmd->c = c; new_cmd->file_list = NULL; new_cmd->num_of_dependent = 0; new_cmd->cmd_num = cmd_num; new_cmd->pid = 0; new_cmd-> next = NULL; // TODO // need to update look up table add_dependencies(c, new_cmd); //if(new_cmd->file_list == NULL) //printf("NULL\n"); //printf("Command dependencies list: "); io_list_t curr = new_cmd->file_list; int i = 0; while(curr != NULL && i != 10) { printf("%s ", curr->name); curr = curr->next; i++; } printf("\n"); }
/*! run this task */ __dllexport void TaskSchedulerTBB::Task::run (Thread& thread) // FIXME: avoid as many __dllexports as possible { /* try to run if not already stolen */ if (try_switch_state(INITIALIZED,DONE)) { Task* prevTask = thread.task; thread.task = this; try { if (thread.scheduler->cancellingException == nullptr) closure->execute(); } catch (...) { if (thread.scheduler->cancellingException == nullptr) thread.scheduler->cancellingException = std::current_exception(); } thread.task = prevTask; add_dependencies(-1); } /* steal until all dependencies have completed */ steal_loop(thread, [&] () { return dependencies>0; }, [&] () { while (thread.tasks.execute_local(thread,this)); }); /* now signal our parent task that we are finished */ if (parent) parent->add_dependencies(-1); }
void execute_command (command_t c, bool time_travel) { if(!time_travel) { exec_command(c); } else { command_t command = checked_malloc(sizeof(struct command)); memcpy(command, c, sizeof(struct command)); pthread_t tid; pthread_mutex_lock(&d_mutex); pthread_mutex_lock(&tc_mutex); int status = pthread_create(&tid, NULL, (void *) &execute_thread, command); if(status == 0) { thread_count++; add_dependencies(c, tid); pthread_mutex_unlock(&tc_mutex); pthread_mutex_unlock(&d_mutex); } else { error(1, status, "Error creating thread"); } } }
// add io file of c into dependencies list // recursive call to add all the file from sub-command to the dependencies list too void add_dependencies(command_t c, command_list_t cmd_list) { if (c->type == SIMPLE_COMMAND) { if(c->input != 0) { add_file_to_list(c->input, cmd_list, IS_READ); //if(cmd_list->file_list == NULL) //printf("NULL in add_dependencies\n"); } if(c->output != 0) { add_file_to_list(c->output, cmd_list, IS_WRITTEN); } int i = 1; while( c->u.word[i]!= NULL) { add_file_to_list(c->u.word[i], cmd_list, IS_READ); i++; } } else if (c->type == SUBSHELL_COMMAND) { if(c->input != 0) { add_file_to_list(c->input, cmd_list, IS_READ); } if(c->output != 0) { add_file_to_list(c->output, cmd_list, IS_WRITTEN); } add_dependencies(c->u.subshell_command, cmd_list); } else if (c->type == AND_COMMAND || c->type == OR_COMMAND || c->type == PIPE_COMMAND || c->type == SEQUENCE_COMMAND) { add_dependencies(c->u.command[0], cmd_list); add_dependencies(c->u.command[1], cmd_list); } else // unregconized command type { error(1, 0, "Error: unregconized command type %d", c->type); } }
command_t execute_parallel_stream (command_stream_t com) { command_node_t dep_head = NULL; command_t final_command = NULL; command_t command; //This function gets the command stream, we are reading the commands, one after the other. for(;;) { command = read_command_stream (com); //This means we finished reading the command if(!command) break; command_node_t curr_node = NULL; //We got a new command, so create a new command, initialize everything to null and new_node->c to the command read command_node_t new_node = checked_malloc(sizeof(struct command_node)); //Initializae function will initialize everything! initialize(new_node,command); //Then we simply need to add the dependencies to our list add_dependencies(new_node, command); final_command = command; //At this point the list has been populated and the dependencies have been added command_node_t current_node = dep_head; for(;;) { //This means there are no dependencie if(current_node == NULL) break; //If ther are dependencies found, we do comparisons and assign the current node accordingly helper(current_node, new_node->outputs, current_node->inputs, new_node); helper(current_node, current_node->outputs, new_node->inputs, new_node); curr_node = current_node; //Traversing the list current_node = current_node->next; } //This means means we can add to the waiting list if( curr_node == NULL) dep_head = new_node; else curr_node->next = new_node; } //dep head // While there's someone on the waiting list command_t retcommand = forkingandwaiting(dep_head,final_command); return retcommand; }
void path_slicert::operator()( const abstract_functionst &abstract_functions, abstract_counterexamplet &abstract_counterexample) { #ifdef DEBUG std::cout << "Path slicer START" << std::endl; #endif // build function map for(abstract_functionst::function_mapt::const_iterator f_it=abstract_functions.function_map.begin(); f_it!=abstract_functions.function_map.end(); f_it++) { for(abstract_programt::const_targett i_it=f_it->second.body.instructions.begin(); i_it!=f_it->second.body.instructions.end(); i_it++) function_map[i_it]=f_it; } string_sett dependencies; { // last one must be assertion assert(!abstract_counterexample.steps.empty()); assert(abstract_counterexample.steps.back().has_pc); // get concrete statement const goto_programt::instructiont &instruction= *abstract_counterexample.steps.back().pc->code.concrete_pc; assert(instruction.is_assert()); // fill up dependencies add_dependencies(instruction.guard, dependencies); } #ifdef DEBUG std::cout << "***********\n"; std::cout << dependencies; std::cout << "***********\n"; #endif // go backwards for(abstract_counterexamplet::stepst::reverse_iterator it=abstract_counterexample.steps.rbegin(); it!=abstract_counterexample.steps.rend(); it++) do_step(abstract_functions, dependencies, *it); }
void add_package(const PackageManifest& p, unsigned level, bool include_build, bool is_native) { TRACE_FUNCTION_F(p.name()); // TODO: If this is a proc macro, set `is_native` // If the package is already loaded for(auto& ent : m_list) { if(ent.package == &p && ent.native == is_native && ent.level >= level) { // NOTE: Only skip if this package will be built before we needed (i.e. the level is greater) return ; } // Keep searching (might already have a higher entry) } m_list.push_back({ &p, is_native, level }); add_dependencies(p, level, include_build, is_native); }
static int do_register(psys_pkg_t pkg, psys_err_t *err, jmp_buf *buf) { int ret; char *dpkgname = NULL; const char *dpkgarch; struct pkginfo *dpkg; psys_flist_t flist = NULL; char *filelist_path = NULL; char *md5list_path = NULL; set_error_handler(err, *buf, out); dpkgname = dpkg_name(psys_pkg_vendor(pkg), psys_pkg_name(pkg)); dpkg = findpackage(dpkgname); if (ensure_not_installed(dpkg, err)) { ret = -1; goto out; } if (ensure_dependencies_met(pkg, err)) { ret = -1; goto out; } blankpackage(dpkg); blankpackageperfile(&dpkg->installed); /* Name, Version */ dpkg->name = dpkgname; parseversion(&dpkg->installed.version, psys_pkg_version(pkg)); /* Architecture */ dpkgarch = dpkg_arch(psys_pkg_arch(pkg), err); if (!dpkgarch) { ret = -1; goto out; } dpkg->installed.architecture = dpkgarch; /* Description */ set_description(dpkg, pkg); /* * Maintainer * * FIXME: Our Maintainer value does not conform to the format * mandated by the Debian Policy Manual (which is "Name <E-Mail>"), * but this is better than not specifying a Maintainer at all * (which is a mandatory field) */ dpkg->installed.maintainer = nfstrsave(psys_pkg_vendor(pkg)); /* Priority */ dpkg->priority = pri_optional; /* Dependencies */ add_dependencies(dpkg, pkg); flist = psys_pkg_flist(pkg, err); if (!flist) { ret = -1; goto out; } /* Installed Size */ set_installed_size(dpkg, flist); /* File List */ filelist_path = create_file_list(dpkg, flist, err); if (!filelist_path) { ret = -1; goto out; } /* MD5SUMS List */ md5list_path = create_md5sums_list(dpkg, flist, err); if (!md5list_path) { ret = -1; goto out; } dpkg->want = want_install; dpkg->status = stat_installed; modstatdb_note(dpkg); ret = 0; out: if (md5list_path) { if (ret == -1) remove(md5list_path); free(md5list_path); } if (filelist_path) { if (ret == -1) remove(filelist_path); free(filelist_path); } if (flist) psys_flist_free(flist); return ret; }
void time_travel_mode(command_stream_t command_stream) // time travle main function { command_t command; int line_num = 1; initialize_dependent_array(); command_list_t head = NULL; // add dependencies and stuff while ((command = read_command_stream (command_stream))) { command_list_t new_cmd = checked_malloc(sizeof(struct command_list)); new_cmd->c = command; new_cmd->file_list = NULL; new_cmd->num_of_dependent = 0; new_cmd->cmd_num = line_num; new_cmd->pid = -10; // arbitrary number that not child and parent new_cmd-> next = NULL; // if number of cmd > current array size // update it if (line_num >= current_size) { current_size *= 2; size_t resize = current_size * sizeof(int); dependent_array = checked_grow_alloc(dependent_array, &resize); } add_dependencies(command, new_cmd); /* #ifdef DEBUG if(new_cmd->file_list == NULL) printf("NULL\n"); printf("Command dependencies list: "); io_list_t cur = new_cmd->file_list; int i = 0; while(cur != NULL && i != 10) { printf("%s ", cur->name); cur = cur->next; i++; } printf("\n"); #endif */ // traverse through the graph to add dependencies command_list_t last = head; command_list_t curr = head; while(curr != NULL) { analyze_dependencies(new_cmd, curr); last = curr; curr = curr->next; } if (last == NULL) // empty list { // add head head = new_cmd; } else { last->next = new_cmd; } line_num++; } /* if (head != NULL) printf("Head outside is Cmd %d\n", head->cmd_num); int i; for( i = 0; i < INIT_SIZE; i++) { int j; for (j = 0; j < INIT_SIZE; j++) { if (dependent_array[i][j] > 0) { printf("Cmd %d requires Cmd %d\n", i, j); } } } command_list_t curr = head; while(curr != NULL) { printf("Cmd %d requires %d cmds\n", curr->cmd_num, curr->num_of_dependent); curr = curr->next; } */ // Execute time travel // TODO //printf("Head is cmd %d\n", head->cmd_num); while(head != NULL) { command_list_t curr = head; while(curr != NULL) { //printf("curr cmd is %d and num of dependency is %d\n", curr->cmd_num, curr->num_of_dependent); // If current command/node does not require other cmd to be executed before // then execute current cmd if(curr->num_of_dependent == 0 && curr->pid < 1) { pid_t pid = fork(); if (pid < 0) error(1, 0, "Fork error: %s\n", strerror(errno)); else if ( pid == 0) // child { exec_command_helper(curr->c); _exit(curr->c->status); } else if ( pid > 0) // parent then save pid and wait { curr->pid = pid; } } curr = curr->next; } int status; pid_t curr_pid = waitpid(-1, &status, 0); // parent wait for chid // Remove node from graph and update look-up table and stuff command_list_t prev = NULL; command_list_t traverse = head; while(traverse != NULL) { if(traverse->pid == curr_pid) // same pid, this node has finish executing { //printf("Remove cmd %d\n", traverse->cmd_num); // update table int i; for(i = 0; i < line_num; i++) { dependent_array[i][traverse->cmd_num] = 0; } //remove from the list if(prev == NULL) // head { head = traverse->next; } else { prev->next = traverse->next; } // update dependency number on each node command_list_t update = head; while(update != NULL) { int sum = 0; int j; for(j=0; j<line_num; j++) { sum += dependent_array[update->cmd_num][j]; } //printf("Cmd %d now requires %d cmd\n", update->cmd_num, sum); update->num_of_dependent = sum; update = update->next; } //printf("before break\n"); break; //printf("after break\n"); } prev = traverse; traverse = traverse->next; } //printf("Head is cmd %d\n", head->cmd_num); //if(head != NULL) // head = head->next; } }
//All the dependencies are added to the node and all the dependencies of the subcommand are added to the node. void add_dependencies(command_node_t node, command_t command) { //We get the command node and the command here. //First lets check if the input is not = 0, if not that means it is a command with an input and we need to take care of it. if(command->input != 0) { if(node->inputs == NULL) { int size = sizeof(node_t); node_t head = checked_malloc(size); //We assign the head of our node_t struct to the input head->word = command->input; //Next is set to null head->next = NULL; node->inputs = head; } else // This means that input is not null { //We need to add the word to the list. We iterate through the noed struct till we reach the //same input as the command input while(strcmp(node->inputs->word, command->input) == 0) { if(node->inputs->next == NULL) { node->inputs->next = checked_malloc(sizeof(node_t)); node->inputs->next->word = command->input; // Word getting added node->inputs->next->next = NULL; } else //continue to loop with the next word in the node node->inputs=node->inputs->next; } } } //Time for output. check if the command has an output if(command->output != 0) { if(node->outputs == NULL) { int size = sizeof(node_t); node_t head = checked_malloc(size); head->word = command->output; head->next = NULL; node->outputs = head; } else // This means that input is not null { //We need to add the word to the list. We iterate through the noed struct till we reach the //same input as the command input while(strcmp(node->outputs->word, command->output) == 0) { if(node->outputs->next == NULL) { node->outputs->next = checked_malloc(sizeof(node_t)); node->outputs->next->word = command->output; // Word getting added node->outputs->next->next = NULL; } else //continue to loop with the next word in the node node->outputs=node->outputs->next; } } } int temp = 0; //At this point we are done adding the input and output of the command to the structs. Let's see what kind of command it is //and do things accordingly if(command->type == AND_COMMAND || command->type == OR_COMMAND || command->type == SEQUENCE_COMMAND || command->type == PIPE_COMMAND) { add_dependencies(node, command->u.command[0]); //Above mentioned commands could have input and out, so have to //to add dependencies both for input and output. That is the left side of a pipe could itself be command. //So we need to take care of those dependecies as well. add_dependencies(node, command->u.command[1]); } //If the command is a simple command then it is a different case. we do not need to call the add dependencies function again //Because simple command will not have a subcommand if(command->type == SIMPLE_COMMAND ) { temp = 1; while(command->u.word[temp] != NULL) { if(node->inputs == NULL) { //Making the input of the node point to the head of node_t int size = sizeof(node_t); node_t head = checked_malloc(size); head->word = command->u.word[temp]; head->next = NULL; node->inputs = head; } else { //We need to add the word to the list. We iterate through the noed struct till we reach the //same input as the command input while(strcmp(node->inputs->word, command->u.word[temp]) == 0) { if(node->inputs->next == NULL) { node->inputs->next = checked_malloc(sizeof(node_t)); node->inputs->next->word = command->u.word[temp]; // Word getting added node->inputs->next->next = NULL; } else //traverse the list( node struct) node->inputs = node->inputs->next; } if(node->outputs == NULL) { //Making the input of the node point to the head of node_t int size = sizeof(node_t); node_t head = checked_malloc(size); head->word = command->u.word[temp]; head->next = NULL; node->outputs = head; } else { //We need to add the word to the list. We iterate through the noed struct till we reach the //same input as the command input while(strcmp(node->outputs->word, command->u.word[temp]) == 0) { if(node->outputs->next == NULL) { node->outputs->next = checked_malloc(sizeof(node_t)); node->outputs->next->word = command->u.word[temp]; // Word getting added node->outputs->next->next = NULL; } else //traverse the list( node struct) node->outputs = node->outputs->next; } } } temp++; } } }
void path_slicert::do_step( const abstract_functionst &abstract_functions, string_sett &dependencies, abstract_stept &step) { if(!step.has_pc) return; // get abstract statement const abstract_programt::instructiont &a_instruction= *step.pc; // get concrete statement const goto_programt::instructiont &c_instruction= *a_instruction.code.concrete_pc; if(c_instruction.is_assign()) { assert(c_instruction.code.operands().size()==2); const exprt &lhs=c_instruction.code.op0(); const exprt &rhs=c_instruction.code.op1(); if(depends_lhs(lhs, dependencies)) add_dependencies(rhs, dependencies); else step.relevant=false; } else if(c_instruction.is_other()) { const irep_idt &statement= c_instruction.code.get_statement(); // check if it's an assignment if(statement=="init") { assert(c_instruction.code.operands().size()==2); const exprt &lhs=c_instruction.code.op0(); const exprt &rhs=c_instruction.code.op1(); if(depends_lhs(lhs, dependencies)) add_dependencies(rhs, dependencies); else step.relevant=false; } else if(statement==ID_assign) { // shouldn't be here assert(false); } else if(statement==ID_expression) { // these don't do anything step.relevant=false; } else if(statement==ID_printf) { // doesn't do anything relevant } else { // arg! throw "path_slicert: unknown statement: `"+id2string(statement)+"'"; } } else if(c_instruction.is_decl()) { assert(c_instruction.code.operands().size()==1); if(!depends_lhs(c_instruction.code.op0(), dependencies)) step.relevant=false; } else if(c_instruction.is_assume()) { add_dependencies(c_instruction.guard, dependencies); } else if(c_instruction.is_goto()) { if(c_instruction.guard.is_constant()) { // ignore } else if(depends(c_instruction.guard, dependencies)) { // it depends! add more dependencies add_dependencies(c_instruction.guard, dependencies); } else { // the abstract one must be the same goto assert(a_instruction.is_goto()); // find out if we merge back to this on all paths assert(a_instruction.targets.size()==1); abstract_programt::const_targett dest; if(step.branch_taken) dest=a_instruction.targets.front(); else { dest=step.pc; dest++; } if(all_merge_to(abstract_functions, dependencies, step.pc, dest)) { step.relevant=false; #ifdef DEBUG std::cout << "GOTO is not relevant\n"; #endif } else { #ifdef DEBUG std::cout << "GOTO is relevant\n"; #endif add_dependencies(c_instruction.guard, dependencies); } } } else if(c_instruction.is_location() || c_instruction.is_end_function()) step.relevant=false; #ifdef DEBUG if(step.relevant) std::cout << "RELEVANT\n"; else std::cout << "NOT RELEVANT\n"; std::cout << "*******\n"; std::cout << dependencies; std::cout << "*******\n"; #endif }