File size: 24,196 Bytes
f4cade0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
/*

 * Copyright (C) 2005-2019 Intel Corporation

 * SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause

 */

/* This file defines macros and inline functions used by

 * the Intel(R) Advisor XE "Dependencies Modeling" and

 * "Suitability Modeling" analysis, and are in described

 * in the "Annotations" section of the help.

 *

 * Expansion Options

 *

 * There are several options you can used to control how advisor-annotate.h

 * is included.  To use these, define the option prior to including

 * advisor-annotate.h.  e.g.

 *  #define ANNOTATE_DECLARE

 *  #include "advisor-annotate.h"

 *

 * Controlling inclusion of windows.h

 *

 *  windows.h is included for declarations for LoadLibrary, GetProcSymbol,

 *  but this can have interactions with user code, such as conflicting

 *  definitions of types.  There are two general approaches to work around

 *  this if this triggers problems building your application:

 *

 *  1. Reduce the amount declared by windows.h by using the following: 

 *      #define NOMINMAX

 *      #define WIN32_LEAN_AND_MEAN

 *     prior to including advisor-annotate.h in your code.

 *     The first avoids problems with STL min/max in particular

 *     This is sufficient in some cases, and may be the easiest.

 *

 *  2. Use a declaration/definition approach, where all uses of advisor-annotate.h

 *     other than one, generate a set of declarations, and windows.h is only

 *     needed in a single implementation module.  In this model, all includes

 *     of advisor-annotate.h except one specify ANNOTATE_DECLARE, which causes

 *     advisor-annotate.h to declare an external routine, and not include

 *     windows.h.  A final include of advisor-annotate.h than specifies

 *     ANNOTATE_DEFINE, to actually define the global routine to resolve

 *     the external reference.  This one include is the only one that winds up

 *     using windows.h.  If necessary, this can be placed in a file by itself.

 *

 *     An example using this mechanism:

 * 

 *      ...

 *      // Some header(s) used in places in your system where you want

 *      // to be able to use annotations

 *      #define ANNOTATE_DECLARE

 *      #include "advisor-annotate.h"

 *      ...

 *         // annotation uses

 *         ANNOTATE_SITE_BEGIN(MySite1)

 *         ...

 *         ANNOTATE_SITE_END(MySite1)

 *      ...

 *

 *      ...

 *      // A single implementation file (.cpp/.cxx) causes windows.h

 *      // to be included, and the support routine to be defined as a

 *      // global routine called from the various annotation uses.

 *      #define ANNOTATE_DEFINE

 *      #include "advisor-annotate.h"

 *      ...

 *

 * Null expansion of annotations

 *

 *  Some people may find it useful to have no expansion for annotations,

 *  if you have a project that you want to build without any annotation

 *  effects at all.  (e.g. if you have a project where you want to have

 *  some annotations in a shared source pool, but only particular

 *  developers are actually building with the annotations enabled.)

 *  Defining ANNOTATE_EXPAND_NULL avoids declaring comdat routines,

 *  and avoids any textual expansion for annotation macros.

 */

#ifndef _ADVISOR_ANNOTATE_H_
#define _ADVISOR_ANNOTATE_H_

/* Version of the annotations.

 * The presence of this macro serves to idetify the annotation definition

 * file and the form of annotations.

 */
#define INTEL_ADVISOR_ANNOTATION_VERSION 1.0

#ifdef ANNOTATE_EXPAND_NULL

#define ANNOTATE_SITE_BEGIN(_SITE)
#define ANNOTATE_SITE_END(...)
#define ANNOTATE_TASK_BEGIN(_TASK)
#define ANNOTATE_TASK_END(...)
#define ANNOTATE_ITERATION_TASK(_TASK)
#define ANNOTATE_LOCK_ACQUIRE(_ADDR)
#define ANNOTATE_LOCK_RELEASE(_ADDR)
#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE)
#define ANNOTATE_RECORD_DEALLOCATION(_ADDR)
#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE)
#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE)
#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE)
#define ANNOTATE_CLEAR_USES(_ADDR)
#define ANNOTATE_DISABLE_OBSERVATION_PUSH
#define ANNOTATE_DISABLE_OBSERVATION_POP
#define ANNOTATE_DISABLE_COLLECTION_PUSH
#define ANNOTATE_DISABLE_COLLECTION_POP
#define ANNOTATE_AGGREGATE_TASK(_COUNT)

#else /* ANNOTATE_EXPAND_NULL */

