Current File : //usr/include/libmtsk_db.h
/*
 */

/*	
 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_LIBMTSK_DB_H
#define	_LIBMTSK_DB_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <proc_service.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct mtsk_db_spawn_func_t {
    char *symbol_name;
    int   o_register_num;
} mtsk_db_spawn_func_t;

/*
 * Error codes returned by libmtsk routines.
 */
 
typedef enum {
    MTSK_DB_NO_CAP=-1,       /* This function is not supported in libmtsk_db */
    MTSK_DB_OK=0,            /* Everything is fine */
    MTSK_DB_VERSION_ERROR,   /* This libmtsk_db cannot support the a.out */
    MTSK_DB_NOT_OMP_THREAD,  /* This thread is not an openmp thread */
    MTSK_DB_NOT_IN_PARALLEL, /* Not in parallel region */
    MTSK_DB_ADDRESS_INVALID, /* If address provided by dbx is invalid */
    MTSK_DB_ERROR,           /* Unknown error, like ps_read failed etc. */
    MTSK_DB_LIBMTSK_HANDLE_INVALID,   /*libmtsk handle is invalid*/    
    MTSK_DB_THREAD_HANDLE_INVALID,    /*thread handle is invalid*/
    MTSK_DB_PARALLEL_HANDLE_INVALID,  /*parallel region handle is invalid*/
    MTSK_DB_TASK_HANDLE_INVALID,      /*task handle is invalid*/
    MTSK_DB_ATTRID_INVALID,            /*attr_id is invalid*/
    MTSK_DB_PAR_ID_INVALID,           /*task_id is invalid*/    
    MTSK_DB_TASK_ID_INVALID,           /*task_id is invalid*/    
    MTSK_DB_EVENT_ID_INVALID,          /*event_id is invalid*/
    MTSK_DB_NO_CURRENT_LOOP            /*the thread is not working on openmp loop*/
} mtsk_db_errno_t;


/*
 * Called by the debugger once to initialize the debug support library.
 * Return handle, that should be used with subsequent queries.
 */

void *mtsk_db_init (struct ps_prochandle *);

/*
 * Called to destroy the handle, and clean up.
 */

void mtsk_db_fini (void *handle);

/*
 * This is called when dbx is about to resume the process, *or* 
 * immediately after dbx has stopped the process.  Either way it
 * indicates that the library needs to flush anyvcached values 
 * from the process that might change.
 */  

void mtsk_db_proc_flush(void *handle);
    
/*
 * Returns a list of items where each item includes the name of a 
 * function which can spawn a new parallel region, and which parameter 
 * holds the pointer to the mfunction.  This is used to support
 * stepping into a region in dbx.
 *
 * This function allocates an array of return type structure
 * using malloc. The count is set to the number of elements in the
 * array. It is the responsibility of the caller to free the returned
 * structure.
 */

struct mtsk_db_spawn_func_t *mtsk_db_spawn_funcs(int *count);
    
/*
 * This is to support the ability to print OMP thread
 * private variables in dbx.  A thread private variable
 * "x" will have a global variable "__tls_x" (or similar)
 * defined by the front end.  This will hold some kind
 * of pointer.  Dbx will need to used stabs info to
 * correlate "x" and "__tls_x", and then read the value
 * in "__tls_x" and use this value as 'base' when calling
 * libmtsk_db_thread_private_addr().  The address
 * in tp_var is the address of the instance of "x" for
 * the given thread.  Note: dbx will have no knowledge
 * of any mangling scheme used to go from the name "x"
 * to the name "__tls_x" (or whatever name it turns out
 * to be) The relationship between these two symbol names
 * will be recorded in the debug information.
 * 
 * For Fortran common blocks dbx will pass in the base
 * address of the common block, and the API will 
 * attempt to return the base address of the 
 * thread private chunk for the given tid. Individual
 * field offsets can be obtained by dbx from the stabs.
 * 
 * Return one of the error codes in libmtsk_db_errno_t
 * On success (MTSK_DB_OK), tp_var will contain the
 * address of the thread private data for this thread.
 */

mtsk_db_errno_t mtsk_db_thread_private_var_addr(void *handle,
                                                pthread_t tid,
                                                unsigned long base,
                                                unsigned long *tp_var);
    
