コード例 #1
0
ファイル: proxy.c プロジェクト: samzcmu/proxy
/* search_cell searches the cache and returns the cached
 * cell if found and returns NULL if the request cell is 
 * not cached. request_line is treated as the key. The 
 * strategy is to lock the cache for reading. reading from
 * the cache is permitted but writing to the cache is not. 
 * In the hit case, the cache is not unlocked until data is
 * writen to client. */
struct cache_cell *search_cell(char *request_line)
{
	struct cache_cell *ptr;
	
	/* locks the cache for reading */
	Pthread_rwlock_rdlock(&cache_lock);
	for (ptr = head; ptr != NULL; ptr = ptr->next)
	{
		if (!strcmp(ptr->request_line, request_line))
		{
			/* locks the mutex in the cell so that 
			 * other threads cannot access this cell. */
			Pthread_rwlock_wrlock(&(ptr->lock));
			Pthread_mutex_lock(&time_mutex);
			ptr->last_use = cache_time;
			cache_time++;
			Pthread_mutex_unlock(&time_mutex);
			Pthread_rwlock_unlock(&(ptr->lock));
			return ptr;
		}
	}
	/* unlocks the cache immediately in miss case */
	Pthread_rwlock_unlock(&cache_lock);
	return NULL;
}
コード例 #2
0
ファイル: proxy.c プロジェクト: samzcmu/proxy
/* search_cell_variant searches the cache but does not update*/
int search_cell_variant(char *request_line)
{
	struct cache_cell *ptr;
	
	Pthread_rwlock_rdlock(&cache_lock);
	for (ptr = head; ptr != NULL; ptr = ptr->next)
		if (!strcmp(ptr->request_line, request_line))
		{
			Pthread_rwlock_unlock(&cache_lock);
			return 1;
		}
	Pthread_rwlock_unlock(&cache_lock);
	return 0;
}
コード例 #3
0
ファイル: cache.c プロジェクト: gt-liu/Simple-HTTP-Proxy
/* Add a new cache item into the cache */
void add_cache_item(Cache_List *cache_list, char *uri, char *content, 
		unsigned int size)
{
	if (DEBUG_MODE) printf("  add_cache_item():\n");
	Cache_Item *cache_item = build_cache_item(uri, content, size);

	/* Abort caching if build_cache_item failed */
	if (cache_item == NULL) {
		if (DEBUG_MODE) printf("  add_cache_item() failed.\n");
		return;
	}

	Pthread_rwlock_wrlock(&cache_rwlock);	/* Lock for exlusive writing */
												/* Writing block */
	while (cache_list->unused_size < size) {
		evict_cache_item(cache_list);
	}
	insert_item_to_listhead(cache_list, cache_item);
	printf("\tResponse content (%u bytes) for URI: %s has been cached.\n",
			size, uri);
	print_cache_status(cache_list);
												/* End of writing block */
	Pthread_rwlock_unlock(&cache_rwlock);	/* Unlock writing */

	if (DEBUG_MODE) printf("  add_cache_item() finish.\n");
}
コード例 #4
0
ファイル: proxy.c プロジェクト: samzcmu/proxy
/* hit_handler handles hit case. It retrieves data from
 * cache and writes data to client. */
void hit_handler(int clientfd, struct cache_cell *cell,
				 struct client_request *request)
{
	if (rio_writen(clientfd, cell->content, cell->size) < 0)
		close_connection(request, clientfd, -1);
	Pthread_rwlock_unlock(&cache_lock);
	close_connection(request, clientfd, -1);
}
コード例 #5
0
ファイル: cache.c プロジェクト: gt-liu/Simple-HTTP-Proxy
/* Search the cache, if hit, copy content to the user buffer */
int search_and_get(Cache_List *cache_list, char *for_uri, void *usrbuf, 
		unsigned int *size) 
{
	Cache_Item *cache_item = NULL;

	Pthread_rwlock_rdlock(&cache_rwlock);	/* Lock for concurrent reading */

	cache_item = search_cache_item(cache_list, for_uri);	/* Reading */
	
	Pthread_rwlock_unlock(&cache_rwlock);	/* Unlocked reading */

	/* During this small transition period after releasing the reading lock 
	 * but before acquiring the writing lock, it is possible that the cache 
	 * item just found would be evicted by another writter who has been 
	 * waiting in the que. So it needs to be double checked before using. If 
	 * it is evicted, just treat it as a cache-miss.
	 */

	if (cache_item != NULL) {

		Pthread_rwlock_wrlock(&cache_rwlock);	/* Lock for exlusive writing */

		/* Check the item again in case it has been evicted instantaneously */
		if (strcmp(cache_item->uri, for_uri) == 0) {
			/* If it is still there, treat it as a cache-hit and use it */
			use_cache_item(cache_list, cache_item, usrbuf, size);
			print_cache_status(cache_list);

			Pthread_rwlock_unlock(&cache_rwlock);	/* Unlock writing */

			return 0;
		}
		else {
			/* If it is lost, treated it as a cache-miss */

			Pthread_rwlock_unlock(&cache_rwlock);	/* Unlock writing */

			return -1;
		}
	}
	else {
		/* Cache-miss */
		return -1;
	}
}
コード例 #6
0
ファイル: proxy.c プロジェクト: samzcmu/proxy
/* add_to_list takes a cell and adds that cell the
 * the cache list. It locks the cache for writing so
 * that other threads cannot modify it. */