#if defined(WIN32) || defined(_WIN32)

#define ANNOTATEAPI __cdecl

#ifndef ANNOTATE_DECLARE
#include <windows.h>

typedef HMODULE lib_t;

#define __itt_get_proc(lib, name) GetProcAddress(lib, name)
#define __itt_load_lib(name)      LoadLibraryA(name)
#define __itt_unload_lib(handle)  FreeLibrary(handle)
#define __itt_system_error()      (int)GetLastError()
#endif /* ANNOTATE_DECLARE */

#else /* defined(WIN32) || defined(_WIN32) */

#if defined _M_IX86 || __i386__
#   define ANNOTATEAPI __attribute__ ((cdecl))
#else
#   define ANNOTATEAPI /* actual only on x86 platform */
#endif


#ifndef ANNOTATE_DECLARE
#include <pthread.h>
#include <dlfcn.h>
#include <errno.h>

typedef void* lib_t;

#define __itt_get_proc(lib, name) dlsym(lib, name)
#define __itt_load_lib(name)      dlopen(name, RTLD_LAZY)
#define __itt_unload_lib(handle)  dlclose(handle)
#define __itt_system_error()      errno
#endif /* ANNOTATE_DECLARE */

#endif /* defined(WIN32) || defined(_WIN32) */

#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#ifndef _ITTNOTIFY_H_ 

/* Handles for sites and tasks.

 */
typedef void* __itt_model_site;             /* handle for lexical site */
typedef void* __itt_model_site_instance;    /* handle for dynamic instance */
typedef void* __itt_model_task;             /* handle for lexical site */
typedef void* __itt_model_task_instance;    /* handle for dynamic instance */

typedef enum {
    __itt_model_disable_observation,
    __itt_model_disable_collection
} __itt_model_disable;

#endif /* _ITTNOTIFY_H_  */

/*** Use the routines in libittnotify.dll. ***/

/* Basic approach:

 * For the case of calling the dll, there is an __annotate_routine function

 * declared as a comdat in each compilation unit with annotations present.

 * That routine in turn has an internal static structure that is initialized

 * once to contain the address of functions occuring in libittnotify.dll.

 * Each time an annotation macro is invoked, that causes a call to the

 * __annotate_routine function to get addresses of the routines, followed

 * by calling the specific routine, provided the address is non-null.

 */

/* This set of macros generates calls that are part of application images,

 * which call the __itt_model_xxx routines in the dynamically loaded

 * libittnotify.dll.

 */
#ifndef _ITTNOTIFY_H_ 
#define ITT_NOTIFY_DECL(_text) _text
#else
#define ITT_NOTIFY_DECL(_text)
#endif

/* For C++, a static initialization is used */
#if defined(__cplusplus) && defined(WIN32)
#define _ANNOTATE_ROUTINES_ADDR __annotate_routines_s
#else
#define _ANNOTATE_ROUTINES_ADDR __annotate_routines_init( __annotate_routines() )
#endif /* __cplusplus */


#define _ANNOTATE_DECLARE_0(_BASENAME) \
typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(); \
static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop() { }; \
ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(); )

#define _ANNOTATE_DECLARE_0_INT(_BASENAME) \
typedef int (ANNOTATEAPI * __annotate_##_BASENAME##_t)(); \
static __inline int ANNOTATEAPI __annotate_##_BASENAME##_t_nop() { return 0; }; \
ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(); )

#define _ANNOTATE_CALL_0(_BASENAME) { _ANNOTATE_ROUTINES_ADDR->_BASENAME(); }

#define _ANNOTATE_DECLARE_1(_BASENAME, _P1TYPE) \
typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(_P1TYPE p1); \
static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop(_P1TYPE p1) { (void)p1; }; \
ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(_P1TYPE p1); )

#define _ANNOTATE_CALL_1(_BASENAME, _P1) { _ANNOTATE_ROUTINES_ADDR->_BASENAME(_P1); }

#define _ANNOTATE_DECLARE_2(_BASENAME, _P1TYPE, _P2TYPE) \
typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(_P1TYPE p1, _P2TYPE p2); \
static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop(_P1TYPE p1, _P2TYPE p2) { (void)p1; (void)p2; }; \
ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(_P1TYPE p1, _P2TYPE p2); )

#define _ANNOTATE_CALL_2(_BASENAME, _P1, _P2) { _ANNOTATE_ROUTINES_ADDR->_BASENAME((_P1), (_P2)); }