/*
 * This function will be called only for the bottom
 * "slave" frame on a stack.  If the master and slave
 * frames are on the same thread, dbx will find the
 * master frame without help.
 *  
 * Dbx provides the thread id of a slave thread which
 * was assigned by the libmtask scheduler.
 * If the tid is not currently assigned to a parallel
 * region, then this function returns -1 as a return value.
 * Otherwise, it returns 0 and assigns a thread id, and
 * a frame pointer value to the reference parameters.
 * 
 * These point to the master frame/thread (or to slightly
 * newer frames).  Dbx will search backwards on the stack
 * from this point looking for the first frame of the function
 * that dbx knows is the "parent" for the mfunction where it
 * started.
 * 
 * Return one of the error codes in in libmtsk_db_errno_t
 * On success (MTSK_DB_OK), solaris_tid and the FP will
 * contain valid information
 */

mtsk_db_errno_t mtsk_db_slave_to_master(void *handle,
                                        pthread_t slave_tid,
                                        pthread_t *solaris_tid,
                                        unsigned long *FP);

/*
 * The new interfaces added in libmtsk_db is to help dbx show openmp items. Currently the items
 * include thread, parallel region, worksharing constructs and task.
 * 
 * For each item, dbx uses attribute id to query attributes. That is to make the interface easy 
 * to keep backward compatibility. 
 * 
 * The attribute is saved in the memory pointed by attr_data. This memory should be allocated by 
 * dbx. Different attribute has different data type. The types are listed in the comments for 
 * attribute id.
 *
 * Each API will return 0 if success. Otherwise, the return value indicates the fail reason.
 *
 */


/****************************
 
 API for versioning
  
 ***************************/ 

typedef enum {
    UNKNOWN = 0,
    ARCHIVE_LIB_7_1,
    SHARED_LIB_8_1,
    SHARED_LIB_8_2
} library_version;

mtsk_db_errno_t mtsk_db_get_version(void * p_libmtsk_handle, library_version * p_version);

/*************************
  
  APIs for omp thread.
 
 ************************/

/*
 * This function get /thread_handle/ of given omp thread whose pthread id is /tid/. It returns 0 for success.
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID  
 * MTSK_DB_NOT_OMP_THREAD
 */
  
mtsk_db_errno_t mtsk_db_get_thread_handle(void * p_libmtsk_handle, pthread_t tid, psaddr_t * thread_handle);


typedef enum{
   /* 
    * data: current parallel region handle
    * type: psaddr_t
    */
   MTSK_THREAD_PAR_REG,   
   /*
    * data: current task handle
    * type: psaddr_t
    */ 
   MTSK_THREAD_TASK_REG,
   /*
    * data: thread state
    * type: MT_THR_STATE 
    */ 
   MTSK_THREAD_STATE,     
   /*
    * data: omp thread tid in current team.
    *       it's always from 0 to teamsize-1
    *       team_tid equals 0 means this is a master thread. 
    * type: int32_t
    */ 
   MTSK_THREAD_TEAM_TID,
   /*
    * data: pthread id for given team
    * type: pthread_t
    */
   MTSK_THREAD_TID

} MTSK_THREAD_ATTR_ID;


/* [THR_STAT] */
/*
 * This enum lists the states recorded internally by libmtsk.  
 */

typedef enum {
    MT_THR_NO_STATE = 0,      /* Not initialized */

    MT_THR_OVHD_STATE = 1,    /* Overhead */
    MT_THR_WORK_STATE = 2,    /* Useful work, excluding reduction, master, 
                                 single, critical */
    MT_THR_IBAR_STATE = 3,    /* In an implicit barrier */
    MT_THR_EBAR_STATE = 4,    /* In an explicit barrier */
    MT_THR_IDLE_STATE = 5,    /* Slave waiting for work */
    MT_THR_SERIAL_STATE = 6,  /* thread not in any OMP parallel region 
                                 (initial thread only) */
    MT_THR_REDUC_STATE = 7,   /* Reduction */
    MT_THR_LKWT_STATE = 8,    /* Waiting for lock */
    MT_THR_CTWT_STATE = 9,    /* Waiting to enter critical region */
    MT_THR_ODWT_STATE = 10,   /* Waiting to execute an ordered region */
    MT_THR_ATWT_STATE = 11,   /* Waiting to enter an atomic region */
    MT_THR_TSKWT_STATE = 12,  /* Waiting for child tasks finishing */

    MT_THR_LAST_STATE
} MT_THR_STATE;

