###
# GDB macros for analyzing RTEMS threads

####################
# bt_task
#
# ABSTRACT
#    Print backtrace of an RTEMS task
#
# ARGUMENTS:
#    arg0 = pointer to the Thread_Control of the task.
#
define bt_task
    set $stkp = $arg0->Registers.gpr1
	set $stkp = *(void**)$stkp
	while $stkp != 0
	    info line **((void**)$stkp+1)
		set $stkp = *(void**)$stkp
	end
end

####################
# dump1task
#
# ABSTRACT
#    Print information about an RTEMS task
# 
# ARGUMENTS
#    arg0 = Task index in the corresponding _Information table.
#    arg1 = pointer to the Thread_Control of the task.
#    arg2 = 1 for verbose output, 0 otherwise
#
define dump1task
	set $d1t_num = $arg0
	set $pt = $arg1
	set $d1t_verbose = $arg2

	printf "%2d | ", $d1t_num
    set $id = $pt->Object.id
	set $name = (unsigned int)$pt->Object.name
	set $n0 = (char) ($name >> 24)
	if $n0 < ' ' || $n0 > 'z'
	    set $n0=' '
	end
	printf "%c",$n0
	set $n1 = (char) (0xff & ($name >> 16))
	if $n1 < ' ' || $n1 > 'z'
	    set $n1=' '
	end
	printf "%c",$n1
	set $n2 = (char) (0xff & ($name >> 8))
	if $n2 < ' ' || $n2 > 'z'
	    set $n2=' '
	end
	printf "%c",$n2
	set $n3 = (char) (0xff & $name)
	if $n3 < ' ' || $n3 > 'z'
	    set $n3=' '
	end
	printf "%c | ",$n3
	printf "%08x | ",$id

	set $state = $pt->current_state
	set $pri = $pt->current_priority
	printf "%3d | ",$pri
	set $ticks = $pt->ticks_executed
	printf "%8d | ", $ticks
	set $thread_pc = $pt->Registers.pc

	printf ""
	if $state == 0
		printf "READY"
	end
	if $state & 1
		printf "DORM "
	end
	if $state & 2
		printf "SUSP "
	end
	if $state & 4
		printf "TRANS "
	end
	if $state & 8
		printf "DELAY "
	end
	if $state & 0x10
		printf "Wtime "
	end
	if $state & 0x20
		printf "Wbuf "
	end
	if $state & 0x40
		printf "Wseg "
	end
	if $state & 0x80
		printf "Wmsg "
	end
	if $state & 0x100
		printf "Wevnt "
	end
	if $state & 0x200
		printf "Wsem "
	end
	if $state & 0x400
		printf "Wmutex "
	end
	if $state & 0x800
		printf "Wcvar "
	end
	if $state & 0x1000
		printf "Wjatx "
	end
	if $state & 0x2000
		printf "Wrpc "
	end
	if $state & 0x4000
		printf "Wrate "
	end
	if $state & 0x8000
		printf "Wsig "
	end
	if $state & 0x10000
		printf "Wisig "
	end
	
    printf "\n\
---+------+----------+-----+----------+------------------------------\n"
	if $d1t_verbose
	   printf "\
BACKTRACE\n\
~~~~~~~~~\n"
	   bt_task $pt
	end
end

####################
# task_header
#
# ABSTRACT
#    Print the header of the task list table
#
define task_header
    printf "\
=====================================================================\n"
  printf "\
 # | Name |    ID    | Pri |  Ticks   | State\n"
    printf "\
---+------+----------+-----+----------+------------------------------\n"
end

####################
# show_task_support
#
# ABSTRACT
#    Support routine for verbose listing of a single task
# 
# ARGUMENTS
#    arg0 = _Information table.
#    arg1 = index.
#
define show_task_support
	task_header
    set $pt = (Thread_Control *)$arg0.local_table[$arg1]
    dump1task $arg1 $pt 1
end

####################
# dump_tasks_support
#
# ABSTRACT
#    Support routine for verbose listing of all tasks of a given class
# 
# ARGUMENTS
#    arg0 = _Information table for the class (internal, classic, POSIX etc.).
#
define dump_tasks_support
  task_header
  set $index = 1
  while $index <= $arg0.maximum
    set $pt = (Thread_Control *)$arg0.local_table[$index]
    if $pt != 0
		dump1task $index $pt 0
    end
    set $index = $index + 1
  end
end


####################
# dump_internal_tasks
#
# ABSTRACT
#    Dump all internal tasks
# 
define dump_internal_tasks
  dump_tasks_support  _Thread_Internal_information
end

####################
# dump_tasks
#
# ABSTRACT
#    Dump all Classic tasks
# 
define dump_tasks
  dump_tasks_support  _RTEMS_tasks_Information
end

####################
# dump_pthreads
#
# ABSTRACT
#    Dump all POSIX threads
# 
define dump_pthread
  dump_tasks_support  _POSIX_Threads_Information
end

####################
# dump_all_tasks
#
# ABSTRACT
#    Dump all tasks of all classes (internal, POSIX and Classic)
# 
define dump_all_tasks
  printf "Executing: 0x%x, Heir: 0x%x\n", _Thread_Executing->Object.id,\
    _Thread_Heir.Object.id
  printf "===============================================================================\n"
  printf "Internal Tasks\n"
  dump_tasks_support  _Thread_Internal_information
  printf "===============================================================================\n"
  printf "Classic Tasks\n"
  dump_tasks_support  _RTEMS_tasks_Information
  printf "===============================================================================\n"
  printf "POSIX Tasks\n"
  dump_tasks_support  _POSIX_Threads_Information
end

####################
# show_internal_task
#
# ABSTRACT
#    Verbosely list a single internal task
# 
# ARGUMENTS
#    arg0 = index in the _Information table
#
define show_internal_task
  show_task_support  _Thread_Internal_information $arg0
end

####################
# show_task
#
# ABSTRACT
#    Verbosely list a single classic task
# 
# ARGUMENTS
#    arg0 = index in the _Information table
#
define show_task
  show_task_support  _RTEMS_tasks_Information $arg0
end

####################
# show_task
#
# ABSTRACT
#    Verbosely list a single POSIX thread
# 
# ARGUMENTS
#    arg0 = index in the _Information table
#
define show_pthread
  show_task_support  _POSIX_Threads_Information $arg0
end



