Annotation of embedaddon/quagga/tests/heavy-wq.c, revision 1.1.1.1
1.1 misho 1: /*
2: * This file is part of Quagga.
3: *
4: * Quagga is free software; you can redistribute it and/or modify it
5: * under the terms of the GNU General Public License as published by the
6: * Free Software Foundation; either version 2, or (at your option) any
7: * later version.
8: *
9: * Quagga is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with Quagga; see the file COPYING. If not, write to the Free
16: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17: * 02111-1307, USA.
18: */
19:
20: /* This programme shows the effects of 'heavy' long-running functions
21: * on the cooperative threading model.
22: *
23: * Run it with a config file containing 'password whatever', telnet to it
24: * (it defaults to port 4000) and enter the 'clear foo string' command.
25: * then type whatever and observe that the vty interface is unresponsive
26: * for quite a period of time, due to the clear_something command
27: * taking a very long time to complete.
28: */
29: #include <zebra.h>
30:
31: #include "thread.h"
32: #include "vty.h"
33: #include "command.h"
34: #include "memory.h"
35: #include "log.h"
36: #include "workqueue.h"
37: #include <math.h>
38:
39: extern struct thread_master *master;
40: static struct work_queue *heavy_wq;
41:
42: struct heavy_wq_node
43: {
44: char *str;
45: int i;
46: };
47:
48: enum
49: {
50: ITERS_FIRST = 0,
51: ITERS_ERR = 100,
52: ITERS_LATER = 400,
53: ITERS_PRINT = 10,
54: ITERS_MAX = 1000,
55: };
56:
57: static void
58: heavy_wq_add (struct vty *vty, const char *str, int i)
59: {
60: struct heavy_wq_node *hn;
61:
62: if ((hn = XCALLOC (MTYPE_PREFIX_LIST, sizeof(struct heavy_wq_node))) == NULL)
63: {
64: zlog_err ("%s: unable to allocate hn", __func__);
65: return;
66: }
67:
68: hn->i = i;
69: if (!(hn->str = XSTRDUP (MTYPE_PREFIX_LIST_STR, str)))
70: {
71: zlog_err ("%s: unable to xstrdup", __func__);
72: XFREE (MTYPE_PREFIX_LIST, hn);
73: return;
74: }
75:
76: work_queue_add (heavy_wq, hn);
77:
78: return;
79: }
80:
81: static void
82: slow_func_err (struct work_queue *wq, struct work_queue_item *item)
83: {
84: printf ("%s: running error function\n", __func__);
85: }
86:
87: static void
88: slow_func_del (struct work_queue *wq, void *data)
89: {
90: struct heavy_wq_node *hn = data;
91: assert (hn && hn->str);
92: printf ("%s: %s\n", __func__, hn->str);
93: XFREE (MTYPE_PREFIX_LIST_STR, hn->str);
94: hn->str = NULL;
95: XFREE(MTYPE_PREFIX_LIST, hn);
96: }
97:
98: static wq_item_status
99: slow_func (struct work_queue *wq, void *data)
100: {
101: struct heavy_wq_node *hn = data;
102: double x = 1;
103: int j;
104:
105: assert (hn && hn->str);
106:
107: for (j = 0; j < 300; j++)
108: x += sin(x)*j;
109:
110: if ((hn->i % ITERS_LATER) == 0)
111: return WQ_RETRY_LATER;
112:
113: if ((hn->i % ITERS_ERR) == 0)
114: return WQ_RETRY_NOW;
115:
116: if ((hn->i % ITERS_PRINT) == 0)
117: printf ("%s did %d, x = %g\n", hn->str, hn->i, x);
118:
119: return WQ_SUCCESS;
120: }
121:
122: static void
123: clear_something (struct vty *vty, const char *str)
124: {
125: int i;
126:
127: /* this could be like iterating through 150k of route_table
128: * or worse, iterating through a list of peers, to bgp_stop them with
129: * each having 150k route tables to process...
130: */
131: for (i = ITERS_FIRST; i < ITERS_MAX; i++)
132: heavy_wq_add (vty, str, i);
133: }
134:
135: DEFUN (clear_foo,
136: clear_foo_cmd,
137: "clear foo .LINE",
138: "clear command\n"
139: "arbitrary string\n")
140: {
141: char *str;
142: if (!argc)
143: {
144: vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
145: return CMD_WARNING;
146: }
147:
148: str = argv_concat (argv, argc, 0);
149:
150: clear_something (vty, str);
151: XFREE (MTYPE_TMP, str);
152: return CMD_SUCCESS;
153: }
154:
155: static int
156: heavy_wq_init ()
157: {
158: if (! (heavy_wq = work_queue_new (master, "heavy_work_queue")))
159: {
160: zlog_err ("%s: could not get new work queue!", __func__);
161: return -1;
162: }
163:
164: heavy_wq->spec.workfunc = &slow_func;
165: heavy_wq->spec.errorfunc = &slow_func_err;
166: heavy_wq->spec.del_item_data = &slow_func_del;
167: heavy_wq->spec.max_retries = 3;
168: heavy_wq->spec.hold = 1000;
169:
170: return 0;
171: }
172:
173: void
174: test_init()
175: {
176: install_element (VIEW_NODE, &clear_foo_cmd);
177: heavy_wq_init();
178: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>