/*
 * This function gets thread /attr_data/ according to /attr_id/. Dbx needs to provide /thread_handle/ for target thread.
 *
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_THREAD_HANDLE_INVALID
 * MTSK_DB_ATTRID_INVALID
 */

mtsk_db_errno_t mtsk_db_get_thread_attribute(void * p_libmtsk_handle, psaddr_t thread_handle, MTSK_THREAD_ATTR_ID attr_id, void * attr_data);

/*
 * The only attribute ID allowed now is MTSK_THREAD_TEAM_TID.
 */

mtsk_db_errno_t mtsk_db_get_thread_attribute_in_parallel_region(void * p_libmtsk_handle, psaddr_t thread_handle, psaddr_t parallel_handle, MTSK_THREAD_ATTR_ID attr_id, void * attr_data);

/************************************
 
  APIs for omp parallel region.
 
 *************************************/


/*
 * This function gets /parallel_handle/ of a parallel region according to its /par_id/. 
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_PAR_ID_INVALID
 */ 

mtsk_db_errno_t mtsk_db_get_parallel_handle(void * p_libmtsk_handle, uint64_t par_id, psaddr_t * parallel_handle);

/*
 * This is the type for dbx callback function. Dbx can define such functions to deal with each handle passed by libmtsk_db.
 */

typedef int mtsk_db_iterator_func(psaddr_t handle, void *paramters);

/*
 * This function goes through active parallel regions and call /callback_func/ with the parallel handle and /callback_data/
 * for each region. 
 * With these active parallel regions and their parent attribute, dbx can explore all parallel regions 
 * and build the parallel region tree.
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 *
 * NOTE:If the callback function returns negative value, the iterate function will return MTSK_DB_OK immediately.
 */

mtsk_db_errno_t mtsk_db_active_parallel_iterate(void * p_libmtsk_handle, mtsk_db_iterator_func * callback_func, void * callback_data);

typedef enum{
    /*
     * data: parallel region id
     * type: uint64_t
     */
    MTSK_PARALLEL_ID,            
    /*
     * data: number of threads in current team 
     * type: uint16_t
     */
    MTSK_PARALLEL_TEAM_SIZE,
    /*
     * data: pc for instruction of MasterFunction call
     *       It can be resolved to file name and line number of omp pragma
     *       by dbx using debugging information
     * type: psaddr_t
     *
     */
    MTSK_PARALLEL_LOCATION,
    /*
     * data: handle for parent parallel region
     * type: psaddr_t
     */
    MTSK_PARALLEL_PARENT
}MTSK_PARALLEL_ATTR_ID;

/*
 * This function gets parallel /attr_data/ according to /attr_id/.  The target 
 * parallel region is specified by /parallel_handle/.
 *
 * This function may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_PARALLEL_HANDLE_INVALID
 * MTSK_DB_ATTRID_INVALID
 */

mtsk_db_errno_t mtsk_db_get_parallel_attribute(void * p_libmtsk_handle, psaddr_t parallel_handle,  MTSK_PARALLEL_ATTR_ID attr_id, void * attr_data);

/*
 * This function goes through all threads in the team and call /callback_func/ with thread handle and /callback_data/ for each thread.
 *
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_PARALLEL_HANDLE_INVALID
 *
 * NOTE:If the callback function returns negative value, the iterate function will return MTSK_DB_OK immediately.
 */

mtsk_db_errno_t mtsk_db_team_thread_iterate(void * p_libmtsk_handle, psaddr_t parallel_handle, mtsk_db_iterator_func * callback_func, void * callback_data);

/************************************
 
  APIs for omp loop.
 
 *************************************/
 
 /*
  * This function gets /loop_handle/ for the openmp loop that /current_thread/ is working on.
  * It may fail if:
  * MTSK_DB_LIBMTSK_HANDLE_INVALID
  * MTSK_DB_NOT_OMP_THREAD
  * MTSK_DB_NO_CURRENT_LOOP
  */  

