xref: /linux/tools/perf/util/trigger.h (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
23dcc4436SWang Nan #ifndef __TRIGGER_H_
33dcc4436SWang Nan #define __TRIGGER_H_ 1
43dcc4436SWang Nan 
53dcc4436SWang Nan #include "asm/bug.h"
63dcc4436SWang Nan 
73dcc4436SWang Nan /*
83dcc4436SWang Nan  * Use trigger to model operations which need to be executed when
93dcc4436SWang Nan  * an event (a signal, for example) is observed.
103dcc4436SWang Nan  *
113dcc4436SWang Nan  * States and transits:
123dcc4436SWang Nan  *
133dcc4436SWang Nan  *
14*de19e5c3SAdrian Hunter  *  OFF--> ON --> READY --(hit)--> HIT
153dcc4436SWang Nan  *                 ^               |
163dcc4436SWang Nan  *                 |            (ready)
173dcc4436SWang Nan  *                 |               |
183dcc4436SWang Nan  *                  \_____________/
193dcc4436SWang Nan  *
203dcc4436SWang Nan  * is_hit and is_ready are two key functions to query the state of
213dcc4436SWang Nan  * a trigger. is_hit means the event already happen; is_ready means the
223dcc4436SWang Nan  * trigger is waiting for the event.
233dcc4436SWang Nan  */
243dcc4436SWang Nan 
253dcc4436SWang Nan struct trigger {
263dcc4436SWang Nan 	volatile enum {
273dcc4436SWang Nan 		TRIGGER_ERROR		= -2,
283dcc4436SWang Nan 		TRIGGER_OFF		= -1,
29*de19e5c3SAdrian Hunter 		TRIGGER_ON		= 0,
30*de19e5c3SAdrian Hunter 		TRIGGER_READY		= 1,
31*de19e5c3SAdrian Hunter 		TRIGGER_HIT		= 2,
323dcc4436SWang Nan 	} state;
333dcc4436SWang Nan 	const char *name;
343dcc4436SWang Nan };
353dcc4436SWang Nan 
363dcc4436SWang Nan #define TRIGGER_WARN_ONCE(t, exp) \
373dcc4436SWang Nan 	WARN_ONCE(t->state != exp, "trigger '%s' state transist error: %d in %s()\n", \
383dcc4436SWang Nan 		  t->name, t->state, __func__)
393dcc4436SWang Nan 
trigger_is_available(struct trigger * t)403dcc4436SWang Nan static inline bool trigger_is_available(struct trigger *t)
413dcc4436SWang Nan {
423dcc4436SWang Nan 	return t->state >= 0;
433dcc4436SWang Nan }
443dcc4436SWang Nan 
trigger_is_error(struct trigger * t)453dcc4436SWang Nan static inline bool trigger_is_error(struct trigger *t)
463dcc4436SWang Nan {
473dcc4436SWang Nan 	return t->state <= TRIGGER_ERROR;
483dcc4436SWang Nan }
493dcc4436SWang Nan 
trigger_on(struct trigger * t)503dcc4436SWang Nan static inline void trigger_on(struct trigger *t)
513dcc4436SWang Nan {
523dcc4436SWang Nan 	TRIGGER_WARN_ONCE(t, TRIGGER_OFF);
53*de19e5c3SAdrian Hunter 	t->state = TRIGGER_ON;
543dcc4436SWang Nan }
553dcc4436SWang Nan 
trigger_ready(struct trigger * t)563dcc4436SWang Nan static inline void trigger_ready(struct trigger *t)
573dcc4436SWang Nan {
583dcc4436SWang Nan 	if (!trigger_is_available(t))
593dcc4436SWang Nan 		return;
603dcc4436SWang Nan 	t->state = TRIGGER_READY;
613dcc4436SWang Nan }
623dcc4436SWang Nan 
trigger_hit(struct trigger * t)633dcc4436SWang Nan static inline void trigger_hit(struct trigger *t)
643dcc4436SWang Nan {
653dcc4436SWang Nan 	if (!trigger_is_available(t))
663dcc4436SWang Nan 		return;
673dcc4436SWang Nan 	TRIGGER_WARN_ONCE(t, TRIGGER_READY);
683dcc4436SWang Nan 	t->state = TRIGGER_HIT;
693dcc4436SWang Nan }
703dcc4436SWang Nan 
trigger_off(struct trigger * t)713dcc4436SWang Nan static inline void trigger_off(struct trigger *t)
723dcc4436SWang Nan {
733dcc4436SWang Nan 	if (!trigger_is_available(t))
743dcc4436SWang Nan 		return;
753dcc4436SWang Nan 	t->state = TRIGGER_OFF;
763dcc4436SWang Nan }
773dcc4436SWang Nan 
trigger_error(struct trigger * t)783dcc4436SWang Nan static inline void trigger_error(struct trigger *t)
793dcc4436SWang Nan {
803dcc4436SWang Nan 	t->state = TRIGGER_ERROR;
813dcc4436SWang Nan }
823dcc4436SWang Nan 
trigger_is_ready(struct trigger * t)833dcc4436SWang Nan static inline bool trigger_is_ready(struct trigger *t)
843dcc4436SWang Nan {
853dcc4436SWang Nan 	return t->state == TRIGGER_READY;
863dcc4436SWang Nan }
873dcc4436SWang Nan 
trigger_is_hit(struct trigger * t)883dcc4436SWang Nan static inline bool trigger_is_hit(struct trigger *t)
893dcc4436SWang Nan {
903dcc4436SWang Nan 	return t->state == TRIGGER_HIT;
913dcc4436SWang Nan }
923dcc4436SWang Nan 
933dcc4436SWang Nan #define DEFINE_TRIGGER(n) \
943dcc4436SWang Nan struct trigger n = {.state = TRIGGER_OFF, .name = #n}
953dcc4436SWang Nan #endif
96