1/* 2 * Copyright (c) 2013-2019, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef PT_EVENT_QUEUE_H 30#define PT_EVENT_QUEUE_H 31 32#include "intel-pt.h" 33 34#include <stdint.h> 35 36 37/* Events are grouped by the packet the event binds to. */ 38enum pt_event_binding { 39 evb_psbend, 40 evb_tip, 41 evb_fup, 42 43 evb_max 44}; 45 46enum { 47 /* The maximal number of pending events - should be a power of two. */ 48 evq_max = 8 49}; 50 51/* A queue of events. */ 52struct pt_event_queue { 53 /* A collection of event queues, one per binding. */ 54 struct pt_event queue[evb_max][evq_max]; 55 56 /* The begin and end indices for the above event queues. */ 57 uint8_t begin[evb_max]; 58 uint8_t end[evb_max]; 59 60 /* A standalone event to be published immediately. */ 61 struct pt_event standalone; 62}; 63 64 65/* Initialize (or reset) an event queue. */ 66extern void pt_evq_init(struct pt_event_queue *); 67 68/* Get a standalone event. 69 * 70 * Returns a pointer to the standalone event on success. 71 * Returns NULL if @evq is NULL. 72 */ 73extern struct pt_event *pt_evq_standalone(struct pt_event_queue *evq); 74 75/* Enqueue an event. 76 * 77 * Adds a new event to @evq for binding @evb. 78 * 79 * Returns a pointer to the new event on success. 80 * Returns NULL if @evq is NULL or @evb is invalid. 81 * Returns NULL if @evq is full. 82 */ 83extern struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq, 84 enum pt_event_binding evb); 85 86 87/* Dequeue an event. 88 * 89 * Removes the first event for binding @evb from @evq. 90 * 91 * Returns a pointer to the dequeued event on success. 92 * Returns NULL if @evq is NULL or @evb is invalid. 93 * Returns NULL if @evq is empty. 94 */ 95extern struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq, 96 enum pt_event_binding evb); 97 98/* Clear a queue and discard events. 99 * 100 * Removes all events for binding @evb from @evq. 101 * 102 * Returns zero on success, a negative error code otherwise. 103 * Returns -pte_internal if @evq is NULL or @evb is invalid. 104 */ 105extern int pt_evq_clear(struct pt_event_queue *evq, 106 enum pt_event_binding evb); 107 108/* Check for emptiness. 109 * 110 * Check if @evq for binding @evb is empty. 111 * 112 * Returns a positive number if @evq is empty. 113 * Returns zero if @evq is not empty. 114 * Returns -pte_internal if @evq is NULL or @evb is invalid. 115 */ 116extern int pt_evq_empty(const struct pt_event_queue *evq, 117 enum pt_event_binding evb); 118 119/* Check for non-emptiness. 120 * 121 * Check if @evq for binding @evb contains pending events. 122 * 123 * Returns a positive number if @evq is not empty. 124 * Returns zero if @evq is empty. 125 * Returns -pte_internal if @evq is NULL or @evb is invalid. 126 */ 127extern int pt_evq_pending(const struct pt_event_queue *evq, 128 enum pt_event_binding evb); 129 130/* Find an event by type. 131 * 132 * Searches @evq for binding @evb for an event of type @evt. 133 * 134 * Returns a pointer to the first matching event on success. 135 * Returns NULL if there is no such event. 136 * Returns NULL if @evq is NULL. 137 * Returns NULL if @evb or @evt is invalid. 138 */ 139extern struct pt_event *pt_evq_find(struct pt_event_queue *evq, 140 enum pt_event_binding evb, 141 enum pt_event_type evt); 142 143#endif /* PT_EVENT_QUEUE_H */ 144