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