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. */ 38 enum pt_event_binding { 39 evb_psbend, 40 evb_tip, 41 evb_fup, 42 43 evb_max 44 }; 45 46 enum { 47 /* The maximal number of pending events - should be a power of two. */ 48 evq_max = 8 49 }; 50 51 /* A queue of events. */ 52 struct 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. */ 66 extern 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 */ 73 extern 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 */ 83 extern 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 */ 95 extern 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 */ 105 extern 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 */ 116 extern 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 */ 127 extern 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 */ 139 extern 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