]> git.proxmox.com Git - mirror_frr.git/blame - tests/lib/test_heavy_thread.c
*: remove THREAD_BACKGROUND
[mirror_frr.git] / tests / lib / test_heavy_thread.c
CommitLineData
864c364d 1/*
9f3f7a11 2 * $Id: heavy-thread.c,v 1.2 2005/04/25 16:42:24 paul Exp $
864c364d 3 *
4 * This file is part of Quagga.
5 *
6 * Quagga 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 * Quagga 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 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
864c364d 19 */
20
21/* This programme shows the effects of 'heavy' long-running functions
22 * on the cooperative threading model, as demonstrated by heavy.c, and how
23 * they can be mitigated using a background thread.
24 *
25 * Run it with a config file containing 'password whatever', telnet to it
26 * (it defaults to port 4000) and enter the 'clear foo string' command.
27 * then type whatever and observe that, unlike heavy.c, the vty interface
28 * remains responsive.
29 */
30#include <zebra.h>
31#include <math.h>
32
864c364d 33#include "thread.h"
34#include "vty.h"
35#include "command.h"
36#include "memory.h"
37#include "log.h"
38
9fc3f9b3
DL
39#include "tests.h"
40
9f3f7a11 41extern struct thread_master *master;
864c364d 42
43enum
44{
45 ITERS_FIRST = 0,
46 ITERS_ERR = 100,
47 ITERS_LATER = 400,
48 ITERS_PRINT = 10,
49 ITERS_MAX = 1000,
50};
51
52struct work_state {
53 struct vty *vty;
54 char *str;
55 int i;
56};
57
58static void
59slow_func (struct vty *vty, const char *str, const int i)
60{
61 double x = 1;
62 int j;
63
9f3f7a11 64 for (j = 0; j < 300; j++)
864c364d 65 x += sin(x)*j;
66
67 if ((i % ITERS_LATER) == 0)
68 printf ("%s: %d, temporary error, save this somehow and do it later..\n",
69 __func__, i);
70
71 if ((i % ITERS_ERR) == 0)
72 printf ("%s: hard error\n", __func__);
73
74 if ((i % ITERS_PRINT) == 0)
75 printf ("%s did %d, x = %g\n", str, i, x);
76}
77
78static int
79clear_something (struct thread *thread)
80{
81 struct work_state *ws = THREAD_ARG(thread);
82
83 /* this could be like iterating through 150k of route_table
84 * or worse, iterating through a list of peers, to bgp_stop them with
85 * each having 150k route tables to process...
86 */
87 while (ws->i < ITERS_MAX)
88 {
89 slow_func(ws->vty, ws->str, ws->i);
90 ws->i++;
91 if (thread_should_yield(thread))
92 {
a587d00b 93 thread_add_timer_msec (master, clear_something, ws, 0, NULL);
864c364d 94 return 0;
95 }
96 }
97
98 /* All done! */
99 XFREE (MTYPE_TMP, ws->str);
100 XFREE (MTYPE_TMP, ws);
101 return 0;
102}
103
864c364d 104DEFUN (clear_foo,
105 clear_foo_cmd,
e961923c 106 "clear foo LINE...",
864c364d 107 "clear command\n"
108 "arbitrary string\n")
109{
110 char *str;
111 struct work_state *ws;
112
113 if (!argc)
114 {
115 vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
116 return CMD_WARNING;
117 }
118
119 str = argv_concat (argv, argc, 0);
120
121 if ((ws = XMALLOC(MTYPE_TMP, sizeof(*ws))) == NULL)
122 {
123 zlog_err ("%s: unable to allocate work_state", __func__);
124 return CMD_WARNING;
125 }
126
127 if (!(ws->str = XSTRDUP (MTYPE_TMP, str)))
128 {
129 zlog_err ("%s: unable to xstrdup", __func__);
130 XFREE (MTYPE_TMP, ws);
131 return CMD_WARNING;
132 }
133
134 ws->vty = vty;
135 ws->i = ITERS_FIRST;
136
a587d00b 137 thread_add_timer_msec (master, clear_something, ws, 0, NULL);
864c364d 138
139 return CMD_SUCCESS;
140}
141
9f3f7a11 142void
143test_init()
864c364d 144{
145 install_element (VIEW_NODE, &clear_foo_cmd);
864c364d 146}