-
Notifications
You must be signed in to change notification settings - Fork 4
/
trace_tools.h
executable file
·212 lines (186 loc) · 5.64 KB
/
trace_tools.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#ifndef PQ_TRACE_TOOLS
#define PQ_TRACE_TOOLS
//==============================================================================
// DEFINES, INCLUDES, and STRUCTS
//==============================================================================
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "typedefs.h"
// operation codes for identification
#define PQ_OP_CREATE 0
#define PQ_OP_DESTROY 1
#define PQ_OP_CLEAR 2
#define PQ_OP_GET_KEY 3
#define PQ_OP_GET_ITEM 4
#define PQ_OP_GET_SIZE 5
#define PQ_OP_INSERT 6
#define PQ_OP_FIND_MIN 7
#define PQ_OP_DELETE 8
#define PQ_OP_DELETE_MIN 9
#define PQ_OP_DECREASE_KEY 10
#define PQ_OP_MELD 11
#define PQ_OP_EMPTY 12
/**
* Contains info about the trace file. pq_ids and node_ids are the number of
* unique IDs for the respective pointer types. Valid IDs are in the 0-(n-1)
* range, since IDs are used to index into arrays.
*/
struct pq_trace_header
{
uint64_t op_count;
uint32_t pq_ids;
uint32_t node_ids;
} __attribute__ ((packed, aligned(4)));
struct pq_op_create
{
uint32_t code;
//! specified destination for created pointer
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_destroy
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_clear
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_get_key
{
uint32_t code;
uint32_t pq_id;
uint32_t node_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_get_item
{
uint32_t code;
uint32_t pq_id;
uint32_t node_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_get_size
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_insert
{
uint32_t code;
//! queue into which to insert
uint32_t pq_id;
//! specified destination for created pointer
uint32_t node_id;
//! unique key; ex. actual key in high 32 bits, node_id in low 32 bits
key_type key;
//! typically the same as node_id
item_type item;
} __attribute__ ((packed, aligned(4)));
struct pq_op_find_min
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_delete
{
uint32_t code;
uint32_t pq_id;
uint32_t node_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_delete_min
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_decrease_key
{
uint32_t code;
uint32_t pq_id;
uint32_t node_id;
key_type key;
} __attribute__ ((packed, aligned(4)));
struct pq_op_meld
{
uint32_t code;
uint32_t pq_src1_id;
uint32_t pq_src2_id;
//! id to use for the newly generated heap, i.e. where to store the pointer
uint32_t pq_dst_id;
} __attribute__ ((packed, aligned(4)));
struct pq_op_empty
{
uint32_t code;
uint32_t pq_id;
} __attribute__ ((packed, aligned(4)));
typedef struct pq_trace_header pq_trace_header;
typedef struct pq_op_create pq_op_create;
typedef struct pq_op_destroy pq_op_destroy;
typedef struct pq_op_clear pq_op_clear;
typedef struct pq_op_get_key pq_op_get_key;
typedef struct pq_op_get_item pq_op_get_item;
typedef struct pq_op_get_size pq_op_get_size;
typedef struct pq_op_insert pq_op_insert;
typedef struct pq_op_find_min pq_op_find_min;
typedef struct pq_op_delete pq_op_delete;
typedef struct pq_op_delete_min pq_op_delete_min;
typedef struct pq_op_decrease_key pq_op_decrease_key;
typedef struct pq_op_meld pq_op_meld;
typedef struct pq_op_empty pq_op_empty;
/**
* Dummy struct. Primarily for use as a placeholder for allocation and to
* determine op type via the code field. Should be large enough to encompass
* any other op struct.
*/
typedef struct pq_op_insert pq_op_blank;
//==============================================================================
// PUBLIC DECLARATIONS
//==============================================================================
/**
* Writes a proper trace header with the information specified in the input.
* Rewinds the file to the beginning before writing. Recommended use pattern is
* to write a blank struct at the beginning of trace generation, write all the
* operations, and then write the actual header.
*
* @param file File to write header to
* @param header Header to write
* @return 0 on success, -1 on error
*/
int pq_trace_write_header( int file, pq_trace_header header );
/**
* Reads header from the specified file and writes to passed struct. Assumes
* file is currently at beginning.
*
* @param file File to read from.
* @param header Address of struct to write header info to
* @return 0 on success, -1 on error
*/
int pq_trace_read_header( int file, pq_trace_header *header );
/**
* Takes any priority queue operation struct and writes to the current position
* in the input file. Detects operation type based on code field.
*
* @param file File to write to
* @param op Operation to write out
* @return 0 on success, -1 on error
*/
int pq_trace_write_op( int file, void *op );
/**
* Reads an operation from the input file. Writes to address specified by op.
* For memory safety, it must be at least as long as the longest operation
* struct. For any practical key and item types, this will be pq_op_insert.
*
* @param file File to read from
* @param op Operation to write out
* @return 0 on success, -1 on error
*/
int pq_trace_read_op( int file, void *op );
/**
* Flushes any outstanding writes to the trace file. Must be called before
* closing the file.
*
* @param file File to write to
*/
int pq_trace_flush_buffer( int file );
#endif