linux/tools/perf/util/trigger.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __TRIGGER_H_
   3#define __TRIGGER_H_ 1
   4
   5#include "util/debug.h"
   6#include "asm/bug.h"
   7
   8/*
   9 * Use trigger to model operations which need to be executed when
  10 * an event (a signal, for example) is observed.
  11 *
  12 * States and transits:
  13 *
  14 *
  15 *  OFF--> ON --> READY --(hit)--> HIT
  16 *                 ^               |
  17 *                 |            (ready)
  18 *                 |               |
  19 *                  \_____________/
  20 *
  21 * is_hit and is_ready are two key functions to query the state of
  22 * a trigger. is_hit means the event already happen; is_ready means the
  23 * trigger is waiting for the event.
  24 */
  25
  26struct trigger {
  27        volatile enum {
  28                TRIGGER_ERROR           = -2,
  29                TRIGGER_OFF             = -1,
  30                TRIGGER_ON              = 0,
  31                TRIGGER_READY           = 1,
  32                TRIGGER_HIT             = 2,
  33        } state;
  34        const char *name;
  35};
  36
  37#define TRIGGER_WARN_ONCE(t, exp) \
  38        WARN_ONCE(t->state != exp, "trigger '%s' state transist error: %d in %s()\n", \
  39                  t->name, t->state, __func__)
  40
  41static inline bool trigger_is_available(struct trigger *t)
  42{
  43        return t->state >= 0;
  44}
  45
  46static inline bool trigger_is_error(struct trigger *t)
  47{
  48        return t->state <= TRIGGER_ERROR;
  49}
  50
  51static inline void trigger_on(struct trigger *t)
  52{
  53        TRIGGER_WARN_ONCE(t, TRIGGER_OFF);
  54        t->state = TRIGGER_ON;
  55}
  56
  57static inline void trigger_ready(struct trigger *t)
  58{
  59        if (!trigger_is_available(t))
  60                return;
  61        t->state = TRIGGER_READY;
  62}
  63
  64static inline void trigger_hit(struct trigger *t)
  65{
  66        if (!trigger_is_available(t))
  67                return;
  68        TRIGGER_WARN_ONCE(t, TRIGGER_READY);
  69        t->state = TRIGGER_HIT;
  70}
  71
  72static inline void trigger_off(struct trigger *t)
  73{
  74        if (!trigger_is_available(t))
  75                return;
  76        t->state = TRIGGER_OFF;
  77}
  78
  79static inline void trigger_error(struct trigger *t)
  80{
  81        t->state = TRIGGER_ERROR;
  82}
  83
  84static inline bool trigger_is_ready(struct trigger *t)
  85{
  86        return t->state == TRIGGER_READY;
  87}
  88
  89static inline bool trigger_is_hit(struct trigger *t)
  90{
  91        return t->state == TRIGGER_HIT;
  92}
  93
  94#define DEFINE_TRIGGER(n) \
  95struct trigger n = {.state = TRIGGER_OFF, .name = #n}
  96#endif
  97