back to topotato report
topotato coverage report
Current view: top level - lib - frrevent.h (source / functions) Hit Total Coverage
Test: test_bgp_ecmp_enhe.py::BGP_Unnumbered_ECMP Lines: 6 6 100.0 %
Date: 2023-11-16 17:19:14 Functions: 0 0 -

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /* Event management routine header.
       3             :  * Copyright (C) 1998 Kunihiro Ishiguro
       4             :  */
       5             : 
       6             : #ifndef _ZEBRA_THREAD_H
       7             : #define _ZEBRA_THREAD_H
       8             : 
       9             : #include <zebra.h>
      10             : #include <pthread.h>
      11             : #include <poll.h>
      12             : #include "monotime.h"
      13             : #include "frratomic.h"
      14             : #include "typesafe.h"
      15             : #include "xref.h"
      16             : 
      17             : #ifdef __cplusplus
      18             : extern "C" {
      19             : #endif
      20             : 
      21             : #define CONSUMED_TIME_CHECK 5000000
      22             : 
      23             : extern bool cputime_enabled;
      24             : extern unsigned long cputime_threshold;
      25             : /* capturing wallclock time is always enabled since it is fast (reading
      26             :  * hardware TSC w/o syscalls)
      27             :  */
      28             : extern unsigned long walltime_threshold;
      29             : 
      30             : struct rusage_t {
      31             : #ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
      32             :         struct timespec cpu;
      33             : #else
      34             :         struct rusage cpu;
      35             : #endif
      36             :         struct timeval real;
      37             : };
      38             : #define RUSAGE_T struct rusage_t
      39             : 
      40             : #define GETRUSAGE(X) event_getrusage(X)
      41             : 
      42             : PREDECL_LIST(event_list);
      43             : PREDECL_HEAP(event_timer_list);
      44             : 
      45             : struct fd_handler {
      46             :         /* number of pfd that fit in the allocated space of pfds. This is a
      47             :          * constant and is the same for both pfds and copy.
      48             :          */
      49             :         nfds_t pfdsize;
      50             : 
      51             :         /* file descriptors to monitor for i/o */
      52             :         struct pollfd *pfds;
      53             :         /* number of pollfds stored in pfds */
      54             :         nfds_t pfdcount;
      55             : 
      56             :         /* chunk used for temp copy of pollfds */
      57             :         struct pollfd *copy;
      58             :         /* number of pollfds stored in copy */
      59             :         nfds_t copycount;
      60             : };
      61             : 
      62             : struct xref_eventsched {
      63             :         struct xref xref;
      64             : 
      65             :         const char *funcname;
      66             :         const char *dest;
      67             :         uint32_t event_type;
      68             : };
      69             : 
      70             : PREDECL_HASH(cpu_records);
      71             : 
      72             : /* Master of the theads. */
      73             : struct event_loop {
      74             :         char *name;
      75             : 
      76             :         struct event **read;
      77             :         struct event **write;
      78             :         struct event_timer_list_head timer;
      79             :         struct event_list_head event, ready, unuse;
      80             :         struct list *cancel_req;
      81             :         bool canceled;
      82             :         pthread_cond_t cancel_cond;
      83             :         struct cpu_records_head cpu_records[1];
      84             :         int io_pipe[2];
      85             :         int fd_limit;
      86             :         struct fd_handler handler;
      87             :         unsigned long alloc;
      88             :         long selectpoll_timeout;
      89             :         bool spin;
      90             :         bool handle_signals;
      91             :         pthread_mutex_t mtx;
      92             :         pthread_t owner;
      93             : 
      94             :         nfds_t last_read;
      95             : 
      96             :         bool ready_run_loop;
      97             :         RUSAGE_T last_getrusage;
      98             : };
      99             : 
     100             : /* Event types. */
     101             : enum event_types {
     102             :         EVENT_READ,
     103             :         EVENT_WRITE,
     104             :         EVENT_TIMER,
     105             :         EVENT_EVENT,
     106             :         EVENT_READY,
     107             :         EVENT_UNUSED,
     108             :         EVENT_EXECUTE,
     109             : };
     110             : 
     111             : /* Event itself. */
     112             : struct event {
     113             :         enum event_types type;     /* event type */
     114             :         enum event_types add_type; /* event type */
     115             :         struct event_list_item eventitem;
     116             :         struct event_timer_list_item timeritem;
     117             :         struct event **ref;           /* external reference (if given) */
     118             :         struct event_loop *master;    /* pointer to the struct event_loop */
     119             :         void (*func)(struct event *e); /* event function */
     120             :         void *arg;                    /* event argument */
     121             :         union {
     122             :                 int val;              /* second argument of the event. */
     123             :                 int fd;               /* file descriptor in case of r/w */
     124             :                 struct timeval sands; /* rest of time sands value. */
     125             :         } u;
     126             :         struct timeval real;
     127             :         struct cpu_event_history *hist;     /* cache pointer to cpu_history */
     128             :         unsigned long yield;                /* yield time in microseconds */
     129             :         const struct xref_eventsched *xref; /* origin location */
     130             :         pthread_mutex_t mtx;                /* mutex for thread.c functions */
     131             :         bool ignore_timer_late;
     132             : };
     133             : 
     134             : #ifdef _FRR_ATTRIBUTE_PRINTFRR
     135             : #pragma FRR printfrr_ext "%pTH"(struct event *)
     136             : #endif
     137             : 
     138             : struct cpu_event_history {
     139             :         struct cpu_records_item item;
     140             : 
     141             :         void (*func)(struct event *e);
     142             :         atomic_size_t total_cpu_warn;
     143             :         atomic_size_t total_wall_warn;
     144             :         atomic_size_t total_starv_warn;
     145             :         atomic_size_t total_calls;
     146             :         atomic_size_t total_active;
     147             :         struct time_stats {
     148             :                 atomic_size_t total, max;
     149             :         } real;
     150             :         struct time_stats cpu;
     151             :         atomic_uint_fast32_t types;
     152             :         const char *funcname;
     153             : };
     154             : 
     155             : /* Struct timeval's tv_usec one second value.  */
     156             : #define TIMER_SECOND_MICRO 1000000L
     157             : 
     158             : /* Event yield time.  */
     159             : #define EVENT_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
     160             : 
     161             : #define EVENT_TIMER_STRLEN 12
     162             : 
     163             : /* Macros. */
     164             : #define EVENT_ARG(X) ((X)->arg)
     165             : #define EVENT_FD(X) ((X)->u.fd)
     166             : #define EVENT_VAL(X) ((X)->u.val)
     167             : 
     168             : /*
     169             :  * Please consider this macro deprecated, and do not use it in new code.
     170             :  */
     171             : #define EVENT_OFF(thread)                                                      \
     172             :         do {                                                                   \
     173             :                 if ((thread))                                                  \
     174             :                         event_cancel(&(thread));                               \
     175             :         } while (0)
     176             : 
     177             : /*
     178             :  * Macro wrappers to generate xrefs for all thread add calls.  Includes
     179             :  * file/line/function info for debugging/tracing.
     180             :  */
     181             : #include "lib/xref.h"
     182             : 
     183             : #define _xref_t_a(addfn, type, m, f, a, v, t)                                  \
     184             :         ({                                                                     \
     185             :                 static const struct xref_eventsched _xref __attribute__(       \
     186             :                         (used)) = {                                            \
     187             :                         .xref = XREF_INIT(XREFT_EVENTSCHED, NULL, __func__),   \
     188             :                         .funcname = #f,                                        \
     189             :                         .dest = #t,                                            \
     190             :                         .event_type = EVENT_##type,                            \
     191             :                 };                                                             \
     192             :                 XREF_LINK(_xref.xref);                                         \
     193             :                 _event_add_##addfn(&_xref, m, f, a, v, t);                     \
     194             :         }) /* end */
     195             : 
     196             : #define event_add_read(m, f, a, v, t) _xref_t_a(read_write, READ, m, f, a, v, t)
     197             : #define event_add_write(m, f, a, v, t)                                         \
     198             :         _xref_t_a(read_write, WRITE, m, f, a, v, t)
     199             : #define event_add_timer(m, f, a, v, t) _xref_t_a(timer, TIMER, m, f, a, v, t)
     200             : #define event_add_timer_msec(m, f, a, v, t)                                    \
     201             :         _xref_t_a(timer_msec, TIMER, m, f, a, v, t)
     202             : #define event_add_timer_tv(m, f, a, v, t)                                      \
     203             :         _xref_t_a(timer_tv, TIMER, m, f, a, v, t)
     204             : #define event_add_event(m, f, a, v, t) _xref_t_a(event, EVENT, m, f, a, v, t)
     205             : 
     206             : #define event_execute(m, f, a, v, p)                                           \
     207             :         ({                                                                     \
     208             :                 static const struct xref_eventsched _xref __attribute__(       \
     209             :                         (used)) = {                                            \
     210             :                         .xref = XREF_INIT(XREFT_EVENTSCHED, NULL, __func__),   \
     211             :                         .funcname = #f,                                        \
     212             :                         .dest = NULL,                                          \
     213             :                         .event_type = EVENT_EXECUTE,                           \
     214             :                 };                                                             \
     215             :                 XREF_LINK(_xref.xref);                                         \
     216             :                 _event_execute(&_xref, m, f, a, v, p);                         \
     217             :         }) /* end */
     218             : 
     219             : /* Prototypes. */
     220             : extern struct event_loop *event_master_create(const char *name);
     221             : void event_master_set_name(struct event_loop *master, const char *name);
     222             : extern void event_master_free(struct event_loop *m);
     223             : extern void event_master_free_unused(struct event_loop *m);
     224             : 
     225             : extern void _event_add_read_write(const struct xref_eventsched *xref,
     226             :                                   struct event_loop *master,
     227             :                                   void (*fn)(struct event *), void *arg, int fd,
     228             :                                   struct event **tref);
     229             : 
     230             : extern void _event_add_timer(const struct xref_eventsched *xref,
     231             :                              struct event_loop *master,
     232             :                              void (*fn)(struct event *), void *arg, long t,
     233             :                              struct event **tref);
     234             : 
     235             : extern void _event_add_timer_msec(const struct xref_eventsched *xref,
     236             :                                   struct event_loop *master,
     237             :                                   void (*fn)(struct event *), void *arg, long t,
     238             :                                   struct event **tref);
     239             : 
     240             : extern void _event_add_timer_tv(const struct xref_eventsched *xref,
     241             :                                 struct event_loop *master,
     242             :                                 void (*fn)(struct event *), void *arg,
     243             :                                 struct timeval *tv, struct event **tref);
     244             : 
     245             : extern void _event_add_event(const struct xref_eventsched *xref,
     246             :                              struct event_loop *master,
     247             :                              void (*fn)(struct event *), void *arg, int val,
     248             :                              struct event **tref);
     249             : 
     250             : extern void _event_execute(const struct xref_eventsched *xref,
     251             :                            struct event_loop *master,
     252             :                            void (*fn)(struct event *), void *arg, int val,
     253             :                            struct event **eref);
     254             : 
     255             : extern void event_cancel(struct event **event);
     256             : extern void event_cancel_async(struct event_loop *m, struct event **eptr,
     257             :                                void *data);
     258             : /* Cancel ready tasks with an arg matching 'arg' */
     259             : extern void event_cancel_event_ready(struct event_loop *m, void *arg);
     260             : /* Cancel all tasks with an arg matching 'arg', including timers and io */
     261             : extern void event_cancel_event(struct event_loop *m, void *arg);
     262             : extern struct event *event_fetch(struct event_loop *m, struct event *event);
     263             : extern void event_call(struct event *event);
     264             : extern unsigned long event_timer_remain_second(struct event *event);
     265             : extern struct timeval event_timer_remain(struct event *event);
     266             : extern unsigned long event_timer_remain_msec(struct event *event);
     267             : extern int event_should_yield(struct event *event);
     268             : /* set yield time for thread */
     269             : extern void event_set_yield_time(struct event *event, unsigned long ytime);
     270             : 
     271             : /* Internal libfrr exports */
     272             : extern void event_getrusage(RUSAGE_T *r);
     273             : extern void event_cmd_init(void);
     274             : 
     275             : /* Returns elapsed real (wall clock) time. */
     276             : extern unsigned long event_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
     277             :                                          unsigned long *cpu_time_elapsed);
     278             : 
     279             : /* only for use in logging functions! */
     280             : extern pthread_key_t thread_current;
     281             : extern char *event_timer_to_hhmmss(char *buf, int buf_size,
     282             :                                    struct event *t_timer);
     283             : 
     284         197 : static inline bool event_is_scheduled(struct event *thread)
     285             : {
     286         197 :         if (thread)
     287          35 :                 return true;
     288             : 
     289             :         return false;
     290             : }
     291             : 
     292             : /* Debug signal mask */
     293             : void debug_signals(const sigset_t *sigs);
     294             : 
     295          37 : static inline void event_ignore_late_timer(struct event *event)
     296             : {
     297          37 :         event->ignore_timer_late = true;
     298          29 : }
     299             : 
     300             : #ifdef __cplusplus
     301             : }
     302             : #endif
     303             : 
     304             : #endif /* _ZEBRA_THREAD_H */

Generated by: LCOV version v1.16-topotato