tor  0.4.1.0-alpha-dev
scheduler.h
Go to the documentation of this file.
1 /* * Copyright (c) 2017-2019, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
9 #ifndef TOR_SCHEDULER_H
10 #define TOR_SCHEDULER_H
11 
12 #include "core/or/or.h"
13 #include "core/or/channel.h"
15 
19 typedef enum {
20  SCHEDULER_NONE = -1,
21  SCHEDULER_VANILLA = 1,
22  SCHEDULER_KIST = 2,
23  SCHEDULER_KIST_LITE = 3,
25 
43 typedef struct scheduler_s {
44  /* Scheduler type. This is used for logging when the scheduler is switched
45  * during runtime. */
46  scheduler_types_t type;
47 
48  /* (Optional) To be called when we want to prepare a scheduler for use.
49  * Perhaps Tor just started and we are the lucky chosen scheduler, or
50  * perhaps Tor is switching to this scheduler. No matter the case, this is
51  * where we would prepare any state and initialize parameters. You might
52  * think of this as the opposite of free_all(). */
53  void (*init)(void);
54 
55  /* (Optional) To be called when we want to tell the scheduler to delete all
56  * of its state (if any). Perhaps Tor is shutting down or perhaps we are
57  * switching schedulers. */
58  void (*free_all)(void);
59 
60  /* (Mandatory) Libevent controls the main event loop in Tor, and this is
61  * where we register with libevent the next execution of run_sched_ev [which
62  * ultimately calls run()]. */
63  void (*schedule)(void);
64 
65  /* (Mandatory) This is the heart of a scheduler! This is where the
66  * excitement happens! Here libevent has given us the chance to execute, and
67  * we should do whatever we need to do in order to move some cells from
68  * their circuit queues to output buffers in an intelligent manner. We
69  * should do this quickly. When we are done, we'll try to schedule() ourself
70  * if more work needs to be done to setup the next scheduling run. */
71  void (*run)(void);
72 
73  /*
74  * External event not related to the scheduler but that can influence it.
75  */
76 
77  /* (Optional) To be called whenever Tor finds out about a new consensus.
78  * First the scheduling system as a whole will react to the new consensus
79  * and change the scheduler if needed. After that, the current scheduler
80  * (which might be new) will call this so it has the chance to react to the
81  * new consensus too. If there's a consensus parameter that your scheduler
82  * wants to keep an eye on, this is where you should check for it. */
83  void (*on_new_consensus)(void);
84 
85  /* (Optional) To be called when a channel is being freed. Sometimes channels
86  * go away (for example: the relay on the other end is shutting down). If
87  * the scheduler keeps any channel-specific state and has memory to free
88  * when channels go away, implement this and free it here. */
89  void (*on_channel_free)(const channel_t *);
90 
91  /* (Optional) To be called whenever Tor is reloading configuration options.
92  * For example: SIGHUP was issued and Tor is rereading its torrc. A
93  * scheduler should use this as an opportunity to parse and cache torrc
94  * options so that it doesn't have to call get_options() all the time. */
95  void (*on_new_options)(void);
96 } scheduler_t;
97 
98 /*****************************************************************************
99  * Globally visible scheduler variables/values
100  *
101  * These are variables/constants that all of Tor should be able to see.
102  *****************************************************************************/
103 
104 /* Default interval that KIST runs (in ms). */
105 #define KIST_SCHED_RUN_INTERVAL_DEFAULT 10
106 /* Minimum interval that KIST runs. This value disables KIST. */
107 #define KIST_SCHED_RUN_INTERVAL_MIN 0
108 /* Maximum interval that KIST runs (in ms). */
109 #define KIST_SCHED_RUN_INTERVAL_MAX 100
110 
111 /*****************************************************************************
112  * Globally visible scheduler functions
113  *
114  * These functions are how the rest of Tor communicates with the scheduling
115  * system.
116  *****************************************************************************/
117 
118 void scheduler_init(void);
119 void scheduler_free_all(void);
120 void scheduler_conf_changed(void);
122 MOCK_DECL(void, scheduler_release_channel, (channel_t *chan));
123 
124 /*
125  * Ways for a channel to interact with the scheduling system. A channel only
126  * really knows (i) whether or not it has cells it wants to send, and
127  * (ii) whether or not it would like to write.
128  */
130 MOCK_DECL(void, scheduler_channel_doesnt_want_writes, (channel_t *chan));
131 MOCK_DECL(void, scheduler_channel_has_waiting_cells, (channel_t *chan));
132 
133 /*****************************************************************************
134  * Private scheduler functions
135  *
136  * These functions are only visible to the scheduling system, the current
137  * scheduler implementation, and tests.
138  *****************************************************************************/
139 #ifdef SCHEDULER_PRIVATE_
140 
141 /*********************************
142  * Defined in scheduler.c
143  *********************************/
144 
145 void scheduler_set_channel_state(channel_t *chan, int new_state);
146 const char *get_scheduler_state_string(int scheduler_state);
147 
148 /* Triggers a BUG() and extra information with chan if available. */
149 #define SCHED_BUG(cond, chan) \
150  (PREDICT_UNLIKELY(cond) ? \
151  ((BUG(cond)) ? (scheduler_bug_occurred(chan), 1) : 0) : 0)
152 
153 void scheduler_bug_occurred(const channel_t *chan);
154 
156 MOCK_DECL(int, scheduler_compare_channels,
157  (const void *c1_v, const void *c2_v));
158 void scheduler_ev_active(void);
159 void scheduler_ev_add(const struct timeval *next_run);
160 
161 #ifdef TOR_UNIT_TESTS
163 extern struct mainloop_event_t *run_sched_ev;
164 extern const scheduler_t *the_scheduler;
165 void scheduler_touch_channel(channel_t *chan);
166 #endif /* defined(TOR_UNIT_TESTS) */
167 
168 /*********************************
169  * Defined in scheduler_kist.c
170  *********************************/
171 
172 #ifdef SCHEDULER_KIST_PRIVATE
173 
174 /* Socket table entry which holds information of a channel's socket and kernel
175  * TCP information. Only used by KIST. */
176 typedef struct socket_table_ent_s {
177  HT_ENTRY(socket_table_ent_s) node;
178  const channel_t *chan;
179  /* Amount written this scheduling run */
180  uint64_t written;
181  /* Amount that can be written this scheduling run */
182  uint64_t limit;
183  /* TCP info from the kernel */
184  uint32_t cwnd;
185  uint32_t unacked;
186  uint32_t mss;
187  uint32_t notsent;
188 } socket_table_ent_t;
189 
190 typedef HT_HEAD(outbuf_table_s, outbuf_table_ent_s) outbuf_table_t;
191 
192 MOCK_DECL(int, channel_should_write_to_kernel,
193  (outbuf_table_t *table, channel_t *chan));
194 MOCK_DECL(void, channel_write_to_kernel, (channel_t *chan));
195 MOCK_DECL(void, update_socket_info_impl, (socket_table_ent_t *ent));
196 
197 int scheduler_can_use_kist(void);
198 void scheduler_kist_set_full_mode(void);
199 void scheduler_kist_set_lite_mode(void);
200 scheduler_t *get_kist_scheduler(void);
201 int kist_scheduler_run_interval(void);
202 
203 #ifdef TOR_UNIT_TESTS
204 extern int32_t sched_run_interval;
205 #endif /* TOR_UNIT_TESTS */
206 
207 #endif /* defined(SCHEDULER_KIST_PRIVATE) */
208 
209 /*********************************
210  * Defined in scheduler_vanilla.c
211  *********************************/
212 
213 scheduler_t *get_vanilla_scheduler(void);
214 
215 #endif /* defined(SCHEDULER_PRIVATE_) */
216 
217 #endif /* !defined(TOR_SCHEDULER_H) */
218 
STATIC const scheduler_t * the_scheduler
Definition: scheduler.c:158
const char * get_scheduler_state_string(int scheduler_state)
Definition: scheduler.c:367
STATIC smartlist_t * channels_pending
Definition: scheduler.c:167
struct scheduler_s scheduler_t
scheduler_types_t
Definition: scheduler.h:19
smartlist_t * get_channels_pending(void)
Definition: scheduler.c:397
void scheduler_ev_active(void)
Definition: scheduler.c:598
void scheduler_free_all(void)
Definition: scheduler.c:485
STATIC struct mainloop_event_t * run_sched_ev
Definition: scheduler.c:173
Header file for channel.c.
Master header file for Tor-specific functionality.
void scheduler_notify_networkstatus_changed(void)
Definition: scheduler.c:468
void scheduler_ev_add(const struct timeval *next_run)
Definition: scheduler.c:585
Macros to implement mocking and selective exposure for the test code.
#define MOCK_DECL(rv, funcname, arglist)
Definition: testsupport.h:94
void scheduler_channel_wants_writes(channel_t *chan)
Definition: scheduler.c:669
void scheduler_set_channel_state(channel_t *chan, int new_state)
Definition: scheduler.c:386
void scheduler_conf_changed(void)
Definition: scheduler.c:453