scheduler.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /* * Copyright (c) 2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file scheduler.h
  5. * \brief Header file for scheduler*.c
  6. **/
  7. #ifndef TOR_SCHEDULER_H
  8. #define TOR_SCHEDULER_H
  9. #include "or.h"
  10. #include "channel.h"
  11. #include "testsupport.h"
  12. /*
  13. * A scheduler implementation is a collection of function pointers. If you
  14. * would like to add a new scheduler called foo, create scheduler_foo.c,
  15. * implement at least the mandatory ones, and implement get_foo_scheduler()
  16. * that returns a complete scheduler_t for your foo scheduler. See
  17. * scheduler_kist.c for an example.
  18. *
  19. * These function pointers SHOULD NOT be used anywhere outside of the
  20. * scheduling source files. The rest of Tor should communicate with the
  21. * scheduling system through the functions near the bottom of this file, and
  22. * those functions will call into the current scheduler implementation as
  23. * necessary.
  24. *
  25. * If your scheduler doesn't need to implement something (for example: it
  26. * doesn't create any state for itself, thus it has nothing to free when Tor
  27. * is shutting down), then set that function pointer to NULL.
  28. */
  29. typedef struct scheduler_s {
  30. /* (Optional) To be called when we want to prepare a scheduler for use.
  31. * Perhaps Tor just started and we are the lucky chosen scheduler, or
  32. * perhaps Tor is switching to this scheduler. No matter the case, this is
  33. * where we would prepare any state and initialize parameters. You might
  34. * think of this as the opposite of free_all(). */
  35. void (*init)(void);
  36. /* (Optional) To be called when we want to tell the scheduler to delete all
  37. * of its state (if any). Perhaps Tor is shutting down or perhaps we are
  38. * switching schedulers. */
  39. void (*free_all)(void);
  40. /* (Mandatory) Libevent controls the main event loop in Tor, and this is
  41. * where we register with libevent the next execution of run_sched_ev [which
  42. * ultimately calls run()]. */
  43. void (*schedule)(void);
  44. /* (Mandatory) This is the heart of a scheduler! This is where the
  45. * excitement happens! Here libevent has given us the chance to execute, and
  46. * we should do whatever we need to do in order to move some cells from
  47. * their circuit queues to output buffers in an intelligent manner. We
  48. * should do this quickly. When we are done, we'll try to schedule() ourself
  49. * if more work needs to be done to setup the next scehduling run. */
  50. void (*run)(void);
  51. /*
  52. * External event not related to the scheduler but that can influence it.
  53. */
  54. /* (Optional) To be called whenever Tor finds out about a new consensus.
  55. * First the scheduling system as a whole will react to the new consensus
  56. * and change the scheduler if needed. After that, the current scheduler
  57. * (which might be new) will call this so it has the chance to react to the
  58. * new consensus too. If there's a consensus parameter that your scheduler
  59. * wants to keep an eye on, this is where you should check for it. */
  60. void (*on_new_consensus)(const networkstatus_t *old_c,
  61. const networkstatus_t *new_c);
  62. /* (Optional) To be called when a channel is being freed. Sometimes channels
  63. * go away (for example: the relay on the other end is shutting down). If
  64. * the scheduler keeps any channel-specific state and has memory to free
  65. * when channels go away, implement this and free it here. */
  66. void (*on_channel_free)(const channel_t *);
  67. /* (Optional) To be called whenever Tor is reloading configuration options.
  68. * For example: SIGHUP was issued and Tor is rereading its torrc. A
  69. * scheduler should use this as an opportunity to parse and cache torrc
  70. * options so that it doesn't have to call get_options() all the time. */
  71. void (*on_new_options)(void);
  72. } scheduler_t;
  73. /** Scheduler type, we build an ordered list with those values from the
  74. * parsed strings in Schedulers. The reason to do such a thing is so we can
  75. * quickly and without parsing strings select the scheduler at anytime. */
  76. typedef enum {
  77. SCHEDULER_VANILLA = 1,
  78. SCHEDULER_KIST = 2,
  79. SCHEDULER_KIST_LITE = 3,
  80. } scheduler_types_t;
  81. /*****************************************************************************
  82. * Globally visible scheduler variables/values
  83. *
  84. * These are variables/constants that all of Tor should be able to see.
  85. *****************************************************************************/
  86. /* Default interval that KIST runs (in ms). */
  87. #define KIST_SCHED_RUN_INTERVAL_DEFAULT 10
  88. /* Minimum interval that KIST runs. This value disables KIST. */
  89. #define KIST_SCHED_RUN_INTERVAL_MIN 0
  90. /* Maximum interval that KIST runs (in ms). */
  91. #define KIST_SCHED_RUN_INTERVAL_MAX 100
  92. /*****************************************************************************
  93. * Globally visible scheduler functions
  94. *
  95. * These functions are how the rest of Tor communicates with the scheduling
  96. * system.
  97. *****************************************************************************/
  98. void scheduler_init(void);
  99. void scheduler_free_all(void);
  100. void scheduler_conf_changed(void);
  101. void scheduler_notify_networkstatus_changed(const networkstatus_t *old_c,
  102. const networkstatus_t *new_c);
  103. MOCK_DECL(void, scheduler_release_channel, (channel_t *chan));
  104. /*
  105. * Ways for a channel to interact with the scheduling system. A channel only
  106. * really knows (i) whether or not it has cells it wants to send, and
  107. * (ii) whether or not it would like to write.
  108. */
  109. void scheduler_channel_wants_writes(channel_t *chan);
  110. MOCK_DECL(void, scheduler_channel_doesnt_want_writes, (channel_t *chan));
  111. MOCK_DECL(void, scheduler_channel_has_waiting_cells, (channel_t *chan));
  112. /*****************************************************************************
  113. * Private scheduler functions
  114. *
  115. * These functions are only visible to the scheduling system, the current
  116. * scheduler implementation, and tests.
  117. *****************************************************************************/
  118. #ifdef SCHEDULER_PRIVATE_
  119. /*********************************
  120. * Defined in scheduler.c
  121. *********************************/
  122. smartlist_t *get_channels_pending(void);
  123. MOCK_DECL(int, scheduler_compare_channels,
  124. (const void *c1_v, const void *c2_v));
  125. void scheduler_ev_active(int flags);
  126. void scheduler_ev_add(const struct timeval *next_run);
  127. #ifdef TOR_UNIT_TESTS
  128. extern smartlist_t *channels_pending;
  129. extern struct event *run_sched_ev;
  130. extern const scheduler_t *the_scheduler;
  131. void scheduler_touch_channel(channel_t *chan);
  132. #endif /* TOR_UNIT_TESTS */
  133. /*********************************
  134. * Defined in scheduler_kist.c
  135. *********************************/
  136. #ifdef SCHEDULER_KIST_PRIVATE
  137. /* Socke table entry which holds information of a channel's socket and kernel
  138. * TCP information. Only used by KIST. */
  139. typedef struct socket_table_ent_s {
  140. HT_ENTRY(socket_table_ent_s) node;
  141. const channel_t *chan;
  142. /* Amount written this scheduling run */
  143. uint64_t written;
  144. /* Amount that can be written this scheduling run */
  145. uint64_t limit;
  146. /* TCP info from the kernel */
  147. uint32_t cwnd;
  148. uint32_t unacked;
  149. uint32_t mss;
  150. uint32_t notsent;
  151. } socket_table_ent_t;
  152. typedef HT_HEAD(outbuf_table_s, outbuf_table_ent_s) outbuf_table_t;
  153. MOCK_DECL(int, channel_should_write_to_kernel,
  154. (outbuf_table_t *table, channel_t *chan));
  155. MOCK_DECL(void, channel_write_to_kernel, (channel_t *chan));
  156. MOCK_DECL(void, update_socket_info_impl, (socket_table_ent_t *ent));
  157. int scheduler_can_use_kist(void);
  158. void scheduler_kist_set_full_mode(void);
  159. void scheduler_kist_set_lite_mode(void);
  160. scheduler_t *get_kist_scheduler(void);
  161. int32_t kist_scheduler_run_interval(const networkstatus_t *ns);
  162. #ifdef TOR_UNIT_TESTS
  163. extern int32_t sched_run_interval;
  164. #endif /* TOR_UNIT_TESTS */
  165. #endif /* SCHEDULER_KIST_PRIVATE */
  166. /*********************************
  167. * Defined in scheduler_vanilla.c
  168. *********************************/
  169. scheduler_t *get_vanilla_scheduler(void);
  170. #endif /* SCHEDULER_PRIVATE_ */
  171. #endif /* TOR_SCHEDULER_H */