/*** Declare routines appropriately based on usage style ***/

/* Depending on above, this will either expand to comdats that are

 * used directly, or comdats that call routines in libittnotify.dll

 */
_ANNOTATE_DECLARE_1(site_beginA, const char *)
_ANNOTATE_DECLARE_0(site_end_2)
_ANNOTATE_DECLARE_1(task_beginA, const char *)
_ANNOTATE_DECLARE_0(task_end_2)
_ANNOTATE_DECLARE_1(iteration_taskA, const char *)
_ANNOTATE_DECLARE_1(lock_acquire_2, void *)
_ANNOTATE_DECLARE_1(lock_release_2, void *)
_ANNOTATE_DECLARE_2(record_allocation, void *, size_t)
_ANNOTATE_DECLARE_1(record_deallocation, void *)
_ANNOTATE_DECLARE_2(induction_uses, void *, size_t)
_ANNOTATE_DECLARE_2(reduction_uses, void *, size_t)
_ANNOTATE_DECLARE_2(observe_uses, void *, size_t)
_ANNOTATE_DECLARE_1(clear_uses, void *)
_ANNOTATE_DECLARE_1(disable_push, __itt_model_disable)
_ANNOTATE_DECLARE_0(disable_pop)
_ANNOTATE_DECLARE_1(aggregate_task, size_t)
_ANNOTATE_DECLARE_0_INT(is_collection_disabled)

/* All of the symbols potentially in the library

 */
struct __annotate_routines {
    volatile int                        initialized;
    __annotate_site_beginA_t            site_beginA;
    __annotate_site_end_2_t             site_end_2;
    __annotate_task_beginA_t            task_beginA;
    __annotate_task_end_2_t             task_end_2;
    __annotate_iteration_taskA_t        iteration_taskA;
    __annotate_lock_acquire_2_t         lock_acquire_2;
    __annotate_lock_release_2_t         lock_release_2;
    __annotate_record_allocation_t      record_allocation;
    __annotate_record_deallocation_t    record_deallocation;
    __annotate_induction_uses_t         induction_uses;
    __annotate_reduction_uses_t         reduction_uses;
    __annotate_observe_uses_t           observe_uses;
    __annotate_clear_uses_t             clear_uses;
    __annotate_disable_push_t           disable_push;
    __annotate_disable_pop_t            disable_pop;
    __annotate_aggregate_task_t         aggregate_task;
    __annotate_is_collection_disabled_t is_collection_disabled;
};

/* This comdat-ed routine means there is a single instance of the function pointer

 * structure per image

 */
static __inline struct __annotate_routines* __annotate_routines()

{
    static struct __annotate_routines __annotate_routines;
    return &__annotate_routines;
}

/* This routine is called to get the address of an initialized

 * set of function pointers for the annotation routines.

 */

#ifdef ANNOTATE_DECLARE
extern struct __annotate_routines* ANNOTATEAPI __annotate_routines_init(struct __annotate_routines* itt);
#else
#ifdef ANNOTATE_DEFINE
    /* */
#else
    static __inline 
#endif
struct __annotate_routines*

ANNOTATEAPI

