1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 #pragma once
10 
11 #include "rocksdb/threadpool.h"
12 #include "rocksdb/env.h"
13 
14 #include <memory>
15 #include <functional>
16 
17 namespace ROCKSDB_NAMESPACE {
18 
19 class ThreadPoolImpl : public ThreadPool {
20  public:
21   ThreadPoolImpl();
22   ~ThreadPoolImpl();
23 
24   ThreadPoolImpl(ThreadPoolImpl&&) = delete;
25   ThreadPoolImpl& operator=(ThreadPoolImpl&&) = delete;
26 
27   // Implement ThreadPool interfaces
28 
29   // Wait for all threads to finish.
30   // Discards all the jobs that did not
31   // start executing and waits for those running
32   // to complete
33   void JoinAllThreads() override;
34 
35   // Set the number of background threads that will be executing the
36   // scheduled jobs.
37   void SetBackgroundThreads(int num) override;
38   int GetBackgroundThreads() override;
39 
40   // Get the number of jobs scheduled in the ThreadPool queue.
41   unsigned int GetQueueLen() const override;
42 
43   // Waits for all jobs to complete those
44   // that already started running and those that did not
45   // start yet
46   void WaitForJobsAndJoinAllThreads() override;
47 
48   // Make threads to run at a lower kernel IO priority
49   // Currently only has effect on Linux
50   void LowerIOPriority();
51 
52   // Make threads to run at a lower kernel CPU priority
53   // Currently only has effect on Linux
54   void LowerCPUPriority();
55 
56   // Ensure there is at aleast num threads in the pool
57   // but do not kill threads if there are more
58   void IncBackgroundThreadsIfNeeded(int num);
59 
60   // Submit a fire and forget job
61   // These jobs can not be unscheduled
62 
63   // This allows to submit the same job multiple times
64   void SubmitJob(const std::function<void()>&) override;
65   // This moves the function in for efficiency
66   void SubmitJob(std::function<void()>&&) override;
67 
68   // Schedule a job with an unschedule tag and unschedule function
69   // Can be used to filter and unschedule jobs by a tag
70   // that are still in the queue and did not start running
71   void Schedule(void (*function)(void* arg1), void* arg, void* tag,
72                 void (*unschedFunction)(void* arg));
73 
74   // Filter jobs that are still in a queue and match
75   // the given tag. Remove them from a queue if any
76   // and for each such job execute an unschedule function
77   // if such was given at scheduling time.
78   int UnSchedule(void* tag);
79 
80   void SetHostEnv(Env* env);
81 
82   Env* GetHostEnv() const;
83 
84   // Return the thread priority.
85   // This would allow its member-thread to know its priority.
86   Env::Priority GetThreadPriority() const;
87 
88   // Set the thread priority.
89   void SetThreadPriority(Env::Priority priority);
90 
91   static void PthreadCall(const char* label, int result);
92 
93   struct Impl;
94 
95  private:
96 
97    // Current public virtual interface does not provide usable
98    // functionality and thus can not be used internally to
99    // facade different implementations.
100    //
101    // We propose a pimpl idiom in order to easily replace the thread pool impl
102    // w/o touching the header file but providing a different .cc potentially
103    // CMake option driven.
104    //
105    // Another option is to introduce a Env::MakeThreadPool() virtual interface
106    // and override the environment. This would require refactoring ThreadPool usage.
107    //
108    // We can also combine these two approaches
109    std::unique_ptr<Impl>   impl_;
110 };
111 
112 }  // namespace ROCKSDB_NAMESPACE
113