/** * Open and lock the given file, ensuring that no deadlock will occur now or in the future over contention for this file. * If opening this file immediately would cause a deadlock, this method will block until the file can be safely opened and locked. * If the file cannot be opened, NULL is returned. * * Parameters: path - path to the file you wish to open and lock * mode - mode in which to open the file (same as the argument to fopen()) * Returns: A file pointer to the opened file or NULL on error */ FILE *sfs_fopen(char *path, char *mode) { mutex_lock(memory); // Turn claim edge to assignment edge node *resource = find_file_node(memory, path); node *process = find_process_node(memory, getpid()); if(resource == NULL || process == NULL) {\ mutex_unlock(memory); return NULL; } delete_out_edge(memory, process, resource); add_out_edge(memory, resource, process); // While a cycle exists while(cycle_exists(memory)) { // Convert back to claim edge delete_out_edge(memory, resource, process); add_out_edge(memory, process, resource); // Wait pthread_cond_wait(get_cycle_cond(memory), get_lock(memory)); // Add edge back delete_out_edge(memory, process, resource); add_out_edge(memory, resource, process); } // Upon getting the lock and assuring no cycle, open the file FILE *res = fopen(path, mode); resource->fp = res; mutex_unlock(memory); return res; }
/** * Close and unlock a file which was previously opened and locked using sfs_fopen. * * Parameters: fp - file pointer to the file which you wish to close * Returns: 1 on success, 0 otherwise */ int sfs_fclose(FILE *fp) { if(fp == NULL) return 0; mutex_lock(memory); // Find this process and file resource node *resource = find_file_node_fp(memory, fp); node *process = find_process_node(memory, getpid()); if(resource == NULL || process == NULL) { mutex_unlock(memory); return 0; } resource->fp = NULL; // Convert back to claim edge delete_out_edge(memory, resource, process); add_out_edge(memory, process, resource); // Close file int result = fclose(fp); // Broadcast conditional variable pthread_cond_broadcast(get_cycle_cond(memory)); mutex_unlock(memory); return (result != EOF); }
void Graph::readGraph() { FILE *fin = fopen((folder+graph_file).c_str(), "r"); ASSERT(fin != NULL); int readCnt = 0; for(int i=0; i<m; i++) { readCnt++; //cout << readCnt << endl; int a, b; double p; int c = fscanf(fin, "%d%d%lf", &a, &b, &p); //cout << a << ", " << b << ", " << p << endl; ASSERT(c == 3); ASSERTT(c == 3, a, b, p, c); ASSERT(a < n); ASSERT(b < n); hasNode[a]=true; hasNode[b]=true; add_in_edge(a, b, p); add_out_edge(a, b, p); } if(readCnt != m) ExitMessage("[error] m != number of edges in file " + graph_file); fclose(fin); cout << "[info] finish reading graph data" << endl; }
void Graph::readGraph_v2() { string fileName = folder + graph_file; ifstream myfile (fileName.c_str(), ios::in); string delim = " \t"; if (myfile.is_open()) { while (! myfile.eof() ) { std::string line; getline (myfile,line); if (line.empty()) continue; std::string::size_type pos = line.find_first_of(delim); int prevpos = 0; string str = line.substr(prevpos, pos-prevpos); int a = std::stoi(str); //cout << a << endl; prevpos = line.find_first_not_of(delim, pos); pos = line.find_first_of(delim, prevpos); int b = std::stoi(line.substr(prevpos, pos-prevpos)); //cout << b << endl; double p = 0; prevpos = line.find_first_not_of(delim, pos); pos = line.find_first_of(delim, prevpos); if (pos == string::npos) p = std::stod(line.substr(prevpos)); else p = std::stod(line.substr(prevpos, pos-prevpos)); //cout << a << ", " << b << ", " << p << endl; ASSERT(a < n); ASSERT(b < n); hasNode[a]=true; hasNode[b]=true; add_in_edge(a, b, p); add_out_edge(a, b, p); } myfile.close(); } else { cout << "[error] can't open graph file " << fileName << endl; exit(1); } cout << "[info] finish reading graph data" << endl; }
/** * End this process's access to the shared files. All files opened by this process are closed and unlocked, * this process is removed from the system, and the shared memory segment is detached. * * If the current process wishes to use this library any further (except calling sfs_destroy), it must re-call sfs_declare(). * * Parameters: sys_key - the unique ID of the shared memory segment used in sfs_init and sfs_declare * Returns: 1 on success, 0 otherwise */ int sfs_leave(int sys_key) { mutex_lock (memory); // Remove this process from overall list node* cur_process = memory->processes; node* prev_process = NULL; while(cur_process != NULL && cur_process->pid != getpid()) { prev_process = cur_process; cur_process = cur_process->next; } // Remove the process if(prev_process != NULL) prev_process->next = cur_process->next; else memory->processes = cur_process->next; // Loop through our open files and close them // For each resource node *cur_resource = memory->resources; while(cur_resource != NULL) { // If we are the target of this resource's outgoing edge if(cur_resource->out_edges != NULL && cur_resource->out_edges->data == cur_process) { // Close file and flip edge back delete_out_edge(memory, cur_resource, cur_process); add_out_edge(memory, cur_process, cur_resource); // Close file int result = fclose(cur_resource->fp); if(result == EOF) { mutex_unlock(memory); return 0; } } cur_resource = cur_resource->next; } // Loop through this process's files and delete ones with no other users // For each outgoing edge node *cur_resource_list = cur_process->out_edges; while(cur_resource_list != NULL) { cur_resource = cur_resource_list->data; // If has an outgoing edge to someone else, go on if(cur_resource->out_edges == NULL) { // Otherwise, loop through all processes and search for outgoing edges to resource // If none are found, remove this resource if(!resource_has_incoming_edges(memory, cur_resource)) { // delete this node (remove from resource list and free it) delete_resource_node(memory, cur_resource); } } cur_resource_list = cur_resource_list->next; } // Remove this process's process node free_node(memory, cur_process); // Broadcast conditional variable pthread_cond_broadcast(get_cycle_cond(memory)); mutex_unlock(memory); int result = shmdt(shared_memory); // Update local stuff memory = NULL; shared_memory = NULL; segment_id = -1; if(result == -1) return 0; return 1; }