Coverage Report

Created: 2025-09-17 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/bthread/timer_thread.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
// bthread - An M:N threading library to make applications more concurrent.
19
20
21
#ifndef BTHREAD_TIMER_THREAD_H
22
#define BTHREAD_TIMER_THREAD_H
23
24
#include <vector>                     // std::vector
25
#include <pthread.h>                  // pthread_*
26
#include "butil/atomicops.h" 
27
#include "butil/time.h"                // time utilities
28
#include "bthread/mutex.h"
29
30
namespace bthread {
31
32
struct TimerThreadOptions {
33
    // Scheduling requests are hashed into different bucket to improve
34
    // scalability. However bigger num_buckets may NOT result in more scalable 
35
    // schedule() because bigger values also make each buckets more sparse
36
    // and more likely to lock the global mutex. You better not change
37
    // this value, just leave it to us.
38
    // Default: 13
39
    size_t num_buckets;
40
41
    // If this field is not empty, some bvar for reporting stats of TimerThread
42
    // will be exposed with this prefix.
43
    // Default: ""
44
    std::string bvar_prefix;
45
46
    // Constructed with default options.
47
    TimerThreadOptions();
48
};
49
50
// TimerThread is a separate thread to run scheduled tasks at specific time.
51
// At most one task runs at any time, don't put time-consuming code in the
52
// callback otherwise the task may delay other tasks significantly.
53
class TimerThread {
54
public:
55
    struct Task;
56
    class Bucket;
57
58
    typedef uint64_t TaskId;
59
    const static TaskId INVALID_TASK_ID;
60
61
    TimerThread();
62
    ~TimerThread();
63
64
    // Start the timer thread.
65
    // This method should only be called once.
66
    // return 0 if success, errno otherwise.
67
    int start(const TimerThreadOptions* options);
68
69
    // Stop the timer thread. Later schedule() will return INVALID_TASK_ID.
70
    void stop_and_join();
71
72
    // Schedule |fn(arg)| to run at realtime |abstime| approximately.
73
    // Returns: identifier of the scheduled task, INVALID_TASK_ID on error.
74
    TaskId schedule(void (*fn)(void*), void* arg, const timespec& abstime);
75
76
    // Prevent the task denoted by `task_id' from running. `task_id' must be
77
    // returned by schedule() ever.
78
    // Returns:
79
    //   0   -  Removed the task which does not run yet
80
    //  -1   -  The task does not exist.
81
    //   1   -  The task is just running.
82
    int unschedule(TaskId task_id);
83
84
    // Get identifier of internal pthread.
85
    // Returns (pthread_t)0 if start() is not called yet.
86
0
    pthread_t thread_id() const { return _thread; }
87
    
88
private:
89
    // the timer thread will run this method.
90
    void run();
91
    static void* run_this(void* arg);
92
93
    bool _started;            // whether the timer thread was started successfully.
94
    butil::atomic<bool> _stop;
95
96
    TimerThreadOptions _options;
97
    Bucket* _buckets;        // list of tasks to be run
98
    FastPthreadMutex _mutex;    // protect _nearest_run_time
99
    int64_t _nearest_run_time;
100
    // the futex for wake up timer thread. can't use _nearest_run_time because
101
    // it's 64-bit.
102
    int _nsignals;
103
    pthread_t _thread;       // all scheduled task will be run on this thread
104
};
105
106
// Get the global TimerThread which never quits.
107
TimerThread* get_or_create_global_timer_thread();
108
TimerThread* get_global_timer_thread();
109
110
}   // end namespace bthread
111
112
#endif  // BTHREAD_TIMER_THREAD_H