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
|
import ompdModule
import imp
class ompd_parallel(object):
def __init__(self, parallel_handle):
""" Initializes an ompd_parallel object with the pointer
to a handle of a parallel region."""
self.parallel_handle = parallel_handle
self.threads = {}
self.itasks = {}
self.enclosing_parallel_handle = None
self.enclosing_parallel = False
self.task_handle = None
def get_thread_in_parallel(self, thread_num):
"""Obtains thread handles for the threads associated with the
parallel region specified by parallel_handle."""
if not thread_num in self.threads:
thread_handle = ompdModule.call_ompd_get_thread_in_parallel(self.parallel_handle, thread_num)
self.threads[thread_num] = ompd_thread(thread_handle)
return self.threads[thread_num]
def get_enclosing_parallel_handle(self):
"""Obtains a parallel handle for the parallel region enclosing
the parallel region specified by parallel_handle."""
if not self.enclosing_parallel_handle:
self.enclosing_parallel_handle = ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle)
return self.enclosing_parallel_handle
def get_enclosing_parallel(self):
if not self.enclosing_parallel:
self.enclosing_parallel = ompd_parallel(self.get_enclosing_parallel_handle())
return self.enclosing_parallel
def get_task_in_parallel(self, thread_num):
"""Obtains handles for the implicit tasks associated with the
parallel region specified by parallel_handle."""
if not thread_num in self.itasks:
task_handle = ompdModule.call_ompd_get_task_in_parallel(self.parallel_handle, thread_num)
self.itasks[thread_num] = ompd_task(task_handle)
return self.itasks[thread_num]
def __del__(self):
"""Releases the parallel handle."""
pass # let capsule destructors do the job
class ompd_task(object):
def __init__(self, task_handle):
"""Initializes a new ompd_task_handle object and sets the attribute
to the task handle specified."""
self.task_handle = task_handle
self.task_parallel_handle = False
self.generating_task_handle = False
self.scheduling_task_handle = False
self.task_parallel = False
self.generating_task = False
self.scheduling_task = False
self.task_frames = None
self.task_frame_flags = None
def get_task_parallel_handle(self):
"""Obtains a task parallel handle for the parallel region enclosing
the task region specified."""
if not self.task_parallel_handle:
self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle(self.task_handle)
return self.task_parallel_handle
def get_task_parallel(self):
if not self.task_parallel:
self.task_parallel = ompd_parallel(self.get_task_parallel_handle())
return self.task_parallel
def get_generating_task_handle(self):
"""Obtains the task handle for the task that created the task specified
by the task handle."""
if not self.generating_task_handle:
self.generating_task_handle = ompdModule.call_ompd_get_generating_task_handle(self.task_handle)
return self.generating_task_handle
def get_generating_task(self):
if not self.generating_task:
self.generating_task = ompd_task(ompdModule.call_ompd_get_generating_task_handle(self.task_handle))
return self.generating_task
def get_scheduling_task_handle(self):
"""Obtains the task handle for the task that scheduled the task specified."""
if not self.scheduling_task_handle:
self.scheduling_task_handle = ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle)
return self.scheduling_task_handle
def get_scheduling_task(self):
"""Returns ompd_task object for the task that scheduled the current task."""
if not self.scheduling_task:
self.scheduling_task = ompd_task(self.get_scheduling_task_handle())
return self.scheduling_task
def get_task_function(self):
"""Returns long with address of function entry point."""
return ompdModule.call_ompd_get_task_function(self.task_handle)
def get_task_frame_with_flags(self):
"""Returns enter frame address and flag, exit frame address and flag for current task handle."""
if self.task_frames is None or self.task_frame_flags is None:
ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
if isinstance(ret_value, tuple):
self.task_frames = (ret_value[0], ret_value[2])
self.task_frame_flags = (ret_value[1], ret_value[3])
else:
return ret_value
return (self.task_frames[0], self.task_frame_flags[0], self.task_frames[1], self.task_frame_flags[1])
def get_task_frame(self):
"""Returns enter and exit frame address for current task handle."""
if self.task_frames is None:
ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
if isinstance(ret_value, tuple):
self.task_frames = (ret_value[0], ret_value[2])
else:
return ret_value
return self.task_frames
def __del__(self):
"""Releases the task handle."""
pass # let capsule destructors do the job
class ompd_thread(object):
def __init__(self, thread_handle):
"""Initializes an ompd_thread with the data received from
GDB."""
self.thread_handle = thread_handle
self.parallel_handle = None
self.task_handle = None
self.current_task = False
self.current_parallel = False
self.thread_id = False
def get_current_parallel_handle(self):
"""Obtains the parallel handle for the parallel region associated with
the given thread handle."""
#TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state.
self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(self.thread_handle)
return self.parallel_handle
def get_current_parallel(self):
"""Returns parallel object for parallel handle of the parallel region
associated with the current thread handle."""
if not self.current_parallel:
self.current_parallel = ompd_parallel(self.get_current_parallel_handle())
return self.current_parallel
def get_current_task_handle(self):
"""Obtains the task handle for the current task region of the
given thread."""
return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle)
def get_thread_id(self):
"""Obtains the ID for the given thread."""
if not self.thread_id:
self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle)
return self.thread_id
def get_current_task(self):
"""Returns task object for task handle of the current task region."""
return ompd_task(self.get_current_task_handle())
def get_state(self):
"""Returns tuple with OMPD state (long) and wait_id, in case the thread is in a
waiting state. Helper function for 'ompd threads' command."""
(state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle)
return (state, wait_id)
def __del__(self):
"""Releases the given thread handle."""
pass # let capsule destructors do the job
|