GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 40
Functions: 0.0% 0 / 0 / 9
Branches: 0.0% 0 / 0 / 38

core/ThreadPool.h
Line Branch Exec Source
1 #ifndef _AVS_THREADPOOL_H
2 #define _AVS_THREADPOOL_H
3
4 #include <avisynth.h>
5 #include <future>
6 #include <vector>
7
8 typedef std::future<AVSValue> AVSFuture;
9 typedef std::promise<AVSValue> AVSPromise;
10
11 class InternalEnvironment;
12
13 class JobCompletion : public IJobCompletion
14 {
15 private:
16 const size_t max_jobs;
17 size_t nJobs;
18
19 public:
20 typedef std::pair<AVSPromise, AVSFuture> PromFutPair;
21 PromFutPair *pairs;
22
23 JobCompletion(size_t _max_jobs) :
24 max_jobs(_max_jobs),
25 nJobs(0),
26 pairs(NULL)
27 {
28 pairs = new PromFutPair[max_jobs];
29
30 // Initialize for first use
31 nJobs = max_jobs;
32 Reset();
33 }
34
35 AVSPromise* Add()
36 {
37 if (nJobs == max_jobs)
38 throw AvisynthError("The completion object is already full.");
39
40 AVSPromise* ret = &(pairs[nJobs].first);
41 ++nJobs;
42 return ret;
43 }
44
45 virtual ~JobCompletion()
46 {
47 Wait();
48 delete [] pairs;
49 }
50
51 void __stdcall Wait()
52 {
53 for (size_t i = 0; i < nJobs; ++i)
54 pairs[i].second.wait();
55 }
56 size_t __stdcall Size() const
57 {
58 return nJobs;
59 }
60 size_t __stdcall Capacity() const
61 {
62 return max_jobs;
63 }
64 AVSValue __stdcall Get(size_t i)
65 {
66 return pairs[i].second.get();
67 }
68 #ifdef __clang__
69 #pragma clang diagnostic push
70 #pragma clang diagnostic ignored "-Wpessimizing-move"
71 #elif defined(__GNUC__)
72 #pragma GCC diagnostic push
73 #pragma GCC diagnostic ignored "-Wpessimizing-move"
74 #elif defined(_MSC_VER)
75 // Add MSVC-specific pragma if needed
76 #endif
77 void __stdcall Reset()
78 {
79 for (size_t i = 0; i < nJobs; ++i)
80 {
81 // To be on the safe side, keep std::move to ensure efficient move semantics,
82 // even if copy elision is possible (despite compiler warnings).
83 // AVSValue does not have a move constructor or move assignment operator.
84 // It only has a copy constructor and copy assignment operator. This means that
85 // AVSValue objects will be copied rather than moved, which can be less efficient.
86 pairs[i].first = std::move(AVSPromise());
87 pairs[i].second = std::move(pairs[i].first.get_future());
88 }
89 nJobs = 0;
90 }
91 #ifdef __clang__
92 #pragma clang diagnostic pop
93 #elif defined(__GNUC__)
94 #pragma GCC diagnostic pop
95 #elif defined(_MSC_VER)
96 // Add MSVC-specific pragma if needed
97 #endif
98 void __stdcall Destroy()
99 {
100 delete this;
101 }
102 };
103
104 class ThreadPoolPimpl;
105 class ThreadPool
106 {
107 private:
108 ThreadPoolPimpl* const _pimpl;
109
110 static void ThreadFunc(size_t thread_id, ThreadPoolPimpl* const _pimpl, InternalEnvironment* env);
111 public:
112 ThreadPool(size_t nThreads, size_t nStartId, InternalEnvironment* env);
113 ~ThreadPool();
114
115 void QueueJob(ThreadWorkerFuncPtr clb, void* params, InternalEnvironment* env, JobCompletion* tc);
116 size_t NumThreads() const;
117
118 std::vector<void*> Finish();
119 void Join();
120 };
121
122
123 #endif // _AVS_THREADPOOL_H
124