mtsk_db_errno_t mtsk_db_get_current_loop(void * p_libmtsk_handle, pthread_t current_thread, psaddr_t * loop_handle);

typedef enum
{
    INDEX_INT = 0,
    INDEX_UINT,
    INDEX_LL,
    INDEX_ULL,
    INDEX_SH,
    INDEX_USH,
    INDEX_CH,
    INDEX_UCH
} indexType_t;

typedef union loop_index_type
{
    int i;
    unsigned int ui;
    long long ll;
    unsigned long long ull;
    short int sh;
    unsigned short int ush;
    char ch;
    unsigned char uch;
} loopIndex_t;

typedef enum
{
    SCHEDTYPE_NONE = 0,
    SCHEDTYPE_STATIC,
    SCHEDTYPE_SELF,
    SCHEDTYPE_GSS,
    SCHEDTYPE_FACTORING,
    SCHEDTYPE_AFFINITY,
    SCHEDTYPE_NUMCHUNKS,

    /* For IROPT internal use */
    SCHEDTYPE_INC_TRIANGULAR,
    SCHEDTYPE_INC_LOWER_TRIANGULAR, 
    SCHEDTYPE_DEC_TRIANGULAR,

    /* OpenMP */
    SCHEDTYPE_OMP_STATIC,
    SCHEDTYPE_OMP_GUIDED,
    SCHEDTYPE_OMP_DYNAMIC,
    SCHEDTYPE_OMP_RUNTIME,

    /* NUMA */
    SCHEDTYPE_NUMA,

    /* Other */
    SCHEDTYPE_OMP_AUTO

} sun_sched_t;

typedef enum{
    /*
     * data: flag for ordered loop
     *       It is set to 1 if the loop is ordered. Otherwise it is set to 0.
     * type: int 
     */
    MTSK_LOOP_HAS_ORDER,
    /*
     * data: type of loop index
     *       This is used by dbx to get correct lower bound and upper bound value
     *       from data passed by libmtsk_db
     * type: indexType_t
     */
    MTSK_LOOP_INDEX_TYPE, 
    /*
     * data: loop lower bound
     * type: loopIndex_t
     */
    MTSK_LOOP_LOWER_BOUND,
    /*
     * data: loop upper bound     
     * type: loopIndex_t
     */
    MTSK_LOOP_UPPER_BOUND,
    /*
     * data: loop step
     *       Note: Loop step should be a corresponding signed type to loop index.
     *             This work well in most cases. But it will still display wrong
     *             result if the step is a big unsigned value. 
     *             Libmtsk does not care whether the step is signed or unsigned.
     * type: loopIndex_t
     */
    MTSK_LOOP_STEP,
    
    /*
     * data: loop chunk
     * type: loopIndex_t
     */
    MTSK_LOOP_CHUNK,
    
    /*
     * data: loop scheduling type
     *       Note: only openmp scheduling type should be displayed
     * type: sun_sched_t
     */
    
    MTSK_LOOP_SCHEDULE_TYPE,
    
    /*
     * data: omp loop location
     *       That is the pc for call instruction of libmtsk entry function for openmp loop
     *       It may be the same as parallel location if it is a combined "parallel for" pragma.     
     */
    MTSK_LOOP_LOCATION
    
}MTSK_LOOP_ATTR_ID;

/*
 * This function gets loop /attr_data/ according to /attr_id/.  The target 
 * loop is specified by /parallel_handle/.
 *
 * This function may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_LOOP_HANDLE_INVALID
 * MTSK_DB_ATTRID_INVALID
 */

mtsk_db_errno_t mtsk_db_get_loop_attribute(void * p_libmtsk_handle, psaddr_t loop_handle, MTSK_LOOP_ATTR_ID attr_id, void * attr_data);

/***********************
 
  APIs for omp task.
 
 **********************/

/*
 * This function gets /task_handle/ for omp task entity according to its /task_id/.
 * It will fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_TASK_ID_INVALID
 */
 