__annotate_routines_init(struct __annotate_routines* itt) {

    if (itt->initialized) {
        return itt;
    } else {

        /* Initialized by first invocation

         * This assumes that the code here can be executed successfully

         * by multiple threads, should that ever happen.

         */
        int do_disable_pop = 0;
        char* lib_name = NULL;
        lib_t itt_notify = 0;

        if (sizeof(void*) > 4) {
            lib_name = getenv("INTEL_LIBITTNOTIFY64");
        } else {
            lib_name = getenv("INTEL_LIBITTNOTIFY32");
        }

        if (lib_name) {
            itt_notify = __itt_load_lib(lib_name);
        } else {
#if defined(WIN32) || defined(_WIN32)
            itt_notify = __itt_load_lib("libittnotify.dll");
#elif defined(__APPLE__)
            itt_notify = __itt_load_lib("libittnotify.dylib");
#else
            itt_notify = __itt_load_lib("libittnotify.so");
#endif
        }

        if (itt_notify != NULL) {
            /* The static variables initialized and itt are reported as race conditions

             * or inconsistent lock usage by Dependencies Modeling in some obscure cases

             * involving multiple dlls.  Ignoring this initialization phase gets rid of 

             * this problem. 

             */
            __annotate_disable_push_t disable_push;
            __annotate_is_collection_disabled_t is_collection_disabled;
            disable_push            = (__annotate_disable_push_t)       __itt_get_proc(itt_notify, "__itt_model_disable_push");
            is_collection_disabled  = (__annotate_is_collection_disabled_t) __itt_get_proc(itt_notify, "__itt_model_is_collection_disabled");
            if (disable_push) {
                if ( ! (is_collection_disabled && is_collection_disabled()) )
                {
                    // disable collection only if it is not disabled already (for example, started paused)
                    disable_push(__itt_model_disable_observation);
                    do_disable_pop = 1;
                }
            }
            itt->site_beginA         = (__annotate_site_beginA_t)        __itt_get_proc(itt_notify, "__itt_model_site_beginA");
            itt->site_end_2          = (__annotate_site_end_2_t)         __itt_get_proc(itt_notify, "__itt_model_site_end_2");
            itt->task_beginA         = (__annotate_task_beginA_t)        __itt_get_proc(itt_notify, "__itt_model_task_beginA");
            itt->task_end_2          = (__annotate_task_end_2_t)         __itt_get_proc(itt_notify, "__itt_model_task_end_2");
            itt->iteration_taskA     = (__annotate_iteration_taskA_t)    __itt_get_proc(itt_notify, "__itt_model_iteration_taskA");
            itt->lock_acquire_2      = (__annotate_lock_acquire_2_t)     __itt_get_proc(itt_notify, "__itt_model_lock_acquire_2");
            itt->lock_release_2      = (__annotate_lock_release_2_t)     __itt_get_proc(itt_notify, "__itt_model_lock_release_2");
            itt->record_allocation   = (__annotate_record_allocation_t)  __itt_get_proc(itt_notify, "__itt_model_record_allocation");
            itt->record_deallocation = (__annotate_record_deallocation_t)__itt_get_proc(itt_notify, "__itt_model_record_deallocation");
            itt->induction_uses      = (__annotate_induction_uses_t)     __itt_get_proc(itt_notify, "__itt_model_induction_uses");
            itt->reduction_uses      = (__annotate_reduction_uses_t)     __itt_get_proc(itt_notify, "__itt_model_reduction_uses");
            itt->observe_uses        = (__annotate_observe_uses_t)       __itt_get_proc(itt_notify, "__itt_model_observe_uses");
            itt->clear_uses          = (__annotate_clear_uses_t)         __itt_get_proc(itt_notify, "__itt_model_clear_uses");
            itt->disable_push        = disable_push;
            itt->disable_pop         = (__annotate_disable_pop_t)        __itt_get_proc(itt_notify, "__itt_model_disable_pop");
            itt->aggregate_task      = (__annotate_aggregate_task_t)     __itt_get_proc(itt_notify, "__itt_model_aggregate_task");
            itt->is_collection_disabled = is_collection_disabled;
        }
        /* No-op routine for any that didn't get resolved */
        if (!itt->site_beginA)         itt->site_beginA =       __annotate_site_beginA_t_nop;
        if (!itt->site_end_2)          itt->site_end_2 =        __annotate_site_end_2_t_nop;
        if (!itt->task_beginA)         itt->task_beginA =       __annotate_task_beginA_t_nop;
        if (!itt->task_end_2)          itt->task_end_2 =        __annotate_task_end_2_t_nop;
        if (!itt->iteration_taskA)     itt->iteration_taskA =   __annotate_iteration_taskA_t_nop;
        if (!itt->lock_acquire_2)      itt->lock_acquire_2 =    __annotate_lock_acquire_2_t_nop;
        if (!itt->lock_release_2)      itt->lock_release_2 =    __annotate_lock_release_2_t_nop;
        if (!itt->record_allocation)   itt->record_allocation = __annotate_record_allocation_t_nop;
        if (!itt->record_deallocation) itt->record_deallocation=__annotate_record_deallocation_t_nop;
        if (!itt->induction_uses)      itt->induction_uses =    __annotate_induction_uses_t_nop;
        if (!itt->reduction_uses)      itt->reduction_uses =    __annotate_reduction_uses_t_nop;
        if (!itt->observe_uses)        itt->observe_uses =      __annotate_observe_uses_t_nop;
        if (!itt->clear_uses)          itt->clear_uses =        __annotate_clear_uses_t_nop;
        if (!itt->disable_push)        itt->disable_push =      __annotate_disable_push_t_nop;
        if (!itt->disable_pop)         itt->disable_pop =       __annotate_disable_pop_t_nop;
        if (!itt->aggregate_task)      itt->aggregate_task =    __annotate_aggregate_task_t_nop;
        if (!itt->is_collection_disabled) itt->is_collection_disabled = __annotate_is_collection_disabled_t_nop;

        itt->initialized = 1;

        if (do_disable_pop) {
            itt->disable_pop();
        }
    }
    return itt;
}
#endif /* ANNOTATE_DECLARE */

