Tor 0.4.9.0-alpha-dev
scheduler.h
Go to the documentation of this file.
1/* * Copyright (c) 2017-2021, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * \file scheduler.h
6 * \brief Header file for scheduler*.c
7 **/
8
9#ifndef TOR_SCHEDULER_H
10#define TOR_SCHEDULER_H
11
12#include "core/or/or.h"
13#include "core/or/channel.h"
15
16/** Scheduler type, we build an ordered list with those values from the
17 * parsed strings in Schedulers. The reason to do such a thing is so we can
18 * quickly and without parsing strings select the scheduler at anytime. */
19typedef enum {
20 SCHEDULER_NONE = -1,
21 SCHEDULER_VANILLA = 1,
22 SCHEDULER_KIST = 2,
23 SCHEDULER_KIST_LITE = 3,
25
26/**
27 * A scheduler implementation is a collection of function pointers. If you
28 * would like to add a new scheduler called foo, create scheduler_foo.c,
29 * implement at least the mandatory ones, and implement get_foo_scheduler()
30 * that returns a complete scheduler_t for your foo scheduler. See
31 * scheduler_kist.c for an example.
32 *
33 * These function pointers SHOULD NOT be used anywhere outside of the
34 * scheduling source files. The rest of Tor should communicate with the
35 * scheduling system through the functions near the bottom of this file, and
36 * those functions will call into the current scheduler implementation as
37 * necessary.
38 *
39 * If your scheduler doesn't need to implement something (for example: it
40 * doesn't create any state for itself, thus it has nothing to free when Tor
41 * is shutting down), then set that function pointer to NULL.
42 */
43typedef struct scheduler_t {
44 /* Scheduler type. This is used for logging when the scheduler is switched
45 * during runtime. */
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);
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 2
106/* Minimum interval that KIST runs. */
107#define KIST_SCHED_RUN_INTERVAL_MIN 2
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
118void scheduler_init(void);
119void scheduler_free_all(void);
120void scheduler_conf_changed(void);
122MOCK_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 */
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#include "ext/ht.h"
142
143/*********************************
144 * Defined in scheduler.c
145 *********************************/
146
147void scheduler_set_channel_state(channel_t *chan, int new_state);
148const char *get_scheduler_state_string(int scheduler_state);
149
150/* Triggers a BUG() and extra information with chan if available. */
151#define SCHED_BUG(cond, chan) \
152 (PREDICT_UNLIKELY(cond) ? \
153 ((BUG(cond)) ? (scheduler_bug_occurred(chan), 1) : 0) : 0)
154
155void scheduler_bug_occurred(const channel_t *chan);
156
159 (const void *c1_v, const void *c2_v));
160void scheduler_ev_active(void);
161void scheduler_ev_add(const struct timeval *next_run);
162
163#ifdef TOR_UNIT_TESTS
165extern struct mainloop_event_t *run_sched_ev;
166extern const scheduler_t *the_scheduler;
167void scheduler_touch_channel(channel_t *chan);
168#endif /* defined(TOR_UNIT_TESTS) */
169
170/*********************************
171 * Defined in scheduler_kist.c
172 *********************************/
173
174#ifdef SCHEDULER_KIST_PRIVATE
175
176/* Socket table entry which holds information of a channel's socket and kernel
177 * TCP information. Only used by KIST. */
178typedef struct socket_table_ent_t {
179 HT_ENTRY(socket_table_ent_t) node;
180 const channel_t *chan;
181 /* Amount written this scheduling run */
182 uint64_t written;
183 /* Amount that can be written this scheduling run */
184 uint64_t limit;
185 /* TCP info from the kernel */
186 uint32_t cwnd;
187 uint32_t unacked;
188 uint32_t mss;
189 uint32_t notsent;
190} socket_table_ent_t;
191
192typedef HT_HEAD(outbuf_table_s, outbuf_table_ent_t) outbuf_table_t;
193
194MOCK_DECL(int, channel_should_write_to_kernel,
195 (outbuf_table_t *table, channel_t *chan));
196MOCK_DECL(void, channel_write_to_kernel, (channel_t *chan));
197MOCK_DECL(void, update_socket_info_impl, (socket_table_ent_t *ent));
198
199int scheduler_can_use_kist(void);
200void scheduler_kist_set_full_mode(void);
201void scheduler_kist_set_lite_mode(void);
202scheduler_t *get_kist_scheduler(void);
203int kist_scheduler_run_interval(void);
204
205#ifdef TOR_UNIT_TESTS
206extern int32_t sched_run_interval;
207#endif /* TOR_UNIT_TESTS */
208
209#endif /* defined(SCHEDULER_KIST_PRIVATE) */
210
211/*********************************
212 * Defined in scheduler_vanilla.c
213 *********************************/
214
215scheduler_t *get_vanilla_scheduler(void);
216
217#endif /* defined(SCHEDULER_PRIVATE) */
218
219#endif /* !defined(TOR_SCHEDULER_H) */
Header file for channel.c.
typedef HT_HEAD(hs_service_ht, hs_service_t) hs_service_ht
Master header file for Tor-specific functionality.
void scheduler_ev_active(void)
Definition: scheduler.c:598
const char * get_scheduler_state_string(int scheduler_state)
Definition: scheduler.c:366
smartlist_t * get_channels_pending(void)
Definition: scheduler.c:396
int scheduler_compare_channels(const void *c1_v, const void *c2_v)
Definition: scheduler.c:403
void scheduler_set_channel_state(channel_t *chan, int new_state)
Definition: scheduler.c:385
void scheduler_ev_add(const struct timeval *next_run)
Definition: scheduler.c:585
STATIC struct mainloop_event_t * run_sched_ev
Definition: scheduler.c:172
STATIC const scheduler_t * the_scheduler
Definition: scheduler.c:157
STATIC smartlist_t * channels_pending
Definition: scheduler.c:166
void scheduler_notify_networkstatus_changed(void)
Definition: scheduler.c:467
void scheduler_conf_changed(void)
Definition: scheduler.c:452
void scheduler_free_all(void)
Definition: scheduler.c:484
void scheduler_channel_doesnt_want_writes(channel_t *chan)
Definition: scheduler.c:512
void scheduler_channel_wants_writes(channel_t *chan)
Definition: scheduler.c:673
void scheduler_channel_has_waiting_cells(channel_t *chan)
Definition: scheduler.c:548
scheduler_types_t
Definition: scheduler.h:19
Macros to implement mocking and selective exposure for the test code.
#define MOCK_DECL(rv, funcname, arglist)
Definition: testsupport.h:127