[Openmp-commits] [openmp] r241832 - Enable debugger support

Jonathan Peyton jonathan.l.peyton at intel.com
Thu Jul 9 11:16:59 PDT 2015


Author: jlpeyton
Date: Thu Jul  9 13:16:58 2015
New Revision: 241832

URL: http://llvm.org/viewvc/llvm-project?rev=241832&view=rev
Log:
Enable debugger support

These changes enable external debuggers to conveniently interface with 
the LLVM OpenMP Library.  Structures are added which describe the important
internal structures of the OpenMP Library e.g., teams, threads, etc.
This feature is turned on by default (CMake variable LIBOMP_USE_DEBUGGER)
and can be turned off with -DLIBOMP_USE_DEBUGGER=off.

Differential Revision: http://reviews.llvm.org/D10038

Added:
    openmp/trunk/runtime/src/kmp_debugger.c   (with props)
    openmp/trunk/runtime/src/kmp_debugger.h   (with props)
Modified:
    openmp/trunk/runtime/CMakeLists.txt
    openmp/trunk/runtime/cmake/Definitions.cmake
    openmp/trunk/runtime/cmake/SourceFiles.cmake
    openmp/trunk/runtime/src/dllexports
    openmp/trunk/runtime/src/exports_so.txt
    openmp/trunk/runtime/src/kmp.h
    openmp/trunk/runtime/src/kmp_barrier.cpp
    openmp/trunk/runtime/src/kmp_omp.h
    openmp/trunk/runtime/src/kmp_runtime.c
    openmp/trunk/runtime/src/makefile.mk
    openmp/trunk/runtime/tools/src/common-tools.mk

Modified: openmp/trunk/runtime/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/CMakeLists.txt?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/CMakeLists.txt (original)
+++ openmp/trunk/runtime/CMakeLists.txt Thu Jul  9 13:16:58 2015
@@ -124,6 +124,10 @@ set(LIBOMP_OSX_ARCHITECTURES "${CMAKE_OS
     "For Mac builds, semicolon separated list of architectures to build for universal fat binary.")
 set(CMAKE_OSX_ARCHITECTURES ${LIBOMP_OSX_ARCHITECTURES})
 
+# - Code that allows the OpenMP library to conveniently interface with debuggers
+set(LIBOMP_USE_DEBUGGER true CACHE BOOL
+    "Enable debugger interface code?")
+
 # OMPT-support
 set(LIBOMP_OMPT_SUPPORT false CACHE BOOL
     "OMPT-support?")
@@ -590,6 +594,7 @@ if(${LIBOMP_STANDALONE_BUILD})
     endif()
     say("LIBOMP: Build                -- ${build}")
     say("LIBOMP: Stats-Gathering      -- ${LIBOMP_STATS}")
+    say("LIBOMP: Debugger-support     -- ${LIBOMP_USE_DEBUGGER}")
     say("LIBOMP: OMPT-support         -- ${LIBOMP_OMPT_SUPPORT}")
     if(${LIBOMP_OMPT_SUPPORT})
         say("LIBOMP: OMPT-blame           -- ${LIBOMP_OMPT_BLAME}")