/* For C++ only, use a class to force initialization */

#if defined(__cplusplus) && defined(WIN32)
/* Force one-shot initialization so individual calls don't need it */
static struct __annotate_routines* __annotate_routines_s = __annotate_routines_init( __annotate_routines() );
#endif

/* For C++, allow the Annotate::SiteBegin(x) form.  For Windows CLR, this is the default

 * expansion for the macros (with no-inline) to get the best call stacks in the tools. */
#if defined(__cplusplus)
/* Ensure this code is managed and non-inlinable */
#if defined(WIN32) && defined(__CLR_VER)
#pragma managed(push, on)
#define ANNOTATE_CLR_NOINLINE __declspec(noinline)
#else
#define ANNOTATE_CLR_NOINLINE
#endif
class Annotate {
public:
    static ANNOTATE_CLR_NOINLINE void SiteBegin(const char* site)      { _ANNOTATE_ROUTINES_ADDR->site_beginA(site); }
    static ANNOTATE_CLR_NOINLINE void SiteEnd()                        { _ANNOTATE_ROUTINES_ADDR->site_end_2(); }
    static ANNOTATE_CLR_NOINLINE void TaskBegin(const char* task)      { _ANNOTATE_ROUTINES_ADDR->task_beginA(task); }
    static ANNOTATE_CLR_NOINLINE void TaskEnd()                        { _ANNOTATE_ROUTINES_ADDR->task_end_2(); }
    static ANNOTATE_CLR_NOINLINE void IterationTask(const char* task)  { _ANNOTATE_ROUTINES_ADDR->iteration_taskA(task); }
    static ANNOTATE_CLR_NOINLINE void LockAcquire(void* lockId)        { _ANNOTATE_ROUTINES_ADDR->lock_acquire_2(lockId); }
    static ANNOTATE_CLR_NOINLINE void LockRelease(void* lockId)        { _ANNOTATE_ROUTINES_ADDR->lock_release_2(lockId); }
    static ANNOTATE_CLR_NOINLINE void RecordAllocation(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->record_allocation(p, s); }
    static ANNOTATE_CLR_NOINLINE void RecordDeallocation(void *p)      { _ANNOTATE_ROUTINES_ADDR->record_deallocation(p); }
    static ANNOTATE_CLR_NOINLINE void InductionUses(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->induction_uses(p, s); }
    static ANNOTATE_CLR_NOINLINE void ReductionUses(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->reduction_uses(p, s); }
    static ANNOTATE_CLR_NOINLINE void ObserveUses(void *p, size_t s)   { _ANNOTATE_ROUTINES_ADDR->observe_uses(p, s); }
    static ANNOTATE_CLR_NOINLINE void ClearUses(void *p)               { _ANNOTATE_ROUTINES_ADDR->clear_uses(p); }
    static ANNOTATE_CLR_NOINLINE void DisablePush(__itt_model_disable d) { _ANNOTATE_ROUTINES_ADDR->disable_push(d); }
    static ANNOTATE_CLR_NOINLINE void DisablePop()                     { _ANNOTATE_ROUTINES_ADDR->disable_pop(); }
    static ANNOTATE_CLR_NOINLINE void AggregateTask(size_t c)          { _ANNOTATE_ROUTINES_ADDR->aggregate_task(c); }
};
#if defined(WIN32) && defined(__CLR_VER)
#pragma managed(pop)
#endif
#undef ANNOTATE_CLR_NOINLINE
#endif

#if defined(__cplusplus) && defined(WIN32) && defined(__CLR_VER)