void add_to_list(struct cache_cell *cell)
{
	/* locks the cache for writing */
	Pthread_rwlock_wrlock(&cache_lock);
	/* if there is enough space in the cache,
	 * no eviction is needed. */
	if (cache_size + cell->size <= MAX_CACHE_SIZE)
	{
		cell->next = head;
		if (head != NULL)
			head->previous = cell;
		head = cell;
		cache_size += cell->size;
		cell->last_use = cache_time;
		
		Pthread_mutex_lock(&time_mutex);
		cache_time++;
		Pthread_mutex_unlock(&time_mutex);
	}
	/* if there is not enough space in the cache,
	 * eviction is needed. */
	else
	{
		struct cache_cell *tmp_cell, *ptr;
		int tmp_last_use;
		
		/* remove elements from cache so that there is enough
		 * space in the cache. */
		while (!(cache_size + cell->size <= MAX_CACHE_SIZE))
		{
			tmp_last_use = cache_time + 1;
			for (ptr = head; ptr != NULL; ptr = ptr->next)
				if (ptr->last_use < tmp_last_use)
				{
					tmp_last_use = ptr->last_use;
					tmp_cell = ptr;
				}
			remove_from_list(tmp_cell);
		}
		
		/* add cell to cache */
		cell->next = head;
		if (head != NULL)
			head->previous = cell;
		head = cell;
		cache_size += cell->size;
		cell->last_use = cache_time;
		
		Pthread_mutex_lock(&time_mutex);
		cache_time++;
		Pthread_mutex_unlock(&time_mutex);
	}
	Pthread_rwlock_unlock(&cache_lock);
	return;
}
コード例 #7
0
/* include incr */
	void *
incr(void *arg)
{
	int		i;

	for (i = 0; i < nloop; i++) {
		Pthread_rwlock_wrlock(&shared.rwlock);
		shared.counter++;
		Pthread_rwlock_unlock(&shared.rwlock);
	}
	return(NULL);
}
コード例 #8
0
ファイル: test3.c プロジェクト: hechenyu/lib_code
void *thread1(void *arg)
{
	sleep(1);
	printf("%s: first child tries to obtain write lock\n", gf_time());
	Pthread_rwlock_wrlock(&rwlock);	/* this should block */
	printf("%s: first child obtains write lock\n", gf_time());

	sleep(2);
	Pthread_rwlock_unlock(&rwlock);
	printf("%s: first child releases write lock\n", gf_time());
	return NULL;
}
コード例 #9
0
ファイル: test3.c プロジェクト: hechenyu/lib_code
void *thread2(void *arg)
{
		/* 4second child */
	sleep(3);
	printf("%s: second child tries to obtain read lock\n", gf_time());
	Pthread_rwlock_rdlock(&rwlock);
	printf("%s: second child obtains read lock\n", gf_time());

	sleep(4);
	Pthread_rwlock_unlock(&rwlock);
	printf("%s: second child releases read lock\n", gf_time());
	return NULL;
}
コード例 #10
0
ファイル: test3.c プロジェクト: hechenyu/lib_code
int main()
{
	pthread_t tid1, tid2;

	Pthread_rwlock_wrlock(&rwlock);	/* parent read locks entire file */
	printf("%s: parent has write lock\n", gf_time());

	Pthread_create(&tid1, NULL, thread1, NULL);
	Pthread_create(&tid2, NULL, thread2, NULL);

	/* 4parent */
	sleep(5);
	Pthread_rwlock_unlock(&rwlock);
	printf("%s: parent releases write lock\n", gf_time());

	Pthread_join(tid1, NULL);
	Pthread_join(tid2, NULL);

	exit(0);
}
コード例 #11
0
	int
main(int argc, char **argv)
{
	int		i, nthreads;
	pthread_t	tid[MAXNTHREADS];

	if (argc != 3)
	{
		fprintf(stderr, "usage: incr_rwlock1 <#loops> <#threads>");
		exit(EXIT_FAILURE);
	}
	nloop = atoi(argv[1]);
	nthreads = min(atoi(argv[2]), MAXNTHREADS);

	/* obtain write lock */
	Pthread_rwlock_wrlock(&shared.rwlock);

	/* create all the threads */
	//Set_concurrency(nthreads);
	for (i = 0; i < nthreads; i++) {
		pthread_create(&tid[i], NULL, incr, NULL);
	}
	/* start the timer and release the write lock */
	Start_time();
	// 写锁释放之后,线程才可以运行
	Pthread_rwlock_unlock(&shared.rwlock);

	/* wait for all the threads */
	for (i = 0; i < nthreads; i++) {
		pthread_join(tid[i], NULL);
	}
	printf("microseconds: %.0f usec\n", Stop_time());
	if (shared.counter != nloop * nthreads)
		printf("error: counter = %ld\n", shared.counter);
	else
		printf("success: counter = %ld\n", shared.counter);


	exit(0);
}