Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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);
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
/**
 * 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;
}