]> granicus.if.org Git - icinga2/blob - lib/base/threadpool.hpp
Update copyright headers for 2016
[icinga2] / lib / base / threadpool.hpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2016 Icinga Development Team (https://www.icinga.org/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef THREADPOOL_H
21 #define THREADPOOL_H
22
23 #include "base/i2-base.hpp"
24 #include <boost/function.hpp>
25 #include <boost/thread/thread.hpp>
26 #include <boost/thread/mutex.hpp>
27 #include <boost/thread/condition_variable.hpp>
28 #include <deque>
29
30 namespace icinga
31 {
32
33 #define QUEUECOUNT 4U
34
35 enum SchedulerPolicy
36 {
37         DefaultScheduler,
38         LowLatencyScheduler
39 };
40
41 /**
42  * A thread pool.
43  *
44  * @ingroup base
45  */
46 class I2_BASE_API ThreadPool
47 {
48 public:
49         typedef boost::function<void ()> WorkFunction;
50
51         ThreadPool(size_t max_threads = UINT_MAX);
52         ~ThreadPool(void);
53
54         void Start(void);
55         void Stop(void);
56
57         bool Post(const WorkFunction& callback, SchedulerPolicy policy = DefaultScheduler);
58
59 private:
60         enum ThreadState
61         {
62                 ThreadUnspecified,
63                 ThreadDead,
64                 ThreadIdle,
65                 ThreadBusy
66         };
67
68         struct WorkItem
69         {
70                 WorkFunction Callback;
71                 double Timestamp;
72         };
73
74         struct Queue;
75
76         struct WorkerThread
77         {
78                 ThreadState State;
79                 bool Zombie;
80                 double Utilization;
81                 double LastUpdate;
82                 boost::thread *Thread;
83
84                 WorkerThread(ThreadState state = ThreadDead)
85                         : State(state), Zombie(false), Utilization(0), LastUpdate(0), Thread(NULL)
86                 { }
87
88                 void UpdateUtilization(ThreadState state = ThreadUnspecified);
89
90                 void ThreadProc(Queue& queue);
91         };
92
93         struct Queue
94         {
95                 boost::mutex Mutex;
96                 boost::condition_variable CV;
97                 boost::condition_variable CVStarved;
98
99                 std::deque<WorkItem> Items;
100
101                 double WaitTime;
102                 double ServiceTime;
103                 int TaskCount;
104
105                 bool Stopped;
106
107                 WorkerThread Threads[16];
108
109                 Queue(void)
110                         : WaitTime(0), ServiceTime(0), TaskCount(0), Stopped(false)
111                 { }
112
113                 void SpawnWorker(boost::thread_group& group);
114                 void KillWorker(boost::thread_group& group);
115         };
116
117         int m_ID;
118         static int m_NextID;
119
120         size_t m_MaxThreads;
121
122         boost::thread_group m_ThreadGroup;
123
124         boost::thread m_MgmtThread;
125         boost::mutex m_MgmtMutex;
126         boost::condition_variable m_MgmtCV;
127         bool m_Stopped;
128
129         Queue m_Queues[QUEUECOUNT];
130
131         void ManagerThreadProc(void);
132 };
133
134 }
135
136 #endif /* EVENTQUEUE_H */