mtsk_db_errno_t mtsk_db_get_task_handle(void * p_libmtsk_handle, uint64_t task_id, psaddr_t * task_handle);

/*
 * This function goes through all tasks currently being executed in given parallel region and calls /callback_func/ with
 * task handle and /callback_data/ for each task.
 *
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_PARALLEL_HANDLE_INVALID
 *
 * NOTE:If the callback function returns negative value, the iterate function will return MTSK_DB_OK immediately.
 */

mtsk_db_errno_t mtsk_db_active_task_iterate(void * p_libmtsk_handle, psaddr_t parallel_handle, mtsk_db_iterator_func * callback_func,void * callback_data);

/*
 * This function goes through all tasks created but not executed in given parallel region and calls /callback_func/ with
 * task handle and /callback_data/ for each task.
 *
 * The enqueued tasks and active tasks cover all leaves on the task tree. So dbx can explore all tasks from these 2 lists.
 * 
 * It may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_PARALLEL_HANDLE_INVALID
 *
 * NOTE:If the callback function returns negative value, the iterate function will return MTSK_DB_OK immediately.
 */
mtsk_db_errno_t mtsk_db_enqueued_task_iterate(void * p_libmtsk_handle, psaddr_t parallel_handle, mtsk_db_iterator_func * callback_func, void * callback_data);

typedef enum{
    /*
     * data: task id
     * type: uint64_t
     */
    MTSK_TASK_ID,
    /*
     * data: task type
     * type: MT_TASK_TYPE 
     */
    MTSK_TASK_TYPE,
    /*
     * data: task state
     * type: MT_TASK_STATE
     */
    MTSK_TASK_STATE,
    /*
     * data: handle of thread executing the task
     * type: psaddr_t 
     */
    MTSK_TASK_EXEC_THREAD,
    /*
     * data: pc for instruction of OmptaskFunction call
     * type: psaddr_t
     */
    MTSK_TASK_LOCATION,
    /*
     * data: number of unfinished children
     * type: int
     */
    MTSK_NUM_UNFINISHED_CHILDREN,
    /*
     * data: handle of parent task
     * type: psaddr_t
     */
    MTSK_TASK_PARENT 
}MTSK_TASK_ATTR_ID;

typedef enum{
    MT_TASK_EXPLICIT,
    MT_TASK_IMPLICIT 
}MT_TASK_TYPE;

typedef enum{
    MT_TASK_CREATED,
    MT_TASK_EXECUTING,
    MT_TASK_WAITING,
    MT_TASK_FINISHED,
}MT_TASK_STATE;

/*
 * This function gets task /attr_data/ according to /attr_id/. 
 * The target task is specified by /task_handle/.
 * 
 * This function may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_TASK_HANDLE_INVALID
 * MTSK_DB_ATTRID_INVALID
 */
mtsk_db_errno_t mtsk_db_get_task_attribute(void * p_libmtsk_handle, psaddr_t task_handle, MTSK_TASK_ATTR_ID attr_id, void * attr_data);

/***********************
 
  APIs for omp events.

 ***********************/ 
typedef uint64_t MTSK_DB_EVENT_ID;
#define OMP_EXPLICIT_BARRIER_ENTER 0x000001
#define OMP_EXPLICIT_BARRIER_EXIT  0x000002
#define OMP_IMPLICIT_BARRIER_ENTER 0x000004
#define OMP_IMPLICIT_BARRIER_EXIT  0x000008
#define OMP_TASKWAIT_ENTER         0x000010
#define OMP_TASKWAIT_EXIT          0x000020
#define OMP_ORDERED_BEGIN          0x000040
#define OMP_ORDERED_ENTER          0x000080
#define OMP_ORDERED_EXIT           0x000100
#define OMP_CRITICAL_BEGIN         0x000200
#define OMP_CRITICAL_ENTER         0x000400
#define OMP_CRITICAL_EXIT          0x000800
#define OMP_ATOMIC_BEGIN           0x001000
#define OMP_ATOMIC_EXIT            0x002000
#define OMP_FLUSH_IMPLICIT         0x004000
#define OMP_FLUSH_EXPLICIT         0x008000
#define OMP_MASTER_BEGIN           0x010000
#define OMP_MASTER_END             0x020000
#define OMP_SINGLE_BEGIN           0x040000
#define OMP_SINGLE_END             0x080000
#define OMP_TASK_CREATE            0x100000
#define OMP_TASK_START             0x200000
#define OMP_TASK_FINISH            0x400000
#define OMP_EXPLICIT_BARRIER_ALLENTERED 0x0800000
#define OMP_IMPLICIT_BARRIER_ALLENTERED 0x1000000
#define OMP_THREAD_BEGIN 0x2000000
#define OMP_MAX_EVENT 0x2000000