#define ANNOTATE_SITE_BEGIN(_SITE) Annotate::SiteBegin(#_SITE)
#define ANNOTATE_SITE_END(...) Annotate::SiteEnd()
#define ANNOTATE_TASK_BEGIN(_TASK) Annotate::TaskBegin(#_TASK)
#define ANNOTATE_TASK_END(...) Annotate::TaskEnd()
#define ANNOTATE_ITERATION_TASK(_TASK) Annotate::IterationTask(#_TASK)
#define ANNOTATE_LOCK_ACQUIRE(_ADDR) Annotate::LockAcquire(_ADDR)
#define ANNOTATE_LOCK_RELEASE(_ADDR) Annotate::LockRelease(_ADDR)
#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE) Annotate::RecordAllocation((_ADDR), (_SIZE))
#define ANNOTATE_RECORD_DEALLOCATION(_ADDR) Annotate::RecordDeallocation(_ADDR)
#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE) Annotate::InductionUses((_ADDR), (_SIZE))
#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE) Annotate::ReductionUses((_ADDR), (_SIZE))
#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE) Annotate::ObserveUses((_ADDR), (_SIZE))
#define ANNOTATE_CLEAR_USES(_ADDR) Annotate::ClearUses(_ADDR)
#define ANNOTATE_DISABLE_OBSERVATION_PUSH Annotate::DisablePush(itt_model_disable_observation)
#define ANNOTATE_DISABLE_OBSERVATION_POP Annotate::DisablePop()
#define ANNOTATE_DISABLE_COLLECTION_PUSH Annotate::DisablePush(__itt_model_disable_collection)
#define ANNOTATE_DISABLE_COLLECTION_POP Annotate::DisablePop()
#define ANNOTATE_AGGREGATE_TASK(_COUNT) Annotate::AggregateTask(_COUNT)

#else

/* Mark the start of a site (region) to be analyzed by the tool */
#define ANNOTATE_SITE_BEGIN(_SITE) _ANNOTATE_CALL_1(site_beginA, #_SITE)

/* Mark the end of a site (region) to be analyzed by the tool and

 * indicate a WaitForAll task synchronization */
#define ANNOTATE_SITE_END(...) _ANNOTATE_CALL_0(site_end_2)

/* Mark the beginning of a region of code that constitutes a task */
#define ANNOTATE_TASK_BEGIN(_TASK) _ANNOTATE_CALL_1(task_beginA, #_TASK)

/* Mark the end of a region of code that constitutes a task */
#define ANNOTATE_TASK_END(...) _ANNOTATE_CALL_0(task_end_2)

/* Mark the break between one task and the next task (a "split" description model

 * rather than a "begin/end" description model. */
#define ANNOTATE_ITERATION_TASK(_TASK) _ANNOTATE_CALL_1(iteration_taskA, #_TASK)

/* Acquire a lock identified by lockId */
#define ANNOTATE_LOCK_ACQUIRE(_ADDR) _ANNOTATE_CALL_1(lock_acquire_2, (_ADDR))

/* Release a lock identified by lockId */
#define ANNOTATE_LOCK_RELEASE(_ADDR) _ANNOTATE_CALL_1(lock_release_2, (_ADDR))

/* Record user allocation of memory */
#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE) _ANNOTATE_CALL_2(record_allocation, (_ADDR), (_SIZE))

/* Record user deallocation of memory */
#define ANNOTATE_RECORD_DEALLOCATION(_ADDR) _ANNOTATE_CALL_1(record_deallocation, (_ADDR))

/* Denote storage as an inductive value */
#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(induction_uses, (_ADDR), (_SIZE))

/* Denote storage as a reduction */
#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(reduction_uses, (_ADDR), (_SIZE))

/* Record all observations of uses */
#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(observe_uses, (_ADDR), (_SIZE))

/* Clear handling of values */
#define ANNOTATE_CLEAR_USES(_ADDR) _ANNOTATE_CALL_1(clear_uses, (_ADDR))

/* Push disable of observations */
#define ANNOTATE_DISABLE_OBSERVATION_PUSH _ANNOTATE_CALL_1(disable_push, __itt_model_disable_observation)

/* Pop disable of observations */
#define ANNOTATE_DISABLE_OBSERVATION_POP _ANNOTATE_CALL_0(disable_pop)

/* Push disable of collection */
#define ANNOTATE_DISABLE_COLLECTION_PUSH _ANNOTATE_CALL_1(disable_push, __itt_model_disable_collection)

/* Pop disable of collection */
#define ANNOTATE_DISABLE_COLLECTION_POP _ANNOTATE_CALL_0(disable_pop)

/* Task aggregation */
#define ANNOTATE_AGGREGATE_TASK(_COUNT) _ANNOTATE_CALL_1(aggregate_task, (_COUNT))

#endif

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* ANNOTATE_EXPAND_NULL */

#endif /* _ADVISOR_ANNOTATE_H_ */