File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / thread.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:39 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    1: /* Thread management routine header.
    2:  * Copyright (C) 1998 Kunihiro Ishiguro
    3:  * Portions Copyright (c) 2008 Everton da Silva Marques <everton.marques@gmail.com>
    4:  *
    5:  * This file is part of GNU Zebra.
    6:  *
    7:  * GNU Zebra is free software; you can redistribute it and/or modify it
    8:  * under the terms of the GNU General Public License as published by the
    9:  * Free Software Foundation; either version 2, or (at your option) any
   10:  * later version.
   11:  *
   12:  * GNU Zebra is distributed in the hope that it will be useful, but
   13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15:  * General Public License for more details.
   16:  *
   17:  * You should have received a copy of the GNU General Public License
   18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20:  * 02111-1307, USA.  
   21:  */
   22: 
   23: #ifndef _ZEBRA_THREAD_H
   24: #define _ZEBRA_THREAD_H
   25: 
   26: #include <zebra.h>
   27: 
   28: struct rusage_t
   29: {
   30: #ifdef HAVE_RUSAGE
   31:   struct rusage cpu;
   32: #endif
   33:   struct timeval real;
   34: };
   35: #define RUSAGE_T        struct rusage_t
   36: 
   37: #define GETRUSAGE(X) thread_getrusage(X)
   38: 
   39: /* Linked list of thread. */
   40: struct thread_list
   41: {
   42:   struct thread *head;
   43:   struct thread *tail;
   44:   int count;
   45: };
   46: 
   47: /* Master of the theads. */
   48: struct thread_master
   49: {
   50:   struct thread_list read;
   51:   struct thread_list write;
   52:   struct thread_list timer;
   53:   struct thread_list event;
   54:   struct thread_list ready;
   55:   struct thread_list unuse;
   56:   struct thread_list background;
   57:   fd_set readfd;
   58:   fd_set writefd;
   59:   fd_set exceptfd;
   60:   unsigned long alloc;
   61: };
   62: 
   63: typedef unsigned char thread_type;
   64: 
   65: /* ISO C99 maximum function name length is 63 */
   66: #define FUNCNAME_LEN	64
   67: 
   68: /* Thread itself. */
   69: struct thread
   70: {
   71:   thread_type type;		/* thread type */
   72:   thread_type add_type;		/* thread type */
   73:   struct thread *next;		/* next pointer of the thread */   
   74:   struct thread *prev;		/* previous pointer of the thread */
   75:   struct thread_master *master;	/* pointer to the struct thread_master. */
   76:   int (*func) (struct thread *); /* event function */
   77:   void *arg;			/* event argument */
   78:   union {
   79:     int val;			/* second argument of the event. */
   80:     int fd;			/* file descriptor in case of read/write. */
   81:     struct timeval sands;	/* rest of time sands value. */
   82:   } u;
   83:   struct timeval real;
   84:   struct cpu_thread_history *hist; /* cache pointer to cpu_history */
   85:   char funcname[FUNCNAME_LEN];
   86: };
   87: 
   88: struct cpu_thread_history 
   89: {
   90:   int (*func)(struct thread *);
   91:   unsigned int total_calls;
   92:   struct time_stats
   93:   {
   94:     unsigned long total, max;
   95:   } real;
   96: #ifdef HAVE_RUSAGE
   97:   struct time_stats cpu;
   98: #endif
   99:   thread_type types;
  100:   char funcname[FUNCNAME_LEN];
  101: };
  102: 
  103: /* Clocks supported by Quagga */
  104: enum quagga_clkid {
  105:   QUAGGA_CLK_REALTIME = 0,	/* ala gettimeofday() */
  106:   QUAGGA_CLK_MONOTONIC,		/* monotonic, against an indeterminate base */
  107:   QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */
  108: };
  109: 
  110: /* Thread types. */
  111: #define THREAD_READ           0
  112: #define THREAD_WRITE          1
  113: #define THREAD_TIMER          2
  114: #define THREAD_EVENT          3
  115: #define THREAD_READY          4
  116: #define THREAD_BACKGROUND     5
  117: #define THREAD_UNUSED         6
  118: #define THREAD_EXECUTE        7
  119: 
  120: /* Thread yield time.  */
  121: #define THREAD_YIELD_TIME_SLOT     10 * 1000L /* 10ms */
  122: 
  123: /* Macros. */
  124: #define THREAD_ARG(X) ((X)->arg)
  125: #define THREAD_FD(X)  ((X)->u.fd)
  126: #define THREAD_VAL(X) ((X)->u.val)
  127: 
  128: #define THREAD_READ_ON(master,thread,func,arg,sock) \
  129:   do { \
  130:     if (! thread) \
  131:       thread = thread_add_read (master, func, arg, sock); \
  132:   } while (0)
  133: 
  134: #define THREAD_WRITE_ON(master,thread,func,arg,sock) \
  135:   do { \
  136:     if (! thread) \
  137:       thread = thread_add_write (master, func, arg, sock); \
  138:   } while (0)
  139: 
  140: #define THREAD_TIMER_ON(master,thread,func,arg,time) \
  141:   do { \
  142:     if (! thread) \
  143:       thread = thread_add_timer (master, func, arg, time); \
  144:   } while (0)
  145: 
  146: #define THREAD_TIMER_MSEC_ON(master,thread,func,arg,time) \
  147:   do { \
  148:     if (! thread) \
  149:       thread = thread_add_timer_msec (master, func, arg, time); \
  150:   } while (0)
  151: 
  152: #define THREAD_OFF(thread) \
  153:   do { \
  154:     if (thread) \
  155:       { \
  156:         thread_cancel (thread); \
  157:         thread = NULL; \
  158:       } \
  159:   } while (0)
  160: 
  161: #define THREAD_READ_OFF(thread)  THREAD_OFF(thread)
  162: #define THREAD_WRITE_OFF(thread)  THREAD_OFF(thread)
  163: #define THREAD_TIMER_OFF(thread)  THREAD_OFF(thread)
  164: 
  165: #define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f)
  166: #define thread_add_write(m,f,a,v) funcname_thread_add_write(m,f,a,v,#f)
  167: #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f)
  168: #define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
  169: #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
  170: #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
  171: 
  172: /* The 4th arg to thread_add_background is the # of milliseconds to delay. */
  173: #define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f)
  174: 
  175: /* Prototypes. */
  176: extern struct thread_master *thread_master_create (void);
  177: extern void thread_master_free (struct thread_master *);
  178: 
  179: extern struct thread *funcname_thread_add_read (struct thread_master *, 
  180: 				                int (*)(struct thread *),
  181: 				                void *, int, const char*);
  182: extern struct thread *funcname_thread_add_write (struct thread_master *,
  183: 				                 int (*)(struct thread *),
  184: 				                 void *, int, const char*);
  185: extern struct thread *funcname_thread_add_timer (struct thread_master *,
  186: 				                 int (*)(struct thread *),
  187: 				                 void *, long, const char*);
  188: extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
  189: 				                      int (*)(struct thread *),
  190: 				                      void *, long, const char*);
  191: extern struct thread *funcname_thread_add_event (struct thread_master *,
  192: 				                 int (*)(struct thread *),
  193: 				                 void *, int, const char*);
  194: extern struct thread *funcname_thread_add_background (struct thread_master *,
  195:                                                int (*func)(struct thread *),
  196: 				               void *arg,
  197: 				               long milliseconds_to_delay,
  198: 					       const char *funcname);
  199: extern struct thread *funcname_thread_execute (struct thread_master *,
  200:                                                int (*)(struct thread *),
  201:                                                void *, int, const char *);
  202: extern void thread_cancel (struct thread *);
  203: extern unsigned int thread_cancel_event (struct thread_master *, void *);
  204: extern struct thread *thread_fetch (struct thread_master *, struct thread *);
  205: extern void thread_call (struct thread *);
  206: extern unsigned long thread_timer_remain_second (struct thread *);
  207: extern int thread_should_yield (struct thread *);
  208: 
  209: /* Internal libzebra exports */
  210: extern void thread_getrusage (RUSAGE_T *);
  211: extern struct cmd_element show_thread_cpu_cmd;
  212: extern struct cmd_element clear_thread_cpu_cmd;
  213: 
  214: /* replacements for the system gettimeofday(), clock_gettime() and
  215:  * time() functions, providing support for non-decrementing clock on
  216:  * all systems, and fully monotonic on /some/ systems.
  217:  */
  218: extern int quagga_gettime (enum quagga_clkid, struct timeval *);
  219: extern time_t quagga_time (time_t *);
  220: 
  221: /* Returns elapsed real (wall clock) time. */
  222: extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
  223: 					  unsigned long *cpu_time_elapsed);
  224: 
  225: /* Global variable containing a recent result from gettimeofday.  This can
  226:    be used instead of calling gettimeofday if a recent value is sufficient.
  227:    This is guaranteed to be refreshed before a thread is called. */
  228: extern struct timeval recent_time;
  229: /* Similar to recent_time, but a monotonically increasing time value */
  230: extern struct timeval recent_relative_time (void);
  231: #endif /* _ZEBRA_THREAD_H */

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