/*
 * These functions enable/disable omp events on given thread.
 * Some events listed up may not be implemented. If so, the API will return an error.
 * The event_id can be a combination of events.
 * 
 * These functions may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_NOT_OMP_THREAD
 * MTSK_DB_EVENT_ID_INVALID
 */
mtsk_db_errno_t mtsk_db_monitor_omp_event(void * p_libmtsk_handle, pthread_t thread_id, int on_off, MTSK_DB_EVENT_ID event_id);

/*
 * These functions check if omp events specified /event_id/ is /enabled/ on given thread.
 * If the event_id is a combination of events, the result will be true only if all these events are enabled.
 *
 * This function may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 * MTSK_DB_NOT_OMP_THREAD
 * MTSK_DB_EVENT_ID_INVALID
 */

mtsk_db_errno_t mtsk_db_is_enabled_omp_thread_event(void * p_libmtsk_handle, pthread_t thread_id, MTSK_DB_EVENT_ID event_id, int32_t * enabled);

/*
 * stub fuctions for event monitoring.
 * These functions will be called by libmtsk at the event definition point when that event is monitored.
 *
 * The events for critical, ordered and atomic means:
 * - begin: Thread is going to start the waiting loop for critical/ordered/atomic
 * - enter: Thread finished the waiting and entered the protected area.  
 * - exit:  Thread left the protected area.
 *
 * The atomic does not have enter event. Currently, atomic is implemented the same as critical. But
 * if it is really implemented with atomic operations, there is no such entered status. So we only
 * provide begin and exit for atomic.
 *
 * For master and single, we have 2 events:
 * - begin: Thread entered the single area.
 * - end:   Thread left the single area.  
 *
 */

void mtsk_event_explicit_barrier_enter(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_explicit_barrier_allentered(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_explicit_barrier_exit(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_implicit_barrier_enter(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_implicit_barrier_allentered(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_implicit_barrier_exit(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_taskwait_enter(pthread_t thread_id, uint64_t task_id);
void mtsk_event_taskwait_exit(pthread_t thread_id, uint64_t task_id);

void mtsk_event_ordered_begin(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_ordered_enter(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_ordered_exit(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_critical_begin(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_cirtical_enter(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_critical_exit(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_atomic_begin(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_atomic_exit(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_implicit_flush(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_explicit_flush(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_master_begin(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_master_end(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_single_begin(pthread_t thread_id, uint64_t pr_id);
void mtsk_event_single_end(pthread_t thread_id, uint64_t pr_id);

void mtsk_event_task_create(pthread_t thread_id, uint64_t task_id);
void mtsk_event_task_start(pthread_t thread_id, uint64_t task_id);
void mtsk_event_task_finish(pthread_t thread_id, uint64_t task_id);

void mtsk_event_thread_begin(pthread_t thread_id);

/*******************************
  
  APIs for serialize one region

 ********************************/
/*
 * This function will set the number of threads to 1 for next parallel region. 
 * After entering the paralle region, the number of threads will be restored.
 * So the next encountered parallel region will be parallelized.
 *
 * How to use this API?
 *
 * User needs to stop before the parallel region and issue the serialization command. 
 * After that, dbx call this function to serialize the parallel region. If user choose to
 * serialize next parallel regions meets by all team threads, the tid can be set to -1
 * to represent that.
 *
 * This function may fail if:
 * MTSK_DB_LIBMTSK_HANDLE_INVALID
 */

mtsk_db_errno_t mtsk_db_serialize_next_par_region(void * p_libmtsk_handle, pthread_t tid);


#ifdef __cplusplus
}
#endif

#endif	/* _LIBMTSK_DB_H */