YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_instrument.c
Go to the documentation of this file.
1// Copyright (c) 2026 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <string.h>
6
7#include "tests.h"
8#include "instrument.h"
10
18static void utest_region_name(void);
19static void utest_disabled_is_noop(void);
20static void utest_single_region(void);
21static void utest_nested_regions(void);
22static void utest_deeply_nested_regions(void);
23static void utest_sibling_nested_regions(void);
24static void utest_reregister_destroys_old_handles(void);
25static void utest_start_only_no_stop_cb(void);
26
27int main(void) {
28
29 utest_region_name();
30 utest_disabled_is_noop();
31 utest_single_region();
32 utest_nested_regions();
33 utest_deeply_nested_regions();
34 utest_sibling_nested_regions();
35 utest_reregister_destroys_old_handles();
36 utest_start_only_no_stop_cb();
37
38 return TEST_EXIT_CODE;
39}
40
45
47typedef struct {
48 int create_calls[YAC_INSTR_REGION_COUNT];
49 int start_calls[YAC_INSTR_REGION_COUNT];
50 int stop_calls[YAC_INSTR_REGION_COUNT];
51 int destroy_calls[YAC_INSTR_REGION_COUNT];
52 int last_start_depth[YAC_INSTR_REGION_COUNT];
53 int last_stop_depth[YAC_INSTR_REGION_COUNT];
54 void * last_start_handle[YAC_INSTR_REGION_COUNT];
55 void * last_stop_handle[YAC_INSTR_REGION_COUNT];
56 void * last_destroy_handle[YAC_INSTR_REGION_COUNT];
57 int call_order[4 * YAC_INSTR_REGION_COUNT];
60
61static void utest_record_call(instr_counters * ctx, int tag) {
62 if (ctx->call_order_count < (int)(sizeof(ctx->call_order) /
63 sizeof(ctx->call_order[0])))
64 ctx->call_order[ctx->call_order_count++] = tag;
65}
66
67// tags used to encode (callback kind, region id) pairs in call_order
68enum { CREATE_TAG = 0, START_TAG = 100, STOP_TAG = 200, DESTROY_TAG = 300 };
69
70static void * utest_create_cb(int id, void * user_data) {
71
73 ctx->create_calls[id]++;
74 utest_record_call(ctx, CREATE_TAG + id);
75 return &dummy_handle_storage[id];
76}
77
78static void utest_start_cb(
79 int id, void * handle, int depth, void * user_data) {
80
82 ctx->start_calls[id]++;
83 ctx->last_start_depth[id] = depth;
84 ctx->last_start_handle[id] = handle;
85 utest_record_call(ctx, START_TAG + id);
86}
87
88static void utest_stop_cb(
89 int id, void * handle, int depth, void * user_data) {
90
92 ctx->stop_calls[id]++;
93 ctx->last_stop_depth[id] = depth;
94 ctx->last_stop_handle[id] = handle;
95 utest_record_call(ctx, STOP_TAG + id);
96}
97
98static void utest_destroy_cb(
99 int id, void * handle, void * user_data) {
100
102 ctx->destroy_calls[id]++;
103 ctx->last_destroy_handle[id] = handle;
104 utest_record_call(ctx, DESTROY_TAG + id);
105}
106
107static void utest_region_name(void) {
108
109 // set reference names
110 char const * ref_region_names[YAC_INSTR_REGION_COUNT] = {0};
111 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_NEW] =
112 "distributed grid pair generation";
113 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_DECOMP] =
114 "distributed grid pair decomposition";
115 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_REDIST] =
116 "distributed grid pair redistribution";
117 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_POINT_SEARCH] =
118 "distributed grid pair point search";
119 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_POINT_SEARCH_GC] =
120 "distributed grid pair point search (great circle edges)";
121 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_NNN_SEARCH] =
122 "distributed grid pair n-nearest-neighbour search";
123 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_BND_CIRCLE_SEARCH] =
124 "distributed grid pair bounding circle search";
125 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_DNN_SEARCH] =
126 "distributed grid pair distance-nearest-neighbour search";
127 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_CELL_SEARCH] =
128 "distributed grid pair cell search";
129 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_AUX_GRID] =
130 "distributed grid pair auxiliary grid generation";
131 ref_region_names[YAC_INSTR_DIST_GRID_PAIR_RELOCATE_POINTS] =
132 "distributed grid pair point pair relocation";
133 ref_region_names[YAC_INSTR_DIST_GRID_GLOBAL_TO_LOCAL] =
134 "distributed grid global to local id conversion";
135 ref_region_names[YAC_INSTR_GEN_PROC_SPHERE_PART] =
136 "process sphere part generation";
137 ref_region_names[YAC_INSTR_COMPUTE_TGT_FIELD] =
138 "target field computation (SpMV)";
139 ref_region_names[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] =
140 "target field computation (direct copy)";
141 ref_region_names[YAC_INSTR_INTERP_SEARCH] =
142 "interpolation search (method stack)";
143 ref_region_names[YAC_INSTR_INTERP_SEARCH_AVG] =
144 "interpolation search (average)";
145 ref_region_names[YAC_INSTR_INTERP_SEARCH_NCC] =
146 "interpolation search (nearest corner cells)";
147 ref_region_names[YAC_INSTR_INTERP_SEARCH_NNN] =
148 "interpolation search (n-nearest-neighbour)";
149 ref_region_names[YAC_INSTR_INTERP_SEARCH_1NN] =
150 "interpolation search (nearest-neighbour)";
151 ref_region_names[YAC_INSTR_INTERP_SEARCH_ZERO] =
152 "interpolation search (zero)";
153 ref_region_names[YAC_INSTR_INTERP_SEARCH_DNN] =
154 "interpolation search (distance-nearest-neighbour)";
155 ref_region_names[YAC_INSTR_INTERP_SEARCH_CONSERV_1ST] =
156 "interpolation search (1st order conservative)";
157 ref_region_names[YAC_INSTR_INTERP_SEARCH_CONSERV_2ND] =
158 "interpolation search (2nd order conservative)";
159 ref_region_names[YAC_INSTR_INTERP_SEARCH_FIXED] =
160 "interpolation search (fixed value)";
161 ref_region_names[YAC_INSTR_INTERP_SEARCH_FILE] =
162 "interpolation search (user file)";
163 ref_region_names[YAC_INSTR_INTERP_SEARCH_CHECK] =
164 "interpolation search (check)";
165 ref_region_names[YAC_INSTR_INTERP_SEARCH_HCSBB] =
166 "interpolation search (Bernstein Bezier)";
167 ref_region_names[YAC_INSTR_INTERP_SEARCH_CREEP] =
168 "interpolation search (creep)";
169 ref_region_names[YAC_INSTR_INTERP_SEARCH_CALLBACK] =
170 "interpolation search (user callback)";
171 ref_region_names[YAC_INSTR_INTERP_SEARCH_SPMAP] =
172 "interpolation search (source to target map)";
173
174 for (size_t i = 0; i < YAC_INSTR_REGION_COUNT; i++) {
176 if (name == NULL)
177 PUT_ERR_F("yac_instrument_region_name: unexpected NULL for region %zu\n", i);
178 if (!ref_region_names[i] || strcmp(name, ref_region_names[i]))
179 PUT_ERR_F(
180 "yac_instrument_region_name: "
181 "unexpected name for region %zu (%s vs %s)\n",
182 i, name?name:"(null)",
183 ref_region_names[i]?ref_region_names[i]:"(null)");
184 }
185}
186
187static void utest_disabled_is_noop(void) {
188
189 // ensure a clean, disabled starting state, regardless of test order
191
192 // with no callbacks registered, start/stop must be safe no-ops
193 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
194 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT);
195 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT);
196 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
197}
198
199static void utest_single_region(void) {
200
202
203 // ensure a clean starting state, regardless of test order
206 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx);
207
208 { // test that a single region can be started/stopped, and the callbacks are
209 // invoked correctly
210 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
211 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
212
213 if (ctx.create_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
214 PUT_ERR("single region: create_cb must be called exactly once\n");
215 if (ctx.start_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
216 PUT_ERR("single region: start_cb must be called exactly once\n");
217 if (ctx.stop_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
218 PUT_ERR("single region: stop_cb must be called exactly once\n");
219 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
220 PUT_ERR("single region: start depth must be 0\n");
221 if (ctx.last_stop_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
222 PUT_ERR("single region: stop depth must be 0\n");
223 if (ctx.last_start_handle[YAC_INSTR_COMPUTE_TGT_FIELD] !=
224 &dummy_handle_storage[YAC_INSTR_COMPUTE_TGT_FIELD])
225 PUT_ERR("single region: start_cb must receive the created handle\n");
226 if (ctx.last_stop_handle[YAC_INSTR_COMPUTE_TGT_FIELD] !=
227 &dummy_handle_storage[YAC_INSTR_COMPUTE_TGT_FIELD])
228 PUT_ERR("single region: stop_cb must receive the created handle\n");
229 }
230
231 { // test that re-starting/stopping the same region again must not
232 // re-run create_cb (lazy registration happens only once per region ID)
233 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
234 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
235
236 if (ctx.create_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
237 PUT_ERR("single region: create_cb must not be called again\n");
238 if (ctx.start_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 2)
239 PUT_ERR("single region: start_cb must be called again\n");
240 if (ctx.stop_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 2)
241 PUT_ERR("single region: stop_cb must be called again\n");
242 }
243
244 { // test that clearing the callbacks must destroy the handle for the
245 // resolved region, using the destroy_cb/user_data that was active when
246 // the region was resolved (i.e. the first time it was started)
248
249 if (ctx.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
250 PUT_ERR("single region: destroy_cb must be called exactly once\n");
251 if (ctx.last_destroy_handle[YAC_INSTR_COMPUTE_TGT_FIELD] !=
252 &dummy_handle_storage[YAC_INSTR_COMPUTE_TGT_FIELD])
253 PUT_ERR("single region: destroy_cb must receive the created handle\n");
254
255 // a region never touched must never be created/destroyed
256 if (ctx.create_calls[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 0 ||
257 ctx.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 0)
258 PUT_ERR("single region: untouched region must not be created/destroyed\n");
259 }
260}
261
262static void utest_nested_regions(void) {
263
265
266 // ensure a clean starting state, regardless of test order
269 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx);
270
271 // test that nested regions can be started/stopped, and the callbacks are
272 // invoked correctly, with proper depth and handle values
273 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
274 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT);
275 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT);
276 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
277
278 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
279 PUT_ERR("nested regions: outer region must start at depth 0\n");
280 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 1)
281 PUT_ERR("nested regions: inner region must start at depth 1\n");
282 if (ctx.last_stop_depth[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 1)
283 PUT_ERR("nested regions: inner region must stop at depth 1\n");
284 if (ctx.last_stop_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
285 PUT_ERR("nested regions: outer region must stop at depth 0\n");
286
287 // each region ID gets its own handle
288 if (ctx.last_start_handle[YAC_INSTR_COMPUTE_TGT_FIELD] !=
289 &dummy_handle_storage[YAC_INSTR_COMPUTE_TGT_FIELD])
290 PUT_ERR("nested regions: outer region has the wrong handle\n");
291 if (ctx.last_start_handle[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] !=
292 &dummy_handle_storage[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT])
293 PUT_ERR("nested regions: inner region has the wrong handle\n");
294
295 // calls must happen in proper LIFO order: outer start, inner start,
296 // inner stop, outer stop (creation is interleaved with the first start
297 // of each region)
298 int const expected_order[] = {
299 CREATE_TAG + YAC_INSTR_COMPUTE_TGT_FIELD,
300 START_TAG + YAC_INSTR_COMPUTE_TGT_FIELD,
301 CREATE_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
302 START_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
303 STOP_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
304 STOP_TAG + YAC_INSTR_COMPUTE_TGT_FIELD};
305 int const n_expected =
306 (int)(sizeof(expected_order) / sizeof(expected_order[0]));
307
308 if (ctx.call_order_count != n_expected) {
309 PUT_ERR("nested regions: unexpected number of callback invocations\n");
310 } else {
311 for (int i = 0; i < n_expected; ++i)
312 if (ctx.call_order[i] != expected_order[i])
313 PUT_ERR("nested regions: callbacks fired in the wrong order\n");
314 }
315
317}
318
319static void utest_deeply_nested_regions(void) {
320
322
323 // ensure a clean starting state, regardless of test order
326 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx);
327
328 // test nesting of four distinct region IDs, all strictly nested inside
329 // one another (depth increases by one on every start, in the order the
330 // regions were opened)
331 yac_instrument_region_id const id[4] = {
332 YAC_INSTR_DIST_GRID_PAIR_NEW, YAC_INSTR_DIST_GRID_PAIR_DECOMP,
333 YAC_INSTR_DIST_GRID_PAIR_REDIST, YAC_INSTR_GEN_PROC_SPHERE_PART};
334
335 for (int i = 0; i < 4; ++i) YAC_INSTRUMENT_START(id[i]);
336 for (int i = 3; i >= 0; --i) YAC_INSTRUMENT_STOP(id[i]);
337
338 for (int i = 0; i < 4; ++i) {
339 if (ctx.last_start_depth[id[i]] != i)
340 PUT_ERR_F(
341 "deeply nested regions: region %d must start at depth %d\n", i, i);
342 if (ctx.last_stop_depth[id[i]] != i)
343 PUT_ERR_F(
344 "deeply nested regions: region %d must stop at depth %d\n", i, i);
345 }
346
347 // calls must happen in proper LIFO order: outermost-first on the way in,
348 // innermost-first on the way out
349 int expected_order[8];
350 for (int i = 0; i < 4; ++i) {
351 expected_order[2 * i] = CREATE_TAG + id[i];
352 expected_order[2 * i + 1] = START_TAG + id[i];
353 }
354 int const n_start = 8;
355 int const n_expected = n_start + 4;
356 int full_expected[12];
357 memcpy(full_expected, expected_order, sizeof(expected_order));
358 for (int i = 0; i < 4; ++i)
359 full_expected[n_start + i] = STOP_TAG + id[3 - i];
360
361 if (ctx.call_order_count != n_expected) {
362 PUT_ERR(
363 "deeply nested regions: unexpected number of callback invocations\n");
364 } else {
365 for (int i = 0; i < n_expected; ++i)
366 if (ctx.call_order[i] != full_expected[i])
367 PUT_ERR("deeply nested regions: callbacks fired in the wrong order\n");
368 }
369
371}
372
373static void utest_sibling_nested_regions(void) {
374
376
377 // ensure a clean starting state, regardless of test order
380 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx);
381
382 // test that two sibling regions, both nested inside the same parent but
383 // not overlapping with each other, are each reported at the same depth,
384 // and that the parent's depth is unaffected by either child
385 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD); // depth 0
386
387 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT); // depth 1
388 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT);
389
390 YAC_INSTRUMENT_START(YAC_INSTR_GEN_PROC_SPHERE_PART); // depth 1 again
391 YAC_INSTRUMENT_STOP(YAC_INSTR_GEN_PROC_SPHERE_PART);
392
393 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
394
395 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0 ||
396 ctx.last_stop_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
397 PUT_ERR("sibling nested regions: parent must stay at depth 0\n");
398 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 1 ||
399 ctx.last_stop_depth[YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT] != 1)
400 PUT_ERR("sibling nested regions: first sibling must run at depth 1\n");
401 if (ctx.last_start_depth[YAC_INSTR_GEN_PROC_SPHERE_PART] != 1 ||
402 ctx.last_stop_depth[YAC_INSTR_GEN_PROC_SPHERE_PART] != 1)
403 PUT_ERR("sibling nested regions: second sibling must run at depth 1\n");
404
405 // each sibling must have been started/stopped exactly once, and the
406 // parent must not have been re-created/re-started by either child
407 if (ctx.start_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1 ||
408 ctx.stop_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
409 PUT_ERR("sibling nested regions: parent must start/stop exactly once\n");
410
411 int const expected_order[] = {
412 CREATE_TAG + YAC_INSTR_COMPUTE_TGT_FIELD,
413 START_TAG + YAC_INSTR_COMPUTE_TGT_FIELD,
414 CREATE_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
415 START_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
416 STOP_TAG + YAC_INSTR_COMPUTE_TGT_FIELD_DIRECT,
417 CREATE_TAG + YAC_INSTR_GEN_PROC_SPHERE_PART,
418 START_TAG + YAC_INSTR_GEN_PROC_SPHERE_PART,
419 STOP_TAG + YAC_INSTR_GEN_PROC_SPHERE_PART,
420 STOP_TAG + YAC_INSTR_COMPUTE_TGT_FIELD};
421 int const n_expected =
422 (int)(sizeof(expected_order) / sizeof(expected_order[0]));
423
424 if (ctx.call_order_count != n_expected) {
425 PUT_ERR(
426 "sibling nested regions: unexpected number of callback invocations\n");
427 } else {
428 for (int i = 0; i < n_expected; ++i)
429 if (ctx.call_order[i] != expected_order[i])
430 PUT_ERR(
431 "sibling nested regions: callbacks fired in the wrong order\n");
432 }
433
435}
436
437static void utest_reregister_destroys_old_handles(void) {
438
439 instr_counters ctx_old = (instr_counters){0};
440 instr_counters ctx_new = (instr_counters){0};
441
444 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx_old);
445
446 // resolve the region under the old registration (creates a handle)
447 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
448 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
449
450 // switching to a new registration must destroy the old registration's
451 // handle, using the OLD destroy_cb/user_data
453 utest_create_cb, utest_start_cb, utest_stop_cb, utest_destroy_cb, &ctx_new);
454
455 if (ctx_old.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
456 PUT_ERR(
457 "reregister: old registration's destroy_cb must be called once "
458 "for the resolved region\n");
459 if (ctx_new.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
460 PUT_ERR("reregister: new registration's destroy_cb must not be called\n");
461
462 // the new registration must start with a clean slate: create_cb must run
463 // again for the same region ID
464 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
465 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
466
467 if (ctx_new.create_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
468 PUT_ERR(
469 "reregister: new registration must re-run create_cb for a region "
470 "already resolved under the old registration\n");
471 if (ctx_old.create_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
472 PUT_ERR("reregister: old registration's create_cb must not run again\n");
473
475
476 if (ctx_new.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
477 PUT_ERR(
478 "reregister: clearing callbacks must destroy the new registration's "
479 "handle\n");
480}
481
482static void utest_start_only_no_stop_cb(void) {
483
485
487 // only start_cb is provided (no stop_cb) - this is a valid combination:
488 // instrumentation is enabled as soon as start_cb or stop_cb is set
490 utest_create_cb, utest_start_cb, NULL, utest_destroy_cb, &ctx);
491
492 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
493 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
494
495 if (ctx.start_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
496 PUT_ERR("start-only: start_cb must still be called\n");
497 if (ctx.stop_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
498 PUT_ERR("start-only: stop_cb must never be called (it is NULL)\n");
499
500 // starting the same region again must succeed (i.e. the stop above did
501 // pop the region off the open-region stack, even without a stop_cb to
502 // observe it) and must report depth 0 again
503 YAC_INSTRUMENT_START(YAC_INSTR_COMPUTE_TGT_FIELD);
504 YAC_INSTRUMENT_STOP(YAC_INSTR_COMPUTE_TGT_FIELD);
505
506 if (ctx.start_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 2)
507 PUT_ERR("start-only: start_cb must be called again\n");
508 if (ctx.last_start_depth[YAC_INSTR_COMPUTE_TGT_FIELD] != 0)
509 PUT_ERR("start-only: region must be poppable and restartable at depth 0\n");
510
512
513 if (ctx.destroy_calls[YAC_INSTR_COMPUTE_TGT_FIELD] != 1)
514 PUT_ERR("start-only: destroy_cb must still be called on clear\n");
515}
void yac_instrument_set_callbacks(yac_instrument_create_cb create_cb, yac_instrument_start_cb start_cb, yac_instrument_stop_cb stop_cb, yac_instrument_destroy_cb destroy_cb, void *user_data)
Definition instrument.c:97
void yac_instrument_clear_callbacks(void)
Definition instrument.c:149
const char * yac_instrument_region_name(yac_instrument_region_id id)
Definition instrument.c:154
yac_instrument_region_id
Definition instrument.h:53
@ YAC_INSTR_REGION_COUNT
Definition instrument.h:57
#define YAC_INSTRUMENT_START(ID)
Enter an instrumented region.
#define YAC_INSTRUMENT_STOP(ID)
Exit an instrumented region entered with YAC_INSTRUMENT_START(ID).
void * user_data
void * last_stop_handle[YAC_INSTR_REGION_COUNT]
int stop_calls[YAC_INSTR_REGION_COUNT]
int destroy_calls[YAC_INSTR_REGION_COUNT]
void * last_start_handle[YAC_INSTR_REGION_COUNT]
int last_start_depth[YAC_INSTR_REGION_COUNT]
int last_stop_depth[YAC_INSTR_REGION_COUNT]
int create_calls[YAC_INSTR_REGION_COUNT]
int call_order[4 *YAC_INSTR_REGION_COUNT]
void * last_destroy_handle[YAC_INSTR_REGION_COUNT]
int start_calls[YAC_INSTR_REGION_COUNT]
static int dummy_handle_storage[YAC_INSTR_REGION_COUNT]
@ CREATE_TAG
@ DESTROY_TAG
@ STOP_TAG
@ START_TAG
#define PUT_ERR_F(fmt,...)
Definition tests.h:11
#define TEST_EXIT_CODE
Definition tests.h:15
#define PUT_ERR(string)
Definition tests.h:10
char const * name
Definition toy_scrip.c:114
int id
Definition toy_scrip.c:115