1 /* Thread management routine header. 2 * Copyright (C) 1998 Kunihiro Ishiguro 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 22 #ifndef _THREAD_H_ 23 #define _THREAD_H_ 24 25 struct rusage_t 26 { 27 struct timeval real; 28 }; 29 #define RUSAGE_T struct rusage_t 30 31 #define GETRUSAGE(X) thread_getrusage(X) 32 33 /* Linked list of thread. */ 34 struct thread_list 35 { 36 struct thread *head; 37 struct thread *tail; 38 int count; 39 }; 40 41 /* Master of the theads. */ 42 struct thread_master 43 { 44 struct thread_list read; 45 struct thread_list write; 46 struct thread_list timer; 47 struct thread_list event; 48 struct thread_list ready; 49 struct thread_list unuse; 50 struct thread_list background; 51 fd_set readfd; 52 fd_set writefd; 53 fd_set exceptfd; 54 unsigned long alloc; 55 }; 56 57 typedef unsigned char thread_type; 58 59 /* Thread itself. */ 60 struct thread 61 { 62 thread_type type; /* thread type */ 63 thread_type add_type; /* thread type */ 64 struct thread *next; /* next pointer of the thread */ 65 struct thread *prev; /* previous pointer of the thread */ 66 struct thread_master *master; /* pointer to the struct thread_master. */ 67 int (*func) (struct thread *); /* event function */ 68 void *arg; /* event argument */ 69 union { 70 int val; /* second argument of the event. */ 71 int fd; /* file descriptor in case of read/write. */ 72 struct timeval sands; /* rest of time sands value. */ 73 } u; 74 RUSAGE_T ru; /* Indepth usage info. */ 75 struct cpu_thread_history *hist; /* cache pointer to cpu_history */ 76 char* funcname; 77 }; 78 79 struct cpu_thread_history 80 { 81 int (*func)(struct thread *); 82 char *funcname; 83 unsigned int total_calls; 84 struct time_stats 85 { 86 unsigned long total, max; 87 } real; 88 thread_type types; 89 }; 90 91 /* Clocks supported by Quagga */ 92 enum quagga_clkid { 93 QUAGGA_CLK_REALTIME = 0, /* ala gettimeofday() */ 94 QUAGGA_CLK_MONOTONIC, /* monotonic, against an indeterminate base */ 95 QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */ 96 }; 97 98 /* Thread types. */ 99 #define THREAD_READ 0 100 #define THREAD_WRITE 1 101 #define THREAD_TIMER 2 102 #define THREAD_EVENT 3 103 #define THREAD_READY 4 104 #define THREAD_BACKGROUND 5 105 #define THREAD_UNUSED 6 106 #define THREAD_EXECUTE 7 107 108 /* Thread yield time. */ 109 #define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */ 110 111 /* Macros. */ 112 #define THREAD_ARG(X) ((X)->arg) 113 #define THREAD_FD(X) ((X)->u.fd) 114 #define THREAD_VAL(X) ((X)->u.val) 115 116 #define THREAD_READ_ON(master,thread,func,arg,sock) \ 117 do { \ 118 if (! thread) \ 119 thread = thread_add_read (master, func, arg, sock); \ 120 } while (0) 121 122 #define THREAD_WRITE_ON(master,thread,func,arg,sock) \ 123 do { \ 124 if (! thread) \ 125 thread = thread_add_write (master, func, arg, sock); \ 126 } while (0) 127 128 #define THREAD_TIMER_ON(master,thread,func,arg,time) \ 129 do { \ 130 if (! thread) \ 131 thread = thread_add_timer (master, func, arg, time); \ 132 } while (0) 133 134 #define THREAD_OFF(thread) \ 135 do { \ 136 if (thread) \ 137 { \ 138 thread_cancel (thread); \ 139 thread = NULL; \ 140 } \ 141 } while (0) 142 143 #define THREAD_READ_OFF(thread) THREAD_OFF(thread) 144 #define THREAD_WRITE_OFF(thread) THREAD_OFF(thread) 145 #define THREAD_TIMER_OFF(thread) THREAD_OFF(thread) 146 147 #define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f) 148 #define thread_add_write(m,f,a,v) funcname_thread_add_write(m,f,a,v,#f) 149 #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f) 150 #define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f) 151 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f) 152 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f) 153 154 /* The 4th arg to thread_add_background is the # of milliseconds to delay. */ 155 #define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f) 156 157 /* Prototypes. */ 158 extern struct thread_master *thread_master_create (void); 159 extern void thread_master_free (struct thread_master *); 160 extern struct thread *funcname_thread_add_read (struct thread_master *, int (*)(struct thread *), void *, int, const char *); 161 extern struct thread *funcname_thread_add_write (struct thread_master *, int (*)(struct thread *), void *, int, const char *); 162 extern struct thread *funcname_thread_add_timer (struct thread_master *, int (*)(struct thread *), void *, long, const char *); 163 extern struct thread *funcname_thread_add_timer_msec (struct thread_master *, int (*)(struct thread *), void *, long, const char *); 164 extern struct thread *funcname_thread_add_event (struct thread_master *, int (*)(struct thread *), void *, int, const char *); 165 extern struct thread *funcname_thread_add_background (struct thread_master *, int (*func)(struct thread *), void *arg, long, const char *); 166 extern struct thread *funcname_thread_execute (struct thread_master *, int (*)(struct thread *), void *, int, const char *); 167 extern void thread_cancel (struct thread *); 168 extern unsigned int thread_cancel_event (struct thread_master *, void *); 169 extern struct thread *thread_fetch (struct thread_master *, struct thread *); 170 extern void thread_call (struct thread *); 171 extern unsigned long thread_timer_remain_second (struct thread *); 172 extern int thread_should_yield (struct thread *); 173 extern void thread_getrusage (RUSAGE_T *); 174 extern int quagga_gettime (enum quagga_clkid, struct timeval *); 175 extern time_t quagga_time (time_t *); 176 extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before, unsigned long *cpu_time_elapsed); 177 178 /* Global variable containing a recent result from gettimeofday. This can 179 be used instead of calling gettimeofday if a recent value is sufficient. 180 This is guaranteed to be refreshed before a thread is called. */ 181 extern struct timeval recent_time; 182 /* Similar to recent_time, but a monotonically increasing time value */ 183 extern struct timeval recent_relative_time (void); 184 185 #endif /* _THREAD_H_ */ 186