static class · System.Threading

ThreadPool

public static class ThreadPool

Threads that run queued work: as many as processors, started with the first work item, kept for the program.

Kind
static class
Namespace
System.Threading
Assembly
System.Core
Access
public, static, abstract
Source file
Threading.ant

Inheritance

Base classes
Any ThreadPool

Properties

i32 ThreadCount { get; }
#

static read-only

How many threads run the work.

Methods

QueueUserWorkItem(func item)
#

static

Runs item on a pool thread (an error it throws ends the program).

Private and internal members (8)

Mutex mutex
#

private static

Condition waiting
#

private static

Queue<func> work
#

private static

i32 workers
#

private static

i32 idle
#

private static

AtomicI32 spinning
#

private static

Work()
#

private static

What each worker does: takes work, runs it, again. Before it sleeps it waits a little, giving the processor up in turns: work often comes right after.

Begin()
#

private static

Inherited members (5)

Source

ThreadPool as Antril, decompiled from its Larva HIR.

System.Threading.ThreadPool.ant
// System.Threading.ThreadPool — System.Core (decompiled from Larva HIR)

import System;

into namespace System.Threading
{
	/// Threads that run queued work: as many as processors, started with the first work item, kept for the program.
	public static class ThreadPool
	{
		Mutex mutex;
		Condition waiting;
		Queue<func> work;
		i32 workers;
		i32 idle;
		AtomicI32 spinning;

		/// What each worker does: takes work, runs it, again. Before it sleeps it waits a little, giving the processor
		/// up in turns: work often comes right after.
		Work()
		{
			loop (true)
			{
				if (spinning.Increment() <= 2)
				{
					loop (i32 spin = 0; spin < 2000 && work.Count == 0; spin++)
						Thread.SpinWait(spin < 1000 ? 20 : 0);
					loop (i32 spin = 0; spin < 32 && work.Count == 0; spin++)
						Thread.Yield();
				}
				spinning.Decrement();
				mutex.Lock();
				idle++;
				loop (work.Count == 0)
					waiting.Wait(mutex);
				idle--;
				func item = work.Dequeue();
				mutex.Unlock();
				item();
			}
		}

		[NoInline]
		Begin()
		{
			workers = Environment.ProcessorCount;
			loop (i32 i = 0..workers)
				new Thread(() => { Work(); }).Start();
		}

		public:
			/// Runs `item` on a pool thread (an error it throws ends the program).
			QueueUserWorkItem(func item)
			{
				mutex.Lock();
				if (workers == 0)
					Begin();
				work.Enqueue(item);
				bool someone = idle > 0;
				mutex.Unlock();
				if (someone)
					waiting.Signal();
			}

			/// How many threads run the work.
			i32 ThreadCount
			{
				get => workers;
			}
	}
}
Esc