예제 #1
0
void *reader(void *prm)
{
	char *entry;
	int num = (int) prm;
	int total = 0;
	int rc;

	cp_mutex_lock(&start_mutex);
	while (!running)
		cp_cond_wait(&start_cond, &start_mutex);
	rc = cp_mutex_unlock(&start_mutex);
	if (rc == 0) write_err("reader");
	while (running || cp_hashtable_count(t[num]) > 0)
	{
		cp_mutex_lock(&lock[num]);
		while (running && cp_list_is_empty(tl[num]))
			cp_cond_wait(&cond[num], &lock[num]);

		while ((entry = (char *) cp_list_remove_head(tl[num])))
		{
			cp_hashtable_remove(t[num], entry);
			if (!silent)
				printf("[%d]: (%ld) entry: %s\n", num, cp_hashtable_count(t[num]), entry);
			total++;
			free(entry);
		}
		cp_mutex_unlock(&lock[num]);
	}

	printf("\n (-) reader %d: processed %d entries\n", num, total);
	return NULL;
}
예제 #2
0
void *writer(void *prm)
{
	int i, num;
	long count = (long) prm;
	char kbuf[30];
	char *entry;

	cp_mutex_lock(&start_mutex);
	while (!running)
		cp_cond_wait(&start_cond, &start_mutex);
	cp_mutex_unlock(&start_mutex);
	for (i = 0; i < count; i++)
	{
		sprintf(kbuf, "ENTRY %d", i);
		entry = strdup(kbuf);
		num = i % COUNT;
		if (!silent)
			printf("writing (%d): %s\n", num, entry);

		cp_mutex_lock(&lock[i % COUNT]);
		cp_hashtable_put(t[num], entry, entry);
		cp_list_append(tl[num], entry);
		cp_cond_broadcast(&cond[i % COUNT]);
		cp_mutex_unlock(&lock[i % COUNT]);
	}

	return NULL;
}
예제 #3
0
int cp_pooled_thread_run_task(cp_pooled_thread *pt, 
						      cp_thread_action action, 
							  void *prm)
{
#ifdef __TRACE__
	DEBUGMSG("cp_pooled_thread_run_task: action %lx, prm %lx\n", 
			 (long) action, (long) prm);
#endif

	pt->action = action;
	pt->action_prm = prm;

	if (action == NULL)
	{
		cp_error(CP_INVALID_FUNCTION_POINTER, "missing thread function");
		return CP_INVALID_FUNCTION_POINTER;
	}

	/* signal thread to run */
	cp_mutex_lock(pt->suspend_lock);
	pt->wait = 0;
	cp_cond_signal(pt->suspend_cond);
	cp_mutex_unlock(pt->suspend_lock);

	return 0;
}
예제 #4
0
cp_thread *cp_thread_pool_get_impl(cp_thread_pool *pool, 
                                   cp_thread_action action, 
                                   void *action_prm, 
                                   cp_thread_stop_fn stop_fn,
                                   void *stop_prm,
                                   int block)
{
	cp_pooled_thread *pt = NULL;
	cp_mutex_lock(pool->pool_lock);
		
#ifdef __TRACE__
	DEBUGMSG("cp_thread_pool_get_impl (%d) pool size = %d max size = %d\n", block, pool->size, pool->max_size);
#endif

	pt = cp_list_remove_head(pool->free_pool);
	if (pt == NULL)
	{
		if (pool->size < pool->max_size)
		{
			pt = cp_pooled_thread_create(pool);
			if (pt)
				pool->size++;
		}

		if (pt == NULL) /* no thread available and poolsize == max */
		{
			if (!block)  /* asked not to block, return NULL */
			{
				cp_mutex_unlock(pool->pool_lock);
				return NULL;
			}

			/* wait for a thread to be released to the pool */
#ifdef _WINDOWS
			cp_mutex_unlock(pool->pool_lock);
#endif
			while (pool->running && cp_list_is_empty(pool->free_pool))
				cp_cond_wait(pool->pool_cond, pool->pool_lock);

			if (pool->running)
				pt = cp_list_remove_head(pool->free_pool);

			if (pt == NULL) /* shouldn't be happening except for shutdown */
			{
				cp_mutex_unlock(pool->pool_lock);
				return NULL;
			}
		}
	}

	cp_hashlist_append(pool->in_use, &pt->id, pt);
	cp_mutex_unlock(pool->pool_lock);

	cp_pooled_thread_run_stoppable_task(pt, action, action_prm, stop_fn, stop_prm);

	return pt->worker;
}
예제 #5
0
파일: heap.c 프로젝트: braveyly/codefactory
int cp_heap_lock(cp_heap *heap)
{
    int rc;
    if ((heap->mode & COLLECTION_MODE_NOSYNC)) return EINVAL;
    if ((rc = cp_mutex_lock(heap->lock))) return rc;
    heap->txowner = cp_thread_self();
    heap->mode |= COLLECTION_MODE_IN_TRANSACTION;
    return 0;
}
예제 #6
0
파일: heap.c 프로젝트: braveyly/codefactory
int cp_heap_txlock(cp_heap *heap)
{
    if (heap->mode & COLLECTION_MODE_NOSYNC) return 0;
    if (heap->mode & COLLECTION_MODE_IN_TRANSACTION)
    {
        cp_thread self = cp_thread_self();
        if (cp_thread_equal(self, heap->txowner)) return 0;
    }
    errno = 0;
    return cp_mutex_lock(heap->lock);
}
예제 #7
0
static int cp_thread_pool_set_available(cp_thread_pool *pool, 
		                                cp_pooled_thread *thread)
{
	cp_mutex_lock(pool->pool_lock);
	cp_hashlist_remove(pool->in_use, &thread->id);
	cp_list_append(pool->free_pool, thread);
//	pool->size--;
 	cp_cond_signal(pool->pool_cond);
	cp_mutex_unlock(pool->pool_lock);

	return 0;
}
예제 #8
0
int cp_thread_pool_wait(cp_thread_pool *pool)
{
	while (cp_hashlist_item_count(pool->in_use) && pool->running)
	{
		cp_mutex_lock(pool->pool_lock);
		cp_cond_wait(pool->pool_cond, pool->pool_lock);

		if (pool->running && 
			cp_hashlist_item_count(pool->in_use)) /* wake up someone else */
			cp_cond_signal(pool->pool_cond);
		cp_mutex_unlock(pool->pool_lock);
	}

	return 0;
}
예제 #9
0
void *cp_pooled_thread_run(void *prm)
{
	cp_pooled_thread *pt = (cp_pooled_thread *) prm;

#ifdef __TRACE__
	DEBUGMSG("cp_pooled_thread (%lx) starts", (long) pt);
#endif

	while (!pt->done && pt->owner->running)
	{
		cp_mutex_lock(pt->suspend_lock);
		while (pt->wait && (!pt->done) && pt->owner->running)
			cp_cond_wait(pt->suspend_cond, pt->suspend_lock);
		cp_mutex_unlock(pt->suspend_lock);

		if (pt->done || !pt->owner->running) break;
#ifdef __TRACE__
		DEBUGMSG("cp_pooled_thread_run: action is %lX, action_prm is %lX", pt->action, pt->action_prm);
#endif
		if (pt->action) /* run user defined function if set */
		{
#ifdef __TRACE__
			DEBUGMSG("pooled thread (%lX) handles action (%lX)", (long) pt, (long) pt->action);
#endif
			(*pt->action)(pt->action_prm);
		}
		if (pt->done || !pt->owner->running) break;

		pt->wait = 1;
		/* performed work, notify pool */
		cp_thread_pool_set_available(pt->owner, pt);
	}

#ifdef __TRACE__
	DEBUGMSG("cp_pooled_thread (%lx) exits", (long) pt);
#endif

	cp_pooled_thread_destroy(pt);

	return NULL;
}
예제 #10
0
int cp_pooled_thread_stop(cp_pooled_thread *pt)
{
	int rc = 0;

	cp_mutex_lock(pt->suspend_lock);
	pt->action = NULL;
	if (pt->stop_fn)
	{
		rc = pt->stop_prm ? (*pt->stop_fn)(pt->stop_prm) : 
							  (*pt->stop_fn)(pt->action_prm);
	}

	pt->done = 1;
	pt->wait = 0;

	cp_cond_signal(pt->suspend_cond);
	cp_mutex_unlock(pt->suspend_lock);

//	cp_thread_join(*pt->worker, NULL); //~~ rc

	return rc;
}
예제 #11
0
int main(int argc, char *argv[])
{
	int i;
	cp_thread w[COUNT];
	cp_thread r[COUNT];
	long total;
	int rc;

	if (argc > 1) silent = atoi(argv[1]);

	for (i = 0; i < COUNT; i++)
	{
		rc = cp_mutex_init(&lock[i], NULL);
		cp_cond_init(&cond[i], NULL);
		t[i] = cp_hashtable_create(10, cp_hash_string, cp_hash_compare_string);
		tl[i] = cp_list_create();
	}


	rc = cp_mutex_init(&start_mutex, NULL);
	cp_cond_init(&start_cond, NULL);

	for (i = 0; i < COUNT; i++)
		cp_thread_create(r[i], NULL, reader, (void *) i);

	for (i = 0; i < COUNT; i++)
		cp_thread_create(w[i], NULL, writer, (void *) INSERTS);

	printf("press enter\n");
	getchar();
	cp_mutex_lock(&start_mutex);
	running = 1;
	total = time(NULL);
	cp_cond_broadcast(&start_cond);
	rc = cp_mutex_unlock(&start_mutex);
	if (rc == 0) write_err("MAIN");
	for (i = 0; i < COUNT; i++)
		cp_thread_join(w[i], NULL);
	running = 0;

	for (i = 0; i < COUNT; i++)
	{
		cp_mutex_lock(&lock[i]);
		cp_cond_broadcast(&cond[i]);
		cp_mutex_unlock(&lock[i]);
		cp_thread_join(r[i], NULL);
	}

	total = time(NULL) - total;

	printf("\ndone in %ld seconds. tables should be empty now. press enter.\n",
			total);
	getchar();

	for (i = 0; i < COUNT; i++)
	{
		printf("table %d: %ld items\n", i, cp_hashtable_count(t[i]));
		cp_hashtable_destroy(t[i]);
		printf("list %d: %ld items\n", i, cp_list_item_count(tl[i]));
		while (cp_list_item_count(tl[i]))
		{
			char *leftover = cp_list_remove_head(tl[i]);
			printf("       * %s\n", leftover);
		}
		cp_list_destroy(tl[i]);
	}

	printf("deleted them tables. press enter.\n");
	getchar();

	printf("bye.\n");
	return 0;
}