aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/workerpools.cpp
blob: 939f3a1c454810ac4bb73ab4f538efb6f6cb7a91 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright Epic Games, Inc. All Rights Reserved.

#include "zenutil/workerpools.h"

#include <zencore/intmath.h>
#include <zencore/thread.h>

ZEN_THIRD_PARTY_INCLUDES_START
#include <gsl/gsl-lite.hpp>
ZEN_THIRD_PARTY_INCLUDES_END

namespace zen {
namespace {
	const int LargeWorkerThreadPoolTreadCount  = gsl::narrow<int>(std::thread::hardware_concurrency());
	const int MediumWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 4u), 1u));
	const int SmallWorkerThreadPoolTreadCount  = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 8u), 1u));

	static bool IsShutDown = false;

	RwLock PoolLock;

	std::unique_ptr<WorkerThreadPool> LargeWorkerPool;
	std::unique_ptr<WorkerThreadPool> MediumWorkerPool;
	std::unique_ptr<WorkerThreadPool> SmallWorkerPool;
	std::unique_ptr<WorkerThreadPool> SyncWorkerPool;
}  // namespace

WorkerThreadPool&
GetLargeWorkerPool()
{
	{
		RwLock::SharedLockScope _(PoolLock);
		if (LargeWorkerPool)
		{
			return *LargeWorkerPool;
		}
	}
	RwLock::ExclusiveLockScope _(PoolLock);
	ZEN_ASSERT(!IsShutDown);
	if (LargeWorkerPool)
	{
		return *LargeWorkerPool;
	}
	LargeWorkerPool.reset(new WorkerThreadPool(LargeWorkerThreadPoolTreadCount, "LargeThreadPool"));
	return *LargeWorkerPool;
}

WorkerThreadPool&
GetMediumWorkerPool()
{
	{
		RwLock::SharedLockScope _(PoolLock);
		if (MediumWorkerPool)
		{
			return *MediumWorkerPool;
		}
	}
	RwLock::ExclusiveLockScope _(PoolLock);
	ZEN_ASSERT(!IsShutDown);
	if (MediumWorkerPool)
	{
		return *MediumWorkerPool;
	}
	MediumWorkerPool.reset(new WorkerThreadPool(MediumWorkerThreadPoolTreadCount, "MediumThreadPool"));
	return *MediumWorkerPool;
}

WorkerThreadPool&
GetSmallWorkerPool()
{
	{
		RwLock::SharedLockScope _(PoolLock);
		if (SmallWorkerPool)
		{
			return *SmallWorkerPool;
		}
	}
	RwLock::ExclusiveLockScope _(PoolLock);
	ZEN_ASSERT(!IsShutDown);
	if (SmallWorkerPool)
	{
		return *SmallWorkerPool;
	}
	SmallWorkerPool.reset(new WorkerThreadPool(SmallWorkerThreadPoolTreadCount, "SmallThreadPool"));
	return *SmallWorkerPool;
}

WorkerThreadPool&
GetSyncWorkerPool()
{
	{
		RwLock::SharedLockScope _(PoolLock);
		if (SyncWorkerPool)
		{
			return *SyncWorkerPool;
		}
	}
	RwLock::ExclusiveLockScope _(PoolLock);
	ZEN_ASSERT(!IsShutDown);
	if (SyncWorkerPool)
	{
		return *SyncWorkerPool;
	}
	SyncWorkerPool.reset(new WorkerThreadPool(0, "SyncThreadPool"));
	return *SyncWorkerPool;
}

void
ShutdownWorkerPools()
{
	RwLock::ExclusiveLockScope _(PoolLock);
	IsShutDown = true;
	LargeWorkerPool.reset();
	MediumWorkerPool.reset();
	SmallWorkerPool.reset();
	SyncWorkerPool.reset();
}
}  // namespace zen