thread.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320
  1. /* Thread management routine
  2. * Copyright (C) 1998, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. /* #define DEBUG */
  22. #include <zebra.h>
  23. #include "thread.h"
  24. #include "memory.h"
  25. #include "log.h"
  26. #include "hash.h"
  27. #include "pqueue.h"
  28. #include "command.h"
  29. #include "sigevent.h"
  30. #if defined HAVE_SNMP && defined SNMP_AGENTX
  31. #include <net-snmp/net-snmp-config.h>
  32. #include <net-snmp/net-snmp-includes.h>
  33. #include <net-snmp/agent/net-snmp-agent-includes.h>
  34. #include <net-snmp/agent/snmp_vars.h>
  35. extern int agentx_enabled;
  36. #endif
  37. #if defined(__APPLE__)
  38. #include <mach/mach.h>
  39. #include <mach/mach_time.h>
  40. #endif
  41. /* Recent absolute time of day */
  42. struct timeval recent_time;
  43. static struct timeval last_recent_time;
  44. /* Relative time, since startup */
  45. static struct timeval relative_time;
  46. static struct timeval relative_time_base;
  47. /* init flag */
  48. static unsigned short timers_inited;
  49. static struct hash *cpu_record = NULL;
  50. /* Struct timeval's tv_usec one second value. */
  51. #define TIMER_SECOND_MICRO 1000000L
  52. /* Adjust so that tv_usec is in the range [0,TIMER_SECOND_MICRO).
  53. And change negative values to 0. */
  54. static struct timeval
  55. timeval_adjust (struct timeval a)
  56. {
  57. while (a.tv_usec >= TIMER_SECOND_MICRO)
  58. {
  59. a.tv_usec -= TIMER_SECOND_MICRO;
  60. a.tv_sec++;
  61. }
  62. while (a.tv_usec < 0)
  63. {
  64. a.tv_usec += TIMER_SECOND_MICRO;
  65. a.tv_sec--;
  66. }
  67. if (a.tv_sec < 0)
  68. /* Change negative timeouts to 0. */
  69. a.tv_sec = a.tv_usec = 0;
  70. return a;
  71. }
  72. static struct timeval
  73. timeval_subtract (struct timeval a, struct timeval b)
  74. {
  75. struct timeval ret;
  76. ret.tv_usec = a.tv_usec - b.tv_usec;
  77. ret.tv_sec = a.tv_sec - b.tv_sec;
  78. return timeval_adjust (ret);
  79. }
  80. static long
  81. timeval_cmp (struct timeval a, struct timeval b)
  82. {
  83. return (a.tv_sec == b.tv_sec
  84. ? a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
  85. }
  86. static unsigned long
  87. timeval_elapsed (struct timeval a, struct timeval b)
  88. {
  89. return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
  90. + (a.tv_usec - b.tv_usec));
  91. }
  92. #if !defined(HAVE_CLOCK_MONOTONIC) && !defined(__APPLE__)
  93. static void
  94. quagga_gettimeofday_relative_adjust (void)
  95. {
  96. struct timeval diff;
  97. if (timeval_cmp (recent_time, last_recent_time) < 0)
  98. {
  99. relative_time.tv_sec++;
  100. relative_time.tv_usec = 0;
  101. }
  102. else
  103. {
  104. diff = timeval_subtract (recent_time, last_recent_time);
  105. relative_time.tv_sec += diff.tv_sec;
  106. relative_time.tv_usec += diff.tv_usec;
  107. relative_time = timeval_adjust (relative_time);
  108. }
  109. last_recent_time = recent_time;
  110. }
  111. #endif /* !HAVE_CLOCK_MONOTONIC && !__APPLE__ */
  112. /* gettimeofday wrapper, to keep recent_time updated */
  113. static int
  114. quagga_gettimeofday (struct timeval *tv)
  115. {
  116. int ret;
  117. assert (tv);
  118. if (!(ret = gettimeofday (&recent_time, NULL)))
  119. {
  120. /* init... */
  121. if (!timers_inited)
  122. {
  123. relative_time_base = last_recent_time = recent_time;
  124. timers_inited = 1;
  125. }
  126. /* avoid copy if user passed recent_time pointer.. */
  127. if (tv != &recent_time)
  128. *tv = recent_time;
  129. return 0;
  130. }
  131. return ret;
  132. }
  133. static int
  134. quagga_get_relative (struct timeval *tv)
  135. {
  136. int ret;
  137. #ifdef HAVE_CLOCK_MONOTONIC
  138. {
  139. struct timespec tp;
  140. if (!(ret = clock_gettime (CLOCK_MONOTONIC, &tp)))
  141. {
  142. relative_time.tv_sec = tp.tv_sec;
  143. relative_time.tv_usec = tp.tv_nsec / 1000;
  144. }
  145. }
  146. #elif defined(__APPLE__)
  147. {
  148. uint64_t ticks;
  149. uint64_t useconds;
  150. static mach_timebase_info_data_t timebase_info;
  151. ticks = mach_absolute_time();
  152. if (timebase_info.denom == 0)
  153. mach_timebase_info(&timebase_info);
  154. useconds = ticks * timebase_info.numer / timebase_info.denom / 1000;
  155. relative_time.tv_sec = useconds / 1000000;
  156. relative_time.tv_usec = useconds % 1000000;
  157. return 0;
  158. }
  159. #else /* !HAVE_CLOCK_MONOTONIC && !__APPLE__ */
  160. if (!(ret = quagga_gettimeofday (&recent_time)))
  161. quagga_gettimeofday_relative_adjust();
  162. #endif /* HAVE_CLOCK_MONOTONIC */
  163. if (tv)
  164. *tv = relative_time;
  165. return ret;
  166. }
  167. /* Get absolute time stamp, but in terms of the internal timer
  168. * Could be wrong, but at least won't go back.
  169. */
  170. static void
  171. quagga_real_stabilised (struct timeval *tv)
  172. {
  173. *tv = relative_time_base;
  174. tv->tv_sec += relative_time.tv_sec;
  175. tv->tv_usec += relative_time.tv_usec;
  176. *tv = timeval_adjust (*tv);
  177. }
  178. /* Exported Quagga timestamp function.
  179. * Modelled on POSIX clock_gettime.
  180. */
  181. int
  182. quagga_gettime (enum quagga_clkid clkid, struct timeval *tv)
  183. {
  184. switch (clkid)
  185. {
  186. case QUAGGA_CLK_REALTIME:
  187. return quagga_gettimeofday (tv);
  188. case QUAGGA_CLK_MONOTONIC:
  189. return quagga_get_relative (tv);
  190. case QUAGGA_CLK_REALTIME_STABILISED:
  191. quagga_real_stabilised (tv);
  192. return 0;
  193. default:
  194. errno = EINVAL;
  195. return -1;
  196. }
  197. }
  198. /* time_t value in terms of stabilised absolute time.
  199. * replacement for POSIX time()
  200. */
  201. time_t
  202. quagga_time (time_t *t)
  203. {
  204. struct timeval tv;
  205. quagga_real_stabilised (&tv);
  206. if (t)
  207. *t = tv.tv_sec;
  208. return tv.tv_sec;
  209. }
  210. /* Public export of recent_relative_time by value */
  211. struct timeval
  212. recent_relative_time (void)
  213. {
  214. return relative_time;
  215. }
  216. static unsigned int
  217. cpu_record_hash_key (struct cpu_thread_history *a)
  218. {
  219. return (uintptr_t) a->func;
  220. }
  221. static int
  222. cpu_record_hash_cmp (const struct cpu_thread_history *a,
  223. const struct cpu_thread_history *b)
  224. {
  225. return a->func == b->func;
  226. }
  227. static void *
  228. cpu_record_hash_alloc (struct cpu_thread_history *a)
  229. {
  230. struct cpu_thread_history *new;
  231. new = XCALLOC (MTYPE_THREAD_STATS, sizeof (struct cpu_thread_history));
  232. new->func = a->func;
  233. strcpy(new->funcname, a->funcname);
  234. return new;
  235. }
  236. static void
  237. cpu_record_hash_free (void *a)
  238. {
  239. struct cpu_thread_history *hist = a;
  240. XFREE (MTYPE_THREAD_STATS, hist);
  241. }
  242. static void
  243. vty_out_cpu_thread_history(struct vty* vty,
  244. struct cpu_thread_history *a)
  245. {
  246. #ifdef HAVE_RUSAGE
  247. vty_out(vty, "%7ld.%03ld %9d %8ld %9ld %8ld %9ld",
  248. a->cpu.total/1000, a->cpu.total%1000, a->total_calls,
  249. a->cpu.total/a->total_calls, a->cpu.max,
  250. a->real.total/a->total_calls, a->real.max);
  251. #else
  252. vty_out(vty, "%7ld.%03ld %9d %8ld %9ld",
  253. a->real.total/1000, a->real.total%1000, a->total_calls,
  254. a->real.total/a->total_calls, a->real.max);
  255. #endif
  256. vty_out(vty, " %c%c%c%c%c%c %s%s",
  257. a->types & (1 << THREAD_READ) ? 'R':' ',
  258. a->types & (1 << THREAD_WRITE) ? 'W':' ',
  259. a->types & (1 << THREAD_TIMER) ? 'T':' ',
  260. a->types & (1 << THREAD_EVENT) ? 'E':' ',
  261. a->types & (1 << THREAD_EXECUTE) ? 'X':' ',
  262. a->types & (1 << THREAD_BACKGROUND) ? 'B' : ' ',
  263. a->funcname, VTY_NEWLINE);
  264. }
  265. static void
  266. cpu_record_hash_print(struct hash_backet *bucket,
  267. void *args[])
  268. {
  269. struct cpu_thread_history *totals = args[0];
  270. struct vty *vty = args[1];
  271. thread_type *filter = args[2];
  272. struct cpu_thread_history *a = bucket->data;
  273. a = bucket->data;
  274. if ( !(a->types & *filter) )
  275. return;
  276. vty_out_cpu_thread_history(vty,a);
  277. totals->total_calls += a->total_calls;
  278. totals->real.total += a->real.total;
  279. if (totals->real.max < a->real.max)
  280. totals->real.max = a->real.max;
  281. #ifdef HAVE_RUSAGE
  282. totals->cpu.total += a->cpu.total;
  283. if (totals->cpu.max < a->cpu.max)
  284. totals->cpu.max = a->cpu.max;
  285. #endif
  286. }
  287. static void
  288. cpu_record_print(struct vty *vty, thread_type filter)
  289. {
  290. struct cpu_thread_history tmp;
  291. void *args[3] = {&tmp, vty, &filter};
  292. memset(&tmp, 0, sizeof tmp);
  293. strcpy(tmp.funcname, "TOTAL");
  294. tmp.types = filter;
  295. #ifdef HAVE_RUSAGE
  296. vty_out(vty, "%21s %18s %18s%s",
  297. "", "CPU (user+system):", "Real (wall-clock):", VTY_NEWLINE);
  298. #endif
  299. vty_out(vty, "Runtime(ms) Invoked Avg uSec Max uSecs");
  300. #ifdef HAVE_RUSAGE
  301. vty_out(vty, " Avg uSec Max uSecs");
  302. #endif
  303. vty_out(vty, " Type Thread%s", VTY_NEWLINE);
  304. hash_iterate(cpu_record,
  305. (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
  306. args);
  307. if (tmp.total_calls > 0)
  308. vty_out_cpu_thread_history(vty, &tmp);
  309. }
  310. DEFUN(show_thread_cpu,
  311. show_thread_cpu_cmd,
  312. "show thread cpu [FILTER]",
  313. SHOW_STR
  314. "Thread information\n"
  315. "Thread CPU usage\n"
  316. "Display filter (rwtexb)\n")
  317. {
  318. int i = 0;
  319. thread_type filter = (thread_type) -1U;
  320. if (argc > 0)
  321. {
  322. filter = 0;
  323. while (argv[0][i] != '\0')
  324. {
  325. switch ( argv[0][i] )
  326. {
  327. case 'r':
  328. case 'R':
  329. filter |= (1 << THREAD_READ);
  330. break;
  331. case 'w':
  332. case 'W':
  333. filter |= (1 << THREAD_WRITE);
  334. break;
  335. case 't':
  336. case 'T':
  337. filter |= (1 << THREAD_TIMER);
  338. break;
  339. case 'e':
  340. case 'E':
  341. filter |= (1 << THREAD_EVENT);
  342. break;
  343. case 'x':
  344. case 'X':
  345. filter |= (1 << THREAD_EXECUTE);
  346. break;
  347. case 'b':
  348. case 'B':
  349. filter |= (1 << THREAD_BACKGROUND);
  350. break;
  351. default:
  352. break;
  353. }
  354. ++i;
  355. }
  356. if (filter == 0)
  357. {
  358. vty_out(vty, "Invalid filter \"%s\" specified,"
  359. " must contain at least one of 'RWTEXB'%s",
  360. argv[0], VTY_NEWLINE);
  361. return CMD_WARNING;
  362. }
  363. }
  364. cpu_record_print(vty, filter);
  365. return CMD_SUCCESS;
  366. }
  367. static void
  368. cpu_record_hash_clear (struct hash_backet *bucket,
  369. void *args)
  370. {
  371. thread_type *filter = args;
  372. struct cpu_thread_history *a = bucket->data;
  373. a = bucket->data;
  374. if ( !(a->types & *filter) )
  375. return;
  376. hash_release (cpu_record, bucket->data);
  377. }
  378. static void
  379. cpu_record_clear (thread_type filter)
  380. {
  381. thread_type *tmp = &filter;
  382. hash_iterate (cpu_record,
  383. (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
  384. tmp);
  385. }
  386. DEFUN(clear_thread_cpu,
  387. clear_thread_cpu_cmd,
  388. "clear thread cpu [FILTER]",
  389. "Clear stored data\n"
  390. "Thread information\n"
  391. "Thread CPU usage\n"
  392. "Display filter (rwtexb)\n")
  393. {
  394. int i = 0;
  395. thread_type filter = (thread_type) -1U;
  396. if (argc > 0)
  397. {
  398. filter = 0;
  399. while (argv[0][i] != '\0')
  400. {
  401. switch ( argv[0][i] )
  402. {
  403. case 'r':
  404. case 'R':
  405. filter |= (1 << THREAD_READ);
  406. break;
  407. case 'w':
  408. case 'W':
  409. filter |= (1 << THREAD_WRITE);
  410. break;
  411. case 't':
  412. case 'T':
  413. filter |= (1 << THREAD_TIMER);
  414. break;
  415. case 'e':
  416. case 'E':
  417. filter |= (1 << THREAD_EVENT);
  418. break;
  419. case 'x':
  420. case 'X':
  421. filter |= (1 << THREAD_EXECUTE);
  422. break;
  423. case 'b':
  424. case 'B':
  425. filter |= (1 << THREAD_BACKGROUND);
  426. break;
  427. default:
  428. break;
  429. }
  430. ++i;
  431. }
  432. if (filter == 0)
  433. {
  434. vty_out(vty, "Invalid filter \"%s\" specified,"
  435. " must contain at least one of 'RWTEXB'%s",
  436. argv[0], VTY_NEWLINE);
  437. return CMD_WARNING;
  438. }
  439. }
  440. cpu_record_clear (filter);
  441. return CMD_SUCCESS;
  442. }
  443. static int
  444. thread_timer_cmp(void *a, void *b)
  445. {
  446. struct thread *thread_a = a;
  447. struct thread *thread_b = b;
  448. long cmp = timeval_cmp(thread_a->u.sands, thread_b->u.sands);
  449. if (cmp < 0)
  450. return -1;
  451. if (cmp > 0)
  452. return 1;
  453. return 0;
  454. }
  455. static void
  456. thread_timer_update(void *node, int actual_position)
  457. {
  458. struct thread *thread = node;
  459. thread->index = actual_position;
  460. }
  461. /* Allocate new thread master. */
  462. struct thread_master *
  463. thread_master_create ()
  464. {
  465. struct thread_master *rv;
  466. if (cpu_record == NULL)
  467. cpu_record
  468. = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
  469. (int (*) (const void *, const void *))cpu_record_hash_cmp);
  470. rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
  471. /* Initialize the timer queues */
  472. rv->timer = pqueue_create();
  473. rv->background = pqueue_create();
  474. rv->timer->cmp = rv->background->cmp = thread_timer_cmp;
  475. rv->timer->update = rv->background->update = thread_timer_update;
  476. return rv;
  477. }
  478. /* Add a new thread to the list. */
  479. static void
  480. thread_list_add (struct thread_list *list, struct thread *thread)
  481. {
  482. thread->next = NULL;
  483. thread->prev = list->tail;
  484. if (list->tail)
  485. list->tail->next = thread;
  486. else
  487. list->head = thread;
  488. list->tail = thread;
  489. list->count++;
  490. }
  491. /* Delete a thread from the list. */
  492. static struct thread *
  493. thread_list_delete (struct thread_list *list, struct thread *thread)
  494. {
  495. if (thread->next)
  496. thread->next->prev = thread->prev;
  497. else
  498. list->tail = thread->prev;
  499. if (thread->prev)
  500. thread->prev->next = thread->next;
  501. else
  502. list->head = thread->next;
  503. thread->next = thread->prev = NULL;
  504. list->count--;
  505. return thread;
  506. }
  507. /* Move thread to unuse list. */
  508. static void
  509. thread_add_unuse (struct thread_master *m, struct thread *thread)
  510. {
  511. assert (m != NULL && thread != NULL);
  512. assert (thread->next == NULL);
  513. assert (thread->prev == NULL);
  514. assert (thread->type == THREAD_UNUSED);
  515. thread_list_add (&m->unuse, thread);
  516. /* XXX: Should we deallocate funcname here? */
  517. }
  518. /* Free all unused thread. */
  519. static void
  520. thread_list_free (struct thread_master *m, struct thread_list *list)
  521. {
  522. struct thread *t;
  523. struct thread *next;
  524. for (t = list->head; t; t = next)
  525. {
  526. next = t->next;
  527. XFREE (MTYPE_THREAD, t);
  528. list->count--;
  529. m->alloc--;
  530. }
  531. }
  532. static void
  533. thread_queue_free (struct thread_master *m, struct pqueue *queue)
  534. {
  535. int i;
  536. for (i = 0; i < queue->size; i++)
  537. XFREE(MTYPE_THREAD, queue->array[i]);
  538. m->alloc -= queue->size;
  539. pqueue_delete(queue);
  540. }
  541. /* Stop thread scheduler. */
  542. void
  543. thread_master_free (struct thread_master *m)
  544. {
  545. thread_list_free (m, &m->read);
  546. thread_list_free (m, &m->write);
  547. thread_queue_free (m, m->timer);
  548. thread_list_free (m, &m->event);
  549. thread_list_free (m, &m->ready);
  550. thread_list_free (m, &m->unuse);
  551. thread_queue_free (m, m->background);
  552. XFREE (MTYPE_THREAD_MASTER, m);
  553. if (cpu_record)
  554. {
  555. hash_clean (cpu_record, cpu_record_hash_free);
  556. hash_free (cpu_record);
  557. cpu_record = NULL;
  558. }
  559. }
  560. /* Thread list is empty or not. */
  561. static int
  562. thread_empty (struct thread_list *list)
  563. {
  564. return list->head ? 0 : 1;
  565. }
  566. /* Delete top of the list and return it. */
  567. static struct thread *
  568. thread_trim_head (struct thread_list *list)
  569. {
  570. if (!thread_empty (list))
  571. return thread_list_delete (list, list->head);
  572. return NULL;
  573. }
  574. /* Return remain time in second. */
  575. unsigned long
  576. thread_timer_remain_second (struct thread *thread)
  577. {
  578. quagga_get_relative (NULL);
  579. if (thread->u.sands.tv_sec - relative_time.tv_sec > 0)
  580. return thread->u.sands.tv_sec - relative_time.tv_sec;
  581. else
  582. return 0;
  583. }
  584. /* Trim blankspace and "()"s */
  585. void
  586. strip_funcname (char *dest, const char *funcname)
  587. {
  588. char buff[FUNCNAME_LEN];
  589. char tmp, *e, *b = buff;
  590. strncpy(buff, funcname, sizeof(buff));
  591. buff[ sizeof(buff) -1] = '\0';
  592. e = buff +strlen(buff) -1;
  593. /* Wont work for funcname == "Word (explanation)" */
  594. while (*b == ' ' || *b == '(')
  595. ++b;
  596. while (*e == ' ' || *e == ')')
  597. --e;
  598. e++;
  599. tmp = *e;
  600. *e = '\0';
  601. strcpy (dest, b);
  602. *e = tmp;
  603. }
  604. /* Get new thread. */
  605. static struct thread *
  606. thread_get (struct thread_master *m, u_char type,
  607. int (*func) (struct thread *), void *arg, const char* funcname)
  608. {
  609. struct thread *thread = thread_trim_head (&m->unuse);
  610. if (! thread)
  611. {
  612. thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
  613. m->alloc++;
  614. }
  615. thread->type = type;
  616. thread->add_type = type;
  617. thread->master = m;
  618. thread->func = func;
  619. thread->arg = arg;
  620. thread->index = -1;
  621. strip_funcname (thread->funcname, funcname);
  622. return thread;
  623. }
  624. /* Add new read thread. */
  625. struct thread *
  626. funcname_thread_add_read (struct thread_master *m,
  627. int (*func) (struct thread *), void *arg, int fd, const char* funcname)
  628. {
  629. struct thread *thread;
  630. assert (m != NULL);
  631. if (FD_ISSET (fd, &m->readfd))
  632. {
  633. zlog (NULL, LOG_WARNING, "There is already read fd [%d]", fd);
  634. return NULL;
  635. }
  636. thread = thread_get (m, THREAD_READ, func, arg, funcname);
  637. FD_SET (fd, &m->readfd);
  638. thread->u.fd = fd;
  639. thread_list_add (&m->read, thread);
  640. return thread;
  641. }
  642. /* Add new write thread. */
  643. struct thread *
  644. funcname_thread_add_write (struct thread_master *m,
  645. int (*func) (struct thread *), void *arg, int fd, const char* funcname)
  646. {
  647. struct thread *thread;
  648. assert (m != NULL);
  649. if (FD_ISSET (fd, &m->writefd))
  650. {
  651. zlog (NULL, LOG_WARNING, "There is already write fd [%d]", fd);
  652. return NULL;
  653. }
  654. thread = thread_get (m, THREAD_WRITE, func, arg, funcname);
  655. FD_SET (fd, &m->writefd);
  656. thread->u.fd = fd;
  657. thread_list_add (&m->write, thread);
  658. return thread;
  659. }
  660. static struct thread *
  661. funcname_thread_add_timer_timeval (struct thread_master *m,
  662. int (*func) (struct thread *),
  663. int type,
  664. void *arg,
  665. struct timeval *time_relative,
  666. const char* funcname)
  667. {
  668. struct thread *thread;
  669. struct pqueue *queue;
  670. struct timeval alarm_time;
  671. assert (m != NULL);
  672. assert (type == THREAD_TIMER || type == THREAD_BACKGROUND);
  673. assert (time_relative);
  674. queue = ((type == THREAD_TIMER) ? m->timer : m->background);
  675. thread = thread_get (m, type, func, arg, funcname);
  676. /* Do we need jitter here? */
  677. quagga_get_relative (NULL);
  678. alarm_time.tv_sec = relative_time.tv_sec + time_relative->tv_sec;
  679. alarm_time.tv_usec = relative_time.tv_usec + time_relative->tv_usec;
  680. thread->u.sands = timeval_adjust(alarm_time);
  681. pqueue_enqueue(thread, queue);
  682. return thread;
  683. }
  684. /* Add timer event thread. */
  685. struct thread *
  686. funcname_thread_add_timer (struct thread_master *m,
  687. int (*func) (struct thread *),
  688. void *arg, long timer, const char* funcname)
  689. {
  690. struct timeval trel;
  691. assert (m != NULL);
  692. trel.tv_sec = timer;
  693. trel.tv_usec = 0;
  694. return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg,
  695. &trel, funcname);
  696. }
  697. /* Add timer event thread with "millisecond" resolution */
  698. struct thread *
  699. funcname_thread_add_timer_msec (struct thread_master *m,
  700. int (*func) (struct thread *),
  701. void *arg, long timer, const char* funcname)
  702. {
  703. struct timeval trel;
  704. assert (m != NULL);
  705. trel.tv_sec = timer / 1000;
  706. trel.tv_usec = 1000*(timer % 1000);
  707. return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER,
  708. arg, &trel, funcname);
  709. }
  710. /* Add a background thread, with an optional millisec delay */
  711. struct thread *
  712. funcname_thread_add_background (struct thread_master *m,
  713. int (*func) (struct thread *),
  714. void *arg, long delay,
  715. const char *funcname)
  716. {
  717. struct timeval trel;
  718. assert (m != NULL);
  719. if (delay)
  720. {
  721. trel.tv_sec = delay / 1000;
  722. trel.tv_usec = 1000*(delay % 1000);
  723. }
  724. else
  725. {
  726. trel.tv_sec = 0;
  727. trel.tv_usec = 0;
  728. }
  729. return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND,
  730. arg, &trel, funcname);
  731. }
  732. /* Add simple event thread. */
  733. struct thread *
  734. funcname_thread_add_event (struct thread_master *m,
  735. int (*func) (struct thread *), void *arg, int val, const char* funcname)
  736. {
  737. struct thread *thread;
  738. assert (m != NULL);
  739. thread = thread_get (m, THREAD_EVENT, func, arg, funcname);
  740. thread->u.val = val;
  741. thread_list_add (&m->event, thread);
  742. return thread;
  743. }
  744. /* Cancel thread from scheduler. */
  745. void
  746. thread_cancel (struct thread *thread)
  747. {
  748. struct thread_list *list = NULL;
  749. struct pqueue *queue = NULL;
  750. switch (thread->type)
  751. {
  752. case THREAD_READ:
  753. assert (FD_ISSET (thread->u.fd, &thread->master->readfd));
  754. FD_CLR (thread->u.fd, &thread->master->readfd);
  755. list = &thread->master->read;
  756. break;
  757. case THREAD_WRITE:
  758. assert (FD_ISSET (thread->u.fd, &thread->master->writefd));
  759. FD_CLR (thread->u.fd, &thread->master->writefd);
  760. list = &thread->master->write;
  761. break;
  762. case THREAD_TIMER:
  763. queue = thread->master->timer;
  764. break;
  765. case THREAD_EVENT:
  766. list = &thread->master->event;
  767. break;
  768. case THREAD_READY:
  769. list = &thread->master->ready;
  770. break;
  771. case THREAD_BACKGROUND:
  772. queue = thread->master->background;
  773. break;
  774. default:
  775. return;
  776. break;
  777. }
  778. if (queue)
  779. {
  780. assert(thread->index >= 0);
  781. assert(thread == queue->array[thread->index]);
  782. pqueue_remove_at(thread->index, queue);
  783. }
  784. else if (list)
  785. {
  786. thread_list_delete (list, thread);
  787. }
  788. else
  789. {
  790. assert(!"Thread should be either in queue or list!");
  791. }
  792. thread->type = THREAD_UNUSED;
  793. thread_add_unuse (thread->master, thread);
  794. }
  795. /* Delete all events which has argument value arg. */
  796. unsigned int
  797. thread_cancel_event (struct thread_master *m, void *arg)
  798. {
  799. unsigned int ret = 0;
  800. struct thread *thread;
  801. thread = m->event.head;
  802. while (thread)
  803. {
  804. struct thread *t;
  805. t = thread;
  806. thread = t->next;
  807. if (t->arg == arg)
  808. {
  809. ret++;
  810. thread_list_delete (&m->event, t);
  811. t->type = THREAD_UNUSED;
  812. thread_add_unuse (m, t);
  813. }
  814. }
  815. /* thread can be on the ready list too */
  816. thread = m->ready.head;
  817. while (thread)
  818. {
  819. struct thread *t;
  820. t = thread;
  821. thread = t->next;
  822. if (t->arg == arg)
  823. {
  824. ret++;
  825. thread_list_delete (&m->ready, t);
  826. t->type = THREAD_UNUSED;
  827. thread_add_unuse (m, t);
  828. }
  829. }
  830. return ret;
  831. }
  832. static struct timeval *
  833. thread_timer_wait (struct pqueue *queue, struct timeval *timer_val)
  834. {
  835. if (queue->size)
  836. {
  837. struct thread *next_timer = queue->array[0];
  838. *timer_val = timeval_subtract (next_timer->u.sands, relative_time);
  839. return timer_val;
  840. }
  841. return NULL;
  842. }
  843. static struct thread *
  844. thread_run (struct thread_master *m, struct thread *thread,
  845. struct thread *fetch)
  846. {
  847. *fetch = *thread;
  848. thread->type = THREAD_UNUSED;
  849. thread_add_unuse (m, thread);
  850. return fetch;
  851. }
  852. static int
  853. thread_process_fd (struct thread_list *list, fd_set *fdset, fd_set *mfdset)
  854. {
  855. struct thread *thread;
  856. struct thread *next;
  857. int ready = 0;
  858. assert (list);
  859. for (thread = list->head; thread; thread = next)
  860. {
  861. next = thread->next;
  862. if (FD_ISSET (THREAD_FD (thread), fdset))
  863. {
  864. assert (FD_ISSET (THREAD_FD (thread), mfdset));
  865. FD_CLR(THREAD_FD (thread), mfdset);
  866. thread_list_delete (list, thread);
  867. thread_list_add (&thread->master->ready, thread);
  868. thread->type = THREAD_READY;
  869. ready++;
  870. }
  871. }
  872. return ready;
  873. }
  874. /* Add all timers that have popped to the ready list. */
  875. static unsigned int
  876. thread_timer_process (struct pqueue *queue, struct timeval *timenow)
  877. {
  878. struct thread *thread;
  879. unsigned int ready = 0;
  880. while (queue->size)
  881. {
  882. thread = queue->array[0];
  883. if (timeval_cmp (*timenow, thread->u.sands) < 0)
  884. return ready;
  885. pqueue_dequeue(queue);
  886. thread->type = THREAD_READY;
  887. thread_list_add (&thread->master->ready, thread);
  888. ready++;
  889. }
  890. return ready;
  891. }
  892. /* process a list en masse, e.g. for event thread lists */
  893. static unsigned int
  894. thread_process (struct thread_list *list)
  895. {
  896. struct thread *thread;
  897. struct thread *next;
  898. unsigned int ready = 0;
  899. for (thread = list->head; thread; thread = next)
  900. {
  901. next = thread->next;
  902. thread_list_delete (list, thread);
  903. thread->type = THREAD_READY;
  904. thread_list_add (&thread->master->ready, thread);
  905. ready++;
  906. }
  907. return ready;
  908. }
  909. /* Fetch next ready thread. */
  910. struct thread *
  911. thread_fetch (struct thread_master *m, struct thread *fetch)
  912. {
  913. struct thread *thread;
  914. fd_set readfd;
  915. fd_set writefd;
  916. fd_set exceptfd;
  917. struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
  918. struct timeval timer_val_bg;
  919. struct timeval *timer_wait = &timer_val;
  920. struct timeval *timer_wait_bg;
  921. while (1)
  922. {
  923. int num = 0;
  924. #if defined HAVE_SNMP && defined SNMP_AGENTX
  925. struct timeval snmp_timer_wait;
  926. int snmpblock = 0;
  927. int fdsetsize;
  928. #endif
  929. /* Signals pre-empt everything */
  930. quagga_sigevent_process ();
  931. /* Drain the ready queue of already scheduled jobs, before scheduling
  932. * more.
  933. */
  934. if ((thread = thread_trim_head (&m->ready)) != NULL)
  935. return thread_run (m, thread, fetch);
  936. /* To be fair to all kinds of threads, and avoid starvation, we
  937. * need to be careful to consider all thread types for scheduling
  938. * in each quanta. I.e. we should not return early from here on.
  939. */
  940. /* Normal event are the next highest priority. */
  941. thread_process (&m->event);
  942. /* Structure copy. */
  943. readfd = m->readfd;
  944. writefd = m->writefd;
  945. exceptfd = m->exceptfd;
  946. /* Calculate select wait timer if nothing else to do */
  947. if (m->ready.count == 0)
  948. {
  949. quagga_get_relative (NULL);
  950. timer_wait = thread_timer_wait (m->timer, &timer_val);
  951. timer_wait_bg = thread_timer_wait (m->background, &timer_val_bg);
  952. if (timer_wait_bg &&
  953. (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
  954. timer_wait = timer_wait_bg;
  955. }
  956. #if defined HAVE_SNMP && defined SNMP_AGENTX
  957. /* When SNMP is enabled, we may have to select() on additional
  958. FD. snmp_select_info() will add them to `readfd'. The trick
  959. with this function is its last argument. We need to set it to
  960. 0 if timer_wait is not NULL and we need to use the provided
  961. new timer only if it is still set to 0. */
  962. if (agentx_enabled)
  963. {
  964. fdsetsize = FD_SETSIZE;
  965. snmpblock = 1;
  966. if (timer_wait)
  967. {
  968. snmpblock = 0;
  969. memcpy(&snmp_timer_wait, timer_wait, sizeof(struct timeval));
  970. }
  971. snmp_select_info(&fdsetsize, &readfd, &snmp_timer_wait, &snmpblock);
  972. if (snmpblock == 0)
  973. timer_wait = &snmp_timer_wait;
  974. }
  975. #endif
  976. num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
  977. /* Signals should get quick treatment */
  978. if (num < 0)
  979. {
  980. if (errno == EINTR)
  981. continue; /* signal received - process it */
  982. zlog_warn ("select() error: %s", safe_strerror (errno));
  983. return NULL;
  984. }
  985. #if defined HAVE_SNMP && defined SNMP_AGENTX
  986. if (agentx_enabled)
  987. {
  988. if (num > 0)
  989. snmp_read(&readfd);
  990. else if (num == 0)
  991. {
  992. snmp_timeout();
  993. run_alarms();
  994. }
  995. netsnmp_check_outstanding_agent_requests();
  996. }
  997. #endif
  998. /* Check foreground timers. Historically, they have had higher
  999. priority than I/O threads, so let's push them onto the ready
  1000. list in front of the I/O threads. */
  1001. quagga_get_relative (NULL);
  1002. thread_timer_process (m->timer, &relative_time);
  1003. /* Got IO, process it */
  1004. if (num > 0)
  1005. {
  1006. /* Normal priority read thead. */
  1007. thread_process_fd (&m->read, &readfd, &m->readfd);
  1008. /* Write thead. */
  1009. thread_process_fd (&m->write, &writefd, &m->writefd);
  1010. }
  1011. #if 0
  1012. /* If any threads were made ready above (I/O or foreground timer),
  1013. perhaps we should avoid adding background timers to the ready
  1014. list at this time. If this is code is uncommented, then background
  1015. timer threads will not run unless there is nothing else to do. */
  1016. if ((thread = thread_trim_head (&m->ready)) != NULL)
  1017. return thread_run (m, thread, fetch);
  1018. #endif
  1019. /* Background timer/events, lowest priority */
  1020. thread_timer_process (m->background, &relative_time);
  1021. if ((thread = thread_trim_head (&m->ready)) != NULL)
  1022. return thread_run (m, thread, fetch);
  1023. }
  1024. }
  1025. unsigned long
  1026. thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start, unsigned long *cputime)
  1027. {
  1028. #ifdef HAVE_RUSAGE
  1029. /* This is 'user + sys' time. */
  1030. *cputime = timeval_elapsed (now->cpu.ru_utime, start->cpu.ru_utime) +
  1031. timeval_elapsed (now->cpu.ru_stime, start->cpu.ru_stime);
  1032. #else
  1033. *cputime = 0;
  1034. #endif /* HAVE_RUSAGE */
  1035. return timeval_elapsed (now->real, start->real);
  1036. }
  1037. /* We should aim to yield after THREAD_YIELD_TIME_SLOT milliseconds.
  1038. Note: we are using real (wall clock) time for this calculation.
  1039. It could be argued that CPU time may make more sense in certain
  1040. contexts. The things to consider are whether the thread may have
  1041. blocked (in which case wall time increases, but CPU time does not),
  1042. or whether the system is heavily loaded with other processes competing
  1043. for CPU time. On balance, wall clock time seems to make sense.
  1044. Plus it has the added benefit that gettimeofday should be faster
  1045. than calling getrusage. */
  1046. int
  1047. thread_should_yield (struct thread *thread)
  1048. {
  1049. quagga_get_relative (NULL);
  1050. return (timeval_elapsed(relative_time, thread->real) >
  1051. THREAD_YIELD_TIME_SLOT);
  1052. }
  1053. void
  1054. thread_getrusage (RUSAGE_T *r)
  1055. {
  1056. quagga_get_relative (NULL);
  1057. #ifdef HAVE_RUSAGE
  1058. getrusage(RUSAGE_SELF, &(r->cpu));
  1059. #endif
  1060. r->real = relative_time;
  1061. #ifdef HAVE_CLOCK_MONOTONIC
  1062. /* quagga_get_relative() only updates recent_time if gettimeofday
  1063. * based, not when using CLOCK_MONOTONIC. As we export recent_time
  1064. * and guarantee to update it before threads are run...
  1065. */
  1066. quagga_gettimeofday(&recent_time);
  1067. #endif /* HAVE_CLOCK_MONOTONIC */
  1068. }
  1069. /* We check thread consumed time. If the system has getrusage, we'll
  1070. use that to get in-depth stats on the performance of the thread in addition
  1071. to wall clock time stats from gettimeofday. */
  1072. void
  1073. thread_call (struct thread *thread)
  1074. {
  1075. unsigned long realtime, cputime;
  1076. RUSAGE_T before, after;
  1077. /* Cache a pointer to the relevant cpu history thread, if the thread
  1078. * does not have it yet.
  1079. *
  1080. * Callers submitting 'dummy threads' hence must take care that
  1081. * thread->cpu is NULL
  1082. */
  1083. if (!thread->hist)
  1084. {
  1085. struct cpu_thread_history tmp;
  1086. tmp.func = thread->func;
  1087. strcpy(tmp.funcname, thread->funcname);
  1088. thread->hist = hash_get (cpu_record, &tmp,
  1089. (void * (*) (void *))cpu_record_hash_alloc);
  1090. }
  1091. GETRUSAGE (&before);
  1092. thread->real = before.real;
  1093. (*thread->func) (thread);
  1094. GETRUSAGE (&after);
  1095. realtime = thread_consumed_time (&after, &before, &cputime);
  1096. thread->hist->real.total += realtime;
  1097. if (thread->hist->real.max < realtime)
  1098. thread->hist->real.max = realtime;
  1099. #ifdef HAVE_RUSAGE
  1100. thread->hist->cpu.total += cputime;
  1101. if (thread->hist->cpu.max < cputime)
  1102. thread->hist->cpu.max = cputime;
  1103. #endif
  1104. ++(thread->hist->total_calls);
  1105. thread->hist->types |= (1 << thread->add_type);
  1106. #ifdef CONSUMED_TIME_CHECK
  1107. if (realtime > CONSUMED_TIME_CHECK)
  1108. {
  1109. /*
  1110. * We have a CPU Hog on our hands.
  1111. * Whinge about it now, so we're aware this is yet another task
  1112. * to fix.
  1113. */
  1114. zlog_warn ("SLOW THREAD: task %s (%lx) ran for %lums (cpu time %lums)",
  1115. thread->funcname,
  1116. (unsigned long) thread->func,
  1117. realtime/1000, cputime/1000);
  1118. }
  1119. #endif /* CONSUMED_TIME_CHECK */
  1120. }
  1121. /* Execute thread */
  1122. struct thread *
  1123. funcname_thread_execute (struct thread_master *m,
  1124. int (*func)(struct thread *),
  1125. void *arg,
  1126. int val,
  1127. const char* funcname)
  1128. {
  1129. struct thread dummy;
  1130. memset (&dummy, 0, sizeof (struct thread));
  1131. dummy.type = THREAD_EVENT;
  1132. dummy.add_type = THREAD_EXECUTE;
  1133. dummy.master = NULL;
  1134. dummy.func = func;
  1135. dummy.arg = arg;
  1136. dummy.u.val = val;
  1137. strip_funcname (dummy.funcname, funcname);
  1138. thread_call (&dummy);
  1139. return NULL;
  1140. }