Modified: openmp/trunk/runtime/cmake/Definitions.cmake
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/cmake/Definitions.cmake?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/cmake/Definitions.cmake (original)
+++ openmp/trunk/runtime/cmake/Definitions.cmake Thu Jul  9 13:16:58 2015
@@ -102,6 +102,11 @@ function(append_cpp_flags input_cpp_flag
     else()
         append_definitions("-D KMP_STATS_ENABLED=0")
     endif()
+    if(${LIBOMP_USE_DEBUGGER})
+        append_definitions("-D USE_DEBUGGER=1")
+    else()
+        append_definitions("-D USE_DEBUGGER=0")
+    endif()
     if(${LIBOMP_OMPT_SUPPORT})
         append_definitions("-D OMPT_SUPPORT=1")
     else()

Modified: openmp/trunk/runtime/cmake/SourceFiles.cmake
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/cmake/SourceFiles.cmake?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/cmake/SourceFiles.cmake (original)
+++ openmp/trunk/runtime/cmake/SourceFiles.cmake Thu Jul  9 13:16:58 2015
@@ -42,6 +42,7 @@ function(set_c_files input_c_source_file
         append_c_source_file("kmp_atomic.c")
         append_c_source_file("kmp_csupport.c")
         append_c_source_file("kmp_debug.c")
+        append_c_source_file("kmp_debugger.c")
         append_c_source_file("kmp_itt.c")
         append_c_source_file("kmp_environment.c")
         append_c_source_file("kmp_error.c")

Modified: openmp/trunk/runtime/src/dllexports
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/dllexports?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/dllexports (original)
+++ openmp/trunk/runtime/src/dllexports Thu Jul  9 13:16:58 2015
@@ -182,6 +182,10 @@
     %endif
 
 
+#if USE_DEBUGGER
+        __kmp_debugging                         DATA
+        __kmp_omp_debug_struct_info             DATA
+#endif /* USE_DEBUGGER */
 
         # Symbols for MS mutual detection:
         _You_must_link_with_exactly_one_OpenMP_library    DATA

Modified: openmp/trunk/runtime/src/exports_so.txt
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/exports_so.txt?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/exports_so.txt (original)
+++ openmp/trunk/runtime/src/exports_so.txt Thu Jul  9 13:16:58 2015
@@ -32,6 +32,13 @@ VERSION {
         _You_must_link_with_*;     # Mutual detection/MS compatibility symbols.
 
 
+        #
+        # Debugger support.
+        #
+#if USE_DEBUGGER
+        __kmp_debugging;
+        __kmp_omp_debug_struct_info;
+#endif /* USE_DEBUGGER */
 
         #
         # Internal functions exported for testing purposes.

Modified: openmp/trunk/runtime/src/kmp.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp.h?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp.h (original)
+++ openmp/trunk/runtime/src/kmp.h Thu Jul  9 13:16:58 2015
@@ -86,6 +86,9 @@ class kmp_stats_list;
 #include "kmp_version.h"
 #include "kmp_debug.h"
 #include "kmp_lock.h"
+#if USE_DEBUGGER
+#include "kmp_debugger.h"
+#endif
 #include "kmp_i18n.h"
 
 #define KMP_HANDLE_SIGNALS (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_WINDOWS || KMP_OS_DARWIN)
@@ -1663,6 +1666,11 @@ typedef struct KMP_ALIGN_CACHE kmp_bstat
     kmp_uint8 offset;
     kmp_uint8 wait_flag;
     kmp_uint8 use_oncore_barrier;
+#if USE_DEBUGGER
+    // The following field is intended for the debugger solely. Only the worker thread itself accesses this
+    // field: the worker increases it by 1 when it arrives to a barrier.
+    KMP_ALIGN_CACHE kmp_uint b_worker_arrived;
+#endif /* USE_DEBUGGER */
 } kmp_bstate_t;
 
 union KMP_ALIGN_CACHE kmp_barrier_union {
@@ -1679,6 +1687,13 @@ union KMP_ALIGN_CACHE kmp_barrier_team_u
     char         b_pad[ CACHE_LINE ];
     struct {
         kmp_uint     b_arrived;       /* STATE => task reached synch point. */
+#if USE_DEBUGGER
+        // The following two fields are indended for the debugger solely. Only master of the team accesses
+        // these fields: the first one is increased by 1 when master arrives to a barrier, the
+        // second one is increased by one when all the threads arrived.
+        kmp_uint     b_master_arrived;
+        kmp_uint     b_team_arrived;
+#endif
     };
 };
 
@@ -2718,12 +2733,22 @@ extern kmp_info_t __kmp_monitor;
 extern volatile kmp_uint32 __kmp_team_counter;      // Used by Debugging Support Library.
 extern volatile kmp_uint32 __kmp_task_counter;      // Used by Debugging Support Library.
 
+#if USE_DEBUGGER
+
 #define _KMP_GEN_ID( counter )                                         \
     (                                                                  \
+        __kmp_debugging                                                \
+        ?                                                              \
+        KMP_TEST_THEN_INC32( (volatile kmp_int32 *) & counter ) + 1    \
+        :                                                              \
         ~ 0                                                            \
     )
-
-
+#else
+#define _KMP_GEN_ID( counter )                                         \
+    (                                                                  \
+        ~ 0                                                            \
+    )
+#endif /* USE_DEBUGGER */
 
 #define KMP_GEN_TASK_ID()    _KMP_GEN_ID( __kmp_task_counter )
 #define KMP_GEN_TEAM_ID()    _KMP_GEN_ID( __kmp_team_counter )

Modified: openmp/trunk/runtime/src/kmp_barrier.cpp
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_barrier.cpp?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_barrier.cpp (original)
+++ openmp/trunk/runtime/src/kmp_barrier.cpp Thu Jul  9 13:16:58 2015
@@ -1104,7 +1104,14 @@ __kmp_barrier(enum barrier_type bt, int
         if (__itt_sync_create_ptr || KMP_ITT_DEBUG)
             __kmp_itt_barrier_starting(gtid, itt_sync_obj);
 #endif /* USE_ITT_BUILD */
-
+#if USE_DEBUGGER
+        // Let the debugger know: the thread arrived to the barrier and waiting.
+        if (KMP_MASTER_TID(tid)) { // Master counter is stored in team structure.
+            team->t.t_bar[bt].b_master_arrived += 1;
+        } else {
+            this_thr->th.th_bar[bt].bb.b_worker_arrived += 1;
+        } // if
+#endif /* USE_DEBUGGER */
         if (reduce != NULL) {
             //KMP_DEBUG_ASSERT( is_split == TRUE );  // #C69956
             this_thr->th.th_local.reduce_data = reduce_data;
@@ -1142,7 +1149,10 @@ __kmp_barrier(enum barrier_type bt, int
                                      USE_ITT_BUILD_ARG(itt_sync_obj) );
                 __kmp_task_team_setup(this_thr, team, 0, 0); // use 0,0 to only setup the current team if nthreads > 1
             }
-
+#if USE_DEBUGGER
+            // Let the debugger know: All threads are arrived and starting leaving the barrier.
+            team->t.t_bar[bt].b_team_arrived += 1;
+#endif
 
 #if USE_ITT_BUILD
             /* TODO: In case of split reduction barrier, master thread may send acquired event early,

Added: openmp/trunk/runtime/src/kmp_debugger.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_debugger.c?rev=241832&view=auto
==============================================================================
--- openmp/trunk/runtime/src/kmp_debugger.c (added)
+++ openmp/trunk/runtime/src/kmp_debugger.c Thu Jul  9 13:16:58 2015
@@ -0,0 +1,308 @@
+#if USE_DEBUGGER
+/*
+ * kmp_debugger.c -- debugger support.
+ */
+
+
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.txt for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "kmp.h"
+#include "kmp_lock.h"
+#include "kmp_omp.h"
+#include "kmp_str.h"
+
+/*
+    NOTE: All variable names are known to the debugger, do not change!
+*/
+
+#ifdef __cplusplus
+    extern "C" {
+        extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
+    } // extern "C"
+#endif // __cplusplus
+
+int __kmp_debugging          = FALSE;    // Boolean whether currently debugging OpenMP RTL.
+
+#define offset_and_size_of( structure, field )     \
+    {                                              \
+        offsetof( structure,           field ),    \
+        sizeof( ( (structure *) NULL)->field )     \
+    }
+
+#define offset_and_size_not_available \
+    { -1, -1 }
+
+#define addr_and_size_of( var )                    \
+    {                                              \
+        (kmp_uint64)( & var ),                     \
+        sizeof( var )                              \
+    }
+
+#define nthr_buffer_size 1024
+static kmp_int32
+kmp_omp_nthr_info_buffer[ nthr_buffer_size ] =
+    { nthr_buffer_size * sizeof( kmp_int32 ) };
+
+/* TODO: Check punctuation for various platforms here */
+static char func_microtask[]    = "__kmp_invoke_microtask";
+static char func_fork[]         = "__kmpc_fork_call";
+static char func_fork_teams[]   = "__kmpc_fork_teams";
+
+
+// Various info about runtime structures: addresses, field offsets, sizes, etc.
+kmp_omp_struct_info_t
+__kmp_omp_debug_struct_info = {
+
+    /* Change this only if you make a fundamental data structure change here */
+    KMP_OMP_VERSION,
+
+    /* sanity check.  Only should be checked if versions are identical
+     * This is also used for backward compatibility to get the runtime
+     * structure size if it the runtime is older than the interface */
+    sizeof( kmp_omp_struct_info_t ),
+
+    /* OpenMP RTL version info. */
+    addr_and_size_of( __kmp_version_major ),
+    addr_and_size_of( __kmp_version_minor ),
+    addr_and_size_of( __kmp_version_build ),
+    addr_and_size_of( __kmp_openmp_version ),
+    { (kmp_uint64)( __kmp_copyright ) + KMP_VERSION_MAGIC_LEN, 0 },        // Skip magic prefix.
+
+    /* Various globals. */
+    addr_and_size_of( __kmp_threads ),
+    addr_and_size_of( __kmp_root ),
+    addr_and_size_of( __kmp_threads_capacity ),
+    addr_and_size_of( __kmp_monitor ),
+#if ! KMP_USE_DYNAMIC_LOCK
+    addr_and_size_of( __kmp_user_lock_table ),
+#endif
+    addr_and_size_of( func_microtask ),
+    addr_and_size_of( func_fork ),
+    addr_and_size_of( func_fork_teams ),
+    addr_and_size_of( __kmp_team_counter ),
+    addr_and_size_of( __kmp_task_counter ),
+    addr_and_size_of( kmp_omp_nthr_info_buffer ),
+    sizeof( void * ),
+    OMP_LOCK_T_SIZE < sizeof(void *),
+    bs_last_barrier,
+    TASK_DEQUE_SIZE,
+
+    // thread structure information
+    sizeof( kmp_base_info_t ),
+    offset_and_size_of( kmp_base_info_t, th_info ),
+    offset_and_size_of( kmp_base_info_t, th_team ),
+    offset_and_size_of( kmp_base_info_t, th_root ),
+    offset_and_size_of( kmp_base_info_t, th_serial_team ),
+    offset_and_size_of( kmp_base_info_t, th_ident ),
+    offset_and_size_of( kmp_base_info_t, th_spin_here    ),
+    offset_and_size_of( kmp_base_info_t, th_next_waiting ),
+    offset_and_size_of( kmp_base_info_t, th_task_team    ),
+    offset_and_size_of( kmp_base_info_t, th_current_task ),
+    offset_and_size_of( kmp_base_info_t, th_task_state   ),
+    offset_and_size_of( kmp_base_info_t,   th_bar ),
+    offset_and_size_of( kmp_bstate_t,      b_worker_arrived ),
+
+    // teams information
+    offset_and_size_of( kmp_base_info_t, th_teams_microtask),
+    offset_and_size_of( kmp_base_info_t, th_teams_level),
+    offset_and_size_of( kmp_teams_size_t, nteams ),
+    offset_and_size_of( kmp_teams_size_t, nth ),
+
+    // kmp_desc structure (for info field above)
+    sizeof( kmp_desc_base_t ),
+    offset_and_size_of( kmp_desc_base_t, ds_tid    ),
+    offset_and_size_of( kmp_desc_base_t, ds_gtid   ),
+    // On Windows* OS, ds_thread contains a thread /handle/, which is not usable, while thread /id/
+    // is in ds_thread_id.
+    #if KMP_OS_WINDOWS
+    offset_and_size_of( kmp_desc_base_t, ds_thread_id),
+    #else
+    offset_and_size_of( kmp_desc_base_t, ds_thread),
+    #endif
+
+    // team structure information
+    sizeof( kmp_base_team_t ),
+    offset_and_size_of( kmp_base_team_t,   t_master_tid ),
+    offset_and_size_of( kmp_base_team_t,   t_ident      ),
+    offset_and_size_of( kmp_base_team_t,   t_parent     ),
+    offset_and_size_of( kmp_base_team_t,   t_nproc      ),
+    offset_and_size_of( kmp_base_team_t,   t_threads    ),
+    offset_and_size_of( kmp_base_team_t,   t_serialized ),
+    offset_and_size_of( kmp_base_team_t,   t_id         ),
+    offset_and_size_of( kmp_base_team_t,   t_pkfn       ),
+    offset_and_size_of( kmp_base_team_t,   t_task_team ),
+    offset_and_size_of( kmp_base_team_t,   t_implicit_task_taskdata ),
+    offset_and_size_of( kmp_base_team_t,   t_cancel_request ),
+    offset_and_size_of( kmp_base_team_t,   t_bar ),
+    offset_and_size_of( kmp_balign_team_t, b_master_arrived ),
+    offset_and_size_of( kmp_balign_team_t, b_team_arrived ),
+
+    // root structure information
+    sizeof( kmp_base_root_t ),
+    offset_and_size_of( kmp_base_root_t, r_root_team   ),
+    offset_and_size_of( kmp_base_root_t, r_hot_team    ),
+    offset_and_size_of( kmp_base_root_t, r_uber_thread ),
+    offset_and_size_not_available,
+
+    // ident structure information
+    sizeof( ident_t ),
+    offset_and_size_of( ident_t, psource ),
+    offset_and_size_of( ident_t, flags   ),
+
+    // lock structure information
+    sizeof( kmp_base_queuing_lock_t ),
+    offset_and_size_of( kmp_base_queuing_lock_t, initialized  ),
+    offset_and_size_of( kmp_base_queuing_lock_t, location ),
+    offset_and_size_of( kmp_base_queuing_lock_t, tail_id  ),
+    offset_and_size_of( kmp_base_queuing_lock_t, head_id  ),
+    offset_and_size_of( kmp_base_queuing_lock_t, next_ticket  ),
+    offset_and_size_of( kmp_base_queuing_lock_t, now_serving  ),
+    offset_and_size_of( kmp_base_queuing_lock_t, owner_id     ),
+    offset_and_size_of( kmp_base_queuing_lock_t, depth_locked ),
+    offset_and_size_of( kmp_base_queuing_lock_t, flags ),
+
+#if ! KMP_USE_DYNAMIC_LOCK
+    /* Lock table. */
+    sizeof( kmp_lock_table_t ),
+    offset_and_size_of( kmp_lock_table_t, used       ),
+    offset_and_size_of( kmp_lock_table_t, allocated  ),
+    offset_and_size_of( kmp_lock_table_t, table      ),
+#endif
+
+    // Task team structure information.
+    sizeof( kmp_base_task_team_t ),
+    offset_and_size_of( kmp_base_task_team_t, tt_threads_data       ),
+    offset_and_size_of( kmp_base_task_team_t, tt_found_tasks        ),
+    offset_and_size_of( kmp_base_task_team_t, tt_nproc              ),
+    offset_and_size_of( kmp_base_task_team_t, tt_unfinished_threads ),
+    offset_and_size_of( kmp_base_task_team_t, tt_active             ),
+
+    // task_data_t.
+    sizeof( kmp_taskdata_t ),
+    offset_and_size_of( kmp_taskdata_t, td_task_id                ),
+    offset_and_size_of( kmp_taskdata_t, td_flags                  ),
+    offset_and_size_of( kmp_taskdata_t, td_team                   ),
+    offset_and_size_of( kmp_taskdata_t, td_parent                 ),
+    offset_and_size_of( kmp_taskdata_t, td_level                  ),
+    offset_and_size_of( kmp_taskdata_t, td_ident                  ),
+    offset_and_size_of( kmp_taskdata_t, td_allocated_child_tasks  ),
+    offset_and_size_of( kmp_taskdata_t, td_incomplete_child_tasks ),
+
+    offset_and_size_of( kmp_taskdata_t, td_taskwait_ident   ),
+    offset_and_size_of( kmp_taskdata_t, td_taskwait_counter ),
+    offset_and_size_of( kmp_taskdata_t, td_taskwait_thread  ),
+
+    offset_and_size_of( kmp_taskdata_t, td_taskgroup        ),
+    offset_and_size_of( kmp_taskgroup_t, count              ),
+    offset_and_size_of( kmp_taskgroup_t, cancel_request     ),
+
+    offset_and_size_of( kmp_taskdata_t, td_depnode          ),
+    offset_and_size_of( kmp_depnode_list_t, node            ),
+    offset_and_size_of( kmp_depnode_list_t, next            ),
+    offset_and_size_of( kmp_base_depnode_t, successors      ),
+    offset_and_size_of( kmp_base_depnode_t, task            ),
+    offset_and_size_of( kmp_base_depnode_t, npredecessors   ),
+    offset_and_size_of( kmp_base_depnode_t, nrefs           ),
+    offset_and_size_of( kmp_task_t, routine                 ),
+
+    // thread_data_t.
+    sizeof( kmp_thread_data_t ),
+    offset_and_size_of( kmp_base_thread_data_t, td_deque             ),
+    offset_and_size_of( kmp_base_thread_data_t, td_deque_head        ),
+    offset_and_size_of( kmp_base_thread_data_t, td_deque_tail        ),
+    offset_and_size_of( kmp_base_thread_data_t, td_deque_ntasks      ),
+    offset_and_size_of( kmp_base_thread_data_t, td_deque_last_stolen ),
+
+    // The last field.
+    KMP_OMP_VERSION,
+
+}; // __kmp_omp_debug_struct_info
+
+#undef offset_and_size_of
+#undef addr_and_size_of
+
+/*
+  Intel compiler on IA-32 architecture issues a warning "conversion
+  from "unsigned long long" to "char *" may lose significant bits"
+  when 64-bit value is assigned to 32-bit pointer. Use this function
+  to suppress the warning.
+*/
+static inline
+void *
+__kmp_convert_to_ptr(
+    kmp_uint64    addr
+) {
+    #if KMP_COMPILER_ICC
+        #pragma warning( push )
+        #pragma warning( disable:  810 ) // conversion from "unsigned long long" to "char *" may lose significant bits
+        #pragma warning( disable: 1195 ) // conversion from integer to smaller pointer
+    #endif // KMP_COMPILER_ICC
+    return (void *) addr;
+    #if KMP_COMPILER_ICC
+        #pragma warning( pop )
+    #endif // KMP_COMPILER_ICC
+} // __kmp_convert_to_ptr
+
+
+static int
+kmp_location_match(
+    kmp_str_loc_t *        loc,
+    kmp_omp_nthr_item_t *  item
+) {
+
+    int file_match = 0;
+    int func_match = 0;
+    int line_match = 0;
+
+    char * file = (char *) __kmp_convert_to_ptr( item->file );
+    char * func = (char *) __kmp_convert_to_ptr( item->func );
+    file_match = __kmp_str_fname_match( & loc->fname, file );
+    func_match =
+        item->func == 0  // If item->func is NULL, it allows any func name.
+        ||
+        strcmp( func, "*" ) == 0
+        ||
+        ( loc->func != NULL && strcmp( loc->func, func ) == 0 );
+    line_match =
+        item->begin <= loc->line
+        &&
+        ( item->end <= 0 || loc->line <= item->end ); // if item->end <= 0, it means "end of file".
+
+    return ( file_match && func_match && line_match );
+
+} // kmp_location_match
+
+
+int
+__kmp_omp_num_threads(
+    ident_t const * ident
+) {
+
+    int num_threads = 0;
+
+    kmp_omp_nthr_info_t * info =
+        (kmp_omp_nthr_info_t *) __kmp_convert_to_ptr(  __kmp_omp_debug_struct_info.nthr_info.addr );
+    if ( info->num > 0 && info->array != 0 ) {
+        kmp_omp_nthr_item_t * items = (kmp_omp_nthr_item_t *) __kmp_convert_to_ptr( info->array );
+        kmp_str_loc_t         loc   = __kmp_str_loc_init( ident->psource, 1 );
+        int i;
+        for ( i = 0; i < info->num; ++ i ) {
+            if ( kmp_location_match( & loc, & items[ i ] ) ) {
+                num_threads = items[ i ].num_threads;
+            }; // if
+        }; // for
+        __kmp_str_loc_free( & loc );
+    }; // if
+
+    return num_threads;;
+
+} // __kmp_omp_num_threads
+#endif /* USE_DEBUGGER */

Propchange: openmp/trunk/runtime/src/kmp_debugger.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: openmp/trunk/runtime/src/kmp_debugger.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: openmp/trunk/runtime/src/kmp_debugger.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: openmp/trunk/runtime/src/kmp_debugger.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_debugger.h?rev=241832&view=auto
==============================================================================
--- openmp/trunk/runtime/src/kmp_debugger.h (added)
+++ openmp/trunk/runtime/src/kmp_debugger.h Thu Jul  9 13:16:58 2015
@@ -0,0 +1,51 @@
+#if USE_DEBUGGER
+/*
+ * kmp_debugger.h -- debugger support.
+ */
+
+
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.txt for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef KMP_DEBUGGER_H
+#define KMP_DEBUGGER_H
+
+#ifdef __cplusplus
+    extern "C" {
+#endif // __cplusplus
+
+/* * This external variable can be set by any debugger to flag to the runtime that we
+   are currently executing inside a debugger.  This will allow the debugger to override
+   the number of threads spawned in a parallel region by using __kmp_omp_num_threads() (below). 
+   * When __kmp_debugging is TRUE, each team and each task gets a unique integer identifier 
+   that can be used by debugger to conveniently identify teams and tasks.
+   * The debugger has access to __kmp_omp_debug_struct_info which contains information
+   about the OpenMP library's important internal structures.  This access will allow the debugger 
+   to read detailed information from the typical OpenMP constructs (teams, threads, tasking, etc. )
+   during a debugging session and offer detailed and useful information which the user can probe
+   about the OpenMP portion of their code.
+   */
+extern int __kmp_debugging;             /* Boolean whether currently debugging OpenMP RTL */
+// Return number of threads specified by the debugger for given parallel region.
+/* The ident field, which represents a source file location, is used to check if the 
+   debugger has changed the number of threads for the parallel region at source file 
+   location ident.  This way, specific parallel regions' number of threads can be changed
+   at the debugger's request.
+ */
+int __kmp_omp_num_threads( ident_t const * ident );
+
+#ifdef __cplusplus
+    } // extern "C"
+#endif // __cplusplus
+
+
+#endif // KMP_DEBUGGER_H
+
+#endif // USE_DEBUGGER

Propchange: openmp/trunk/runtime/src/kmp_debugger.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: openmp/trunk/runtime/src/kmp_debugger.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: openmp/trunk/runtime/src/kmp_debugger.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: openmp/trunk/runtime/src/kmp_omp.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_omp.h?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_omp.h (original)
+++ openmp/trunk/runtime/src/kmp_omp.h Thu Jul  9 13:16:58 2015
@@ -1,3 +1,4 @@
+#if USE_DEBUGGER
 /*
  * kmp_omp.h -- OpenMP definition for kmp_omp_struct_info_t.
  *              This is for information about runtime library structures.
@@ -200,12 +201,13 @@ typedef struct {
 
     /* Task dependency */
     offset_and_size_t  td_depnode;                  // pointer to graph node if the task has dependencies
-    offset_and_size_t  dn_successors;
     offset_and_size_t  dn_node;
     offset_and_size_t  dn_next;
+    offset_and_size_t  dn_successors;
     offset_and_size_t  dn_task;
     offset_and_size_t  dn_npredecessors;
     offset_and_size_t  dn_nrefs;
+    offset_and_size_t  dn_routine;
 
     /* kmp_thread_data_t */
     kmp_int32          hd_sizeof_struct;
@@ -220,5 +222,6 @@ typedef struct {
 
 } kmp_omp_struct_info_t;
 
+#endif /* USE_DEBUGGER */
 
 /* end of file */

Modified: openmp/trunk/runtime/src/kmp_runtime.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_runtime.c?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_runtime.c (original)
+++ openmp/trunk/runtime/src/kmp_runtime.c Thu Jul  9 13:16:58 2015
@@ -1136,6 +1136,9 @@ __kmp_fork_team_threads( kmp_root_t *roo
                 for ( b = 0; b < bs_last_barrier; ++ b ) {
                     balign[ b ].bb.b_arrived        = team->t.t_bar[ b ].b_arrived;
                     KMP_DEBUG_ASSERT(balign[b].bb.wait_flag != KMP_BARRIER_PARENT_FLAG);
+#if USE_DEBUGGER
+                    balign[ b ].bb.b_worker_arrived = team->t.t_bar[ b ].b_team_arrived;
+#endif
                 }; // for b
             }
         }
@@ -1360,6 +1363,9 @@ __kmp_serialized_parallel(ident_t *loc,
         }
 #endif /* OMP_40_ENABLED */
 
+#if USE_DEBUGGER
+        serial_team->t.t_pkfn = (microtask_t)( ~0 ); // For the debugger.
+#endif
         this_thr->th.th_info.ds.ds_tid = 0;
 
         /* set thread cache values */
@@ -1671,6 +1677,14 @@ __kmp_fork_call(
             master_th->th.th_set_nproc = 0;
         }
 
+#if USE_DEBUGGER
+    if ( __kmp_debugging ) {    // Let debugger override number of threads.
+        int nth = __kmp_omp_num_threads( loc );
+        if ( nth > 0 ) {        // 0 means debugger does not want to change number of threads.
+            master_set_numthreads = nth;
+        }; // if
+    }; // if
+#endif
 
         KF_TRACE( 10, ( "__kmp_fork_call: before internal fork: root=%p, team=%p, master_th=%p, gtid=%d\n", root, parent_team, master_th, gtid ) );
         __kmp_internal_fork( loc, gtid, parent_team );
@@ -2397,6 +2411,9 @@ __kmp_join_call(ident_t *loc, int gtid
                 for ( b = 0; b < bs_last_barrier; ++ b ) {
                     balign[ b ].bb.b_arrived        = team->t.t_bar[ b ].b_arrived;
                     KMP_DEBUG_ASSERT(balign[ b ].bb.wait_flag != KMP_BARRIER_PARENT_FLAG);
+#if USE_DEBUGGER
+                    balign[ b ].bb.b_worker_arrived = team->t.t_bar[ b ].b_team_arrived;
+#endif
                 }
                 if ( __kmp_tasking_mode != tskm_immediate_exec ) {
                     // Synchronize thread's task state
@@ -3148,6 +3165,10 @@ __kmp_initialize_root( kmp_root_t *root
             0                                                          // argc
             USE_NESTED_HOT_ARG(NULL)                                   // master thread is unknown
         );
+#if USE_DEBUGGER
+    // Non-NULL value should be assigned to make the debugger display the root team.
+    TCW_SYNC_PTR(root_team->t.t_pkfn, (microtask_t)( ~ 0 ));
+#endif
 
     KF_TRACE( 10, ( "__kmp_initialize_root: after root_team = %p\n", root_team ) );
 
@@ -3798,6 +3819,9 @@ __kmp_register_root( int initial_thread
         int b;
         for ( b = 0; b < bs_last_barrier; ++ b ) {
             root_thread->th.th_bar[ b ].bb.b_arrived        = KMP_INIT_BARRIER_STATE;
+#if USE_DEBUGGER
+            root_thread->th.th_bar[ b ].bb.b_worker_arrived = 0;
+#endif
         }; // for
     }
     KMP_DEBUG_ASSERT( root->r.r_hot_team->t.t_bar[ bs_forkjoin_barrier ].b_arrived == KMP_INIT_BARRIER_STATE );
@@ -4968,6 +4992,9 @@ __kmp_allocate_team( kmp_root_t *root, i
                 for ( b = 0; b < bs_last_barrier; ++ b ) {
                     balign[b].bb.b_arrived = team->t.t_bar[b].b_arrived;
                     KMP_DEBUG_ASSERT(balign[b].bb.wait_flag != KMP_BARRIER_PARENT_FLAG);
+#if USE_DEBUGGER
+                    balign[b].bb.b_worker_arrived = team->t.t_bar[b].b_team_arrived;
+#endif
                 }
             }
             if( hot_teams[level].hot_team_nth >= new_nproc ) {
@@ -5014,6 +5041,9 @@ __kmp_allocate_team( kmp_root_t *root, i
                     for( b = 0; b < bs_last_barrier; ++ b ) {
                         balign[ b ].bb.b_arrived        = team->t.t_bar[ b ].b_arrived;
                         KMP_DEBUG_ASSERT(balign[b].bb.wait_flag != KMP_BARRIER_PARENT_FLAG);
+#if USE_DEBUGGER
+                        balign[ b ].bb.b_worker_arrived = team->t.t_bar[ b ].b_team_arrived;
+#endif
                     }
                 }
             }
@@ -5098,6 +5128,9 @@ __kmp_allocate_team( kmp_root_t *root, i
                 for( b = 0; b < bs_last_barrier; ++ b ) {
                     balign[ b ].bb.b_arrived        = team->t.t_bar[ b ].b_arrived;
                     KMP_DEBUG_ASSERT(balign[b].bb.wait_flag != KMP_BARRIER_PARENT_FLAG);
+#if USE_DEBUGGER
+                    balign[ b ].bb.b_worker_arrived = team->t.t_bar[ b ].b_team_arrived;
+#endif
                 }
             }
         }
@@ -5156,6 +5189,10 @@ __kmp_allocate_team( kmp_root_t *root, i
                 int b;
                 for ( b = 0; b < bs_last_barrier; ++ b) {
                     team->t.t_bar[ b ].b_arrived        = KMP_INIT_BARRIER_STATE;
+#if USE_DEBUGGER
+                    team->t.t_bar[ b ].b_master_arrived = 0;
+                    team->t.t_bar[ b ].b_team_arrived   = 0;
+#endif
                 }
             }
 
@@ -5214,6 +5251,10 @@ __kmp_allocate_team( kmp_root_t *root, i
         int b;
         for ( b = 0; b < bs_last_barrier; ++ b ) {
             team->t.t_bar[ b ].b_arrived        = KMP_INIT_BARRIER_STATE;
+#if USE_DEBUGGER
+            team->t.t_bar[ b ].b_master_arrived = 0;
+            team->t.t_bar[ b ].b_team_arrived   = 0;
+#endif
         }
     }
 

Modified: openmp/trunk/runtime/src/makefile.mk
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/makefile.mk?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/src/makefile.mk (original)
+++ openmp/trunk/runtime/src/makefile.mk Thu Jul  9 13:16:58 2015
@@ -709,7 +709,8 @@ else # norm or prof
         kmp_atomic                   \
         kmp_csupport                 \
         kmp_debug                    \
-	kmp_itt                      \
+        kmp_debugger                 \
+        kmp_itt                      \
         $(empty)
     ifeq "$(USE_ITT_NOTIFY)" "1"
         lib_c_items +=  ittnotify_static

Modified: openmp/trunk/runtime/tools/src/common-tools.mk
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/tools/src/common-tools.mk?rev=241832&r1=241831&r2=241832&view=diff
==============================================================================
--- openmp/trunk/runtime/tools/src/common-tools.mk (original)
+++ openmp/trunk/runtime/tools/src/common-tools.mk Thu Jul  9 13:16:58 2015
@@ -41,6 +41,8 @@ endif
 cpp-flags += $(foreach i,$(VPATH),-I $(i))
 
 
+cpp-flags += -D USE_DEBUGGER=1
+
 # Shouldn't this be being set from the command line somehow?
 cpp-flags += -D USE_ITT_BUILD
 





More information about the Openmp-commits mailing list