Esempio n. 1
0
static mono_native_thread_return_t
thread_func (void *thread_data)
{
	thread_init_func (thread_data);

	mono_mutex_lock (&lock);
	for (;;) {
		/*
		 * It's important that we check the continue idle flag with the lock held.
		 * Suppose we didn't check with the lock held, and the result is FALSE.  The
		 * main thread might then set continue idle and signal us before we can take
		 * the lock, and we'd lose the signal.
		 */
		gboolean do_idle = continue_idle_job ();
		SgenThreadPoolJob *job = get_job_and_set_in_progress ();

		if (!job && !do_idle) {
			/*
			 * pthread_cond_wait() can return successfully despite the condition
			 * not being signalled, so we have to run this in a loop until we
			 * really have work to do.
			 */
			mono_cond_wait (&work_cond, &lock);
			continue;
		}

		mono_mutex_unlock (&lock);

		if (job) {
			job->func (thread_data, job);

			mono_mutex_lock (&lock);

			SGEN_ASSERT (0, job->state == STATE_IN_PROGRESS, "The job should still be in progress.");
			job->state = STATE_DONE;
			remove_job (job);
			/*
			 * Only the main GC thread will ever wait on the done condition, so we don't
			 * have to broadcast.
			 */
			mono_cond_signal (&done_cond);
		} else {
			SGEN_ASSERT (0, do_idle, "Why did we unlock if we still have to wait for idle?");
			SGEN_ASSERT (0, idle_job_func, "Why do we have idle work when there's no idle job function?");
			do {
				idle_job_func (thread_data);
				do_idle = continue_idle_job ();
			} while (do_idle && !job_queue.next_slot);

			mono_mutex_lock (&lock);

			if (!do_idle)
				mono_cond_signal (&done_cond);
		}
	}
}
Esempio n. 2
0
void
sgen_thread_pool_wait_for_all_jobs (void)
{
	mono_mutex_lock (&lock);

	while (!sgen_pointer_queue_is_empty (&job_queue))
		mono_cond_wait (&done_cond, &lock);

	mono_mutex_unlock (&lock);
}
Esempio n. 3
0
void
sgen_thread_pool_idle_wait (void)
{
	SGEN_ASSERT (0, idle_job_func, "Why are we waiting for idle without an idle function?");

	mono_mutex_lock (&lock);

	while (continue_idle_job_func ())
		mono_cond_wait (&done_cond, &lock);

	mono_mutex_unlock (&lock);
}
Esempio n. 4
0
void
sgen_thread_pool_job_wait (SgenThreadPoolJob *job)
{
	SGEN_ASSERT (0, job, "Where's the job?");

	mono_mutex_lock (&lock);

	while (find_job_in_queue (job) >= 0)
		mono_cond_wait (&done_cond, &lock);

	mono_mutex_unlock (&lock);
}
Esempio n. 5
0
static void
worker_park (void)
{
	mono_cond_t cond;
	mono_cond_init (&cond, NULL);

	mono_mutex_lock (&threadpool->parked_threads_lock);
	g_ptr_array_add (threadpool->parked_threads, &cond);
	mono_cond_wait (&cond, &threadpool->parked_threads_lock);
	g_ptr_array_remove (threadpool->parked_threads, &cond);
	mono_mutex_unlock (&threadpool->parked_threads_lock);

	mono_cond_destroy (&cond);
}
Esempio n. 6
0
/* Locking: threadpool_io->updates_lock must be held */
static ThreadPoolIOUpdate*
update_get_new (void)
{
	ThreadPoolIOUpdate *update = NULL;
	g_assert (threadpool_io->updates_size <= UPDATES_CAPACITY);

	while (threadpool_io->updates_size == UPDATES_CAPACITY) {
		/* we wait for updates to be applied in the selector_thread and we loop
		 * as long as none are available. if it happends too much, then we need
		 * to increase UPDATES_CAPACITY */
		mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
	}

	g_assert (threadpool_io->updates_size < UPDATES_CAPACITY);

	update = &threadpool_io->updates [threadpool_io->updates_size ++];

	return update;
}
Esempio n. 7
0
void
mono_threadpool_ms_io_remove_domain_jobs (MonoDomain *domain)
{
	ThreadPoolIOUpdate *update;

	if (!mono_lazy_is_initialized (&io_status))
		return;

	mono_mutex_lock (&threadpool_io->updates_lock);

	update = update_get_new ();
	update->type = UPDATE_REMOVE_DOMAIN;
	update->data.remove_domain.domain = domain;
	mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */

	selector_thread_wakeup ();

	mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);

	mono_mutex_unlock (&threadpool_io->updates_lock);
}
Esempio n. 8
0
void
mono_threadpool_ms_io_remove_socket (int fd)
{
	ThreadPoolIOUpdate *update;

	if (!mono_lazy_is_initialized (&io_status))
		return;

	mono_mutex_lock (&threadpool_io->updates_lock);

	update = update_get_new ();
	update->type = UPDATE_REMOVE_SOCKET;
	update->data.add.fd = fd;
	mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */

	selector_thread_wakeup ();

	mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);

	mono_mutex_unlock (&threadpool_io->updates_lock);
}