Annotation of embedaddon/quagga/tests/heavy-thread.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>