//===-- MachThread.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/19/07.
//
//===----------------------------------------------------------------------===//

#include <inttypes.h>
#include <mach/thread_policy.h>
#include <dlfcn.h>
#include "MachThread.h"
#include "MachProcess.h"
#include "DNBLog.h"
#include "DNB.h"
#include "ThreadInfo.h"

static uint32_t
GetSequenceID()
{
    static uint32_t g_nextID = 0;
    return ++g_nextID;
}

MachThread::MachThread (MachProcess *process, bool is_64_bit, uint64_t unique_thread_id, thread_t mach_port_num) :
    m_process (process),
    m_unique_id (unique_thread_id),
    m_mach_port_number (mach_port_num),
    m_seq_id (GetSequenceID()),
    m_state (eStateUnloaded),
    m_state_mutex (PTHREAD_MUTEX_RECURSIVE),
    m_suspend_count (0),
    m_stop_exception (),
    m_arch_ap (DNBArchProtocol::Create (this)),
    m_reg_sets (NULL),
    m_num_reg_sets (0), 
    m_ident_info(),
    m_proc_threadinfo(),
    m_dispatch_queue_name(),
    m_is_64_bit(is_64_bit),
    m_pthread_qos_class_decode (nullptr)
{
    nub_size_t num_reg_sets = 0;
    m_reg_sets = m_arch_ap->GetRegisterSetInfo (&num_reg_sets);
    m_num_reg_sets = num_reg_sets;

    m_pthread_qos_class_decode = (unsigned int (*)(unsigned long, int*, unsigned long*)) dlsym (RTLD_DEFAULT, "_pthread_qos_class_decode");

    // Get the thread state so we know if a thread is in a state where we can't
    // muck with it and also so we get the suspend count correct in case it was
    // already suspended
    GetBasicInfo();
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::MachThread ( process = %p, tid = 0x%8.8" PRIx64 ", seq_id = %u )", &m_process, m_unique_id, m_seq_id);
}

MachThread::~MachThread()
{
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::~MachThread() for tid = 0x%8.8" PRIx64 " (%u)", m_unique_id, m_seq_id);
}



void
MachThread::Suspend()
{
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
    if (MachPortNumberIsValid(m_mach_port_number))
    {
        DNBError err(::thread_suspend (m_mach_port_number), DNBError::MachKernel);
        if (err.Success())
            m_suspend_count++;
        if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
            err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
    }
}

void
MachThread::Resume(bool others_stopped)
{
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
    if (MachPortNumberIsValid(m_mach_port_number))
    {
        SetSuspendCountBeforeResume(others_stopped);
    }
}

bool
MachThread::SetSuspendCountBeforeResume(bool others_stopped)
{
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
    DNBError err;
    if (MachPortNumberIsValid(m_mach_port_number) == false)
        return false;
        
    integer_t times_to_resume;
        
    if (others_stopped)
    {
        if (GetBasicInfo())
        {
            times_to_resume = m_basic_info.suspend_count;
            m_suspend_count = - (times_to_resume - m_suspend_count);
        }
        else
            times_to_resume = 0;
    }
    else
    {
        times_to_resume = m_suspend_count;
        m_suspend_count = 0;
    }

    if (times_to_resume > 0)
    {
        while (times_to_resume > 0)
        {
            err = ::thread_resume (m_mach_port_number);
            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
                err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
            if (err.Success())
                --times_to_resume;
            else
            {
                if (GetBasicInfo())
                    times_to_resume = m_basic_info.suspend_count;
                else
                    times_to_resume = 0;
            }
        }
    }
    return true;
}

bool
MachThread::RestoreSuspendCountAfterStop ()
{
    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
    DNBError err;
    if (MachPortNumberIsValid(m_mach_port_number) == false)
        return false;
        
    if (m_suspend_count > 0)
    {
        while (m_suspend_count > 0)
        {
            err = ::thread_resume (m_mach_port_number);
            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
                err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
            if (err.Success())
                --m_suspend_count;
            else
            {
                if (GetBasicInfo())
                    m_suspend_count = m_basic_info.suspend_count;
                else
                    m_suspend_count = 0;
                return false; // ??? 
            }
        }
    }
    else if (m_suspend_count < 0)
    {
        while (m_suspend_count < 0)
        {
            err = ::thread_suspend (m_mach_port_number);
            if (err.Success())
                ++m_suspend_count;
            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
            {
                err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
                return false;
            }
        }
    }
    return true;
}


const char *
MachThread::GetBasicInfoAsString () const
{
    static char g_basic_info_string[1024];
    struct thread_basic_info basicInfo;

    if (GetBasicInfo(m_mach_port_number, &basicInfo))
    {

//        char run_state_str[32];
//        size_t run_state_str_size = sizeof(run_state_str);
//        switch (basicInfo.run_state)
//        {
//        case TH_STATE_RUNNING:          strncpy(run_state_str, "running", run_state_str_size); break;
//        case TH_STATE_STOPPED:          strncpy(run_state_str, "stopped", run_state_str_size); break;
//        case TH_STATE_WAITING:          strncpy(run_state_str, "waiting", run_state_str_size); break;
//        case TH_STATE_UNINTERRUPTIBLE:  strncpy(run_state_str, "uninterruptible", run_state_str_size); break;
//        case TH_STATE_HALTED:           strncpy(run_state_str, "halted", run_state_str_size); break;
//        default:                        snprintf(run_state_str, run_state_str_size, "%d", basicInfo.run_state); break;    // ???
//        }
        float user = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
        float system = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
        snprintf(g_basic_info_string, sizeof(g_basic_info_string), "Thread 0x%8.8" PRIx64 ": user=%f system=%f cpu=%d sleep_time=%d",
            m_unique_id,
            user,
            system,
            basicInfo.cpu_usage,
            basicInfo.sleep_time);

        return g_basic_info_string;
    }
    return NULL;
}

// Finds the Mach port number for a given thread in the inferior process' port namespace.
thread_t
MachThread::InferiorThreadID() const
{
    mach_msg_type_number_t i;
    mach_port_name_array_t names;
    mach_port_type_array_t types;
    mach_msg_type_number_t ncount, tcount;
    thread_t inferior_tid = INVALID_NUB_THREAD;
    task_t my_task = ::mach_task_self();
    task_t task = m_process->Task().TaskPort();

    kern_return_t kret = ::mach_port_names (task, &names, &ncount, &types, &tcount);
    if (kret == KERN_SUCCESS)
    {

        for (i = 0; i < ncount; i++)
        {
            mach_port_t my_name;
            mach_msg_type_name_t my_type;

            kret = ::mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &my_name, &my_type);
            if (kret == KERN_SUCCESS)
            {
                ::mach_port_deallocate (my_task, my_name);
                if (my_name == m_mach_port_number)
                {
                    inferior_tid = names[i];
                    break;
                }
            }
        }
        // Free up the names and types
        ::vm_deallocate (my_task, (vm_address_t) names, ncount * sizeof (mach_port_name_t));
        ::vm_deallocate (my_task, (vm_address_t) types, tcount * sizeof (mach_port_type_t));
    }
    return inferior_tid;
}

bool
MachThread::IsUserReady()
{
    if (m_basic_info.run_state == 0)
        GetBasicInfo ();
    
    switch (m_basic_info.run_state)
    {
    default: 
    case TH_STATE_UNINTERRUPTIBLE:  
        break;

    case TH_STATE_RUNNING:
    case TH_STATE_STOPPED:
    case TH_STATE_WAITING:
    case TH_STATE_HALTED:
        return true;
    }
    return false;
}

struct thread_basic_info *
MachThread::GetBasicInfo ()
{
    if (MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info))
        return &m_basic_info;
    return NULL;
}


bool
MachThread::GetBasicInfo(thread_t thread, struct thread_basic_info *basicInfoPtr)
{
    if (MachPortNumberIsValid(thread))
    {
        unsigned int info_count = THREAD_BASIC_INFO_COUNT;
        kern_return_t err = ::thread_info (thread, THREAD_BASIC_INFO, (thread_info_t) basicInfoPtr, &info_count);
        if (err == KERN_SUCCESS)
            return true;
    }
    ::memset (basicInfoPtr, 0, sizeof (struct thread_basic_info));
    return false;
}


bool
MachThread::ThreadIDIsValid(uint64_t thread)
{
    return thread != 0;
}

bool
MachThread::MachPortNumberIsValid(thread_t thread)
{
    return thread != THREAD_NULL;
}

bool
MachThread::GetRegisterState(int flavor, bool force)
{
    return m_arch_ap->GetRegisterState(flavor, force) == KERN_SUCCESS;
}

bool
MachThread::SetRegisterState(int flavor)
{
    return m_arch_ap->SetRegisterState(flavor) == KERN_SUCCESS;
}

uint64_t
MachThread::GetPC(uint64_t failValue)
{
    // Get program counter
    return m_arch_ap->GetPC(failValue);
}

bool
MachThread::SetPC(uint64_t value)
{
    // Set program counter
    return m_arch_ap->SetPC(value);
}

uint64_t
MachThread::GetSP(uint64_t failValue)
{
    // Get stack pointer
    return m_arch_ap->GetSP(failValue);
}

nub_process_t
MachThread::ProcessID() const
{
    if (m_process)
        return m_process->ProcessID();
    return INVALID_NUB_PROCESS;
}

void
MachThread::Dump(uint32_t index)
{
    const char * thread_run_state = NULL;

    switch (m_basic_info.run_state)
    {
    case TH_STATE_RUNNING:          thread_run_state = "running"; break;    // 1 thread is running normally
    case TH_STATE_STOPPED:          thread_run_state = "stopped"; break;    // 2 thread is stopped
    case TH_STATE_WAITING:          thread_run_state = "waiting"; break;    // 3 thread is waiting normally
    case TH_STATE_UNINTERRUPTIBLE:  thread_run_state = "uninter"; break;    // 4 thread is in an uninterruptible wait
    case TH_STATE_HALTED:           thread_run_state = "halted "; break;     // 5 thread is halted at a
    default:                        thread_run_state = "???"; break;
    }

    DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
        index,
        m_seq_id,
        m_unique_id,
        GetPC(INVALID_NUB_ADDRESS),
        GetSP(INVALID_NUB_ADDRESS),
        m_basic_info.user_time.seconds,      m_basic_info.user_time.microseconds,
        m_basic_info.system_time.seconds,    m_basic_info.system_time.microseconds,
        m_basic_info.cpu_usage,
        m_basic_info.policy,
        m_basic_info.run_state,
        thread_run_state,
        m_basic_info.flags,
        m_basic_info.suspend_count, m_suspend_count,
        m_basic_info.sleep_time);
    //DumpRegisterState(0);
}

void
MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action, bool others_stopped)
{
    if (thread_action->addr != INVALID_NUB_ADDRESS)
        SetPC (thread_action->addr);

    SetState (thread_action->state);
    switch (thread_action->state)
    {
    case eStateStopped:
    case eStateSuspended:
        assert (others_stopped == false);
        Suspend();
        break;

    case eStateRunning:
    case eStateStepping:
        Resume(others_stopped);
        break;
    default: 
        break;
    }
    m_arch_ap->ThreadWillResume();
    m_stop_exception.Clear();
}

DNBBreakpoint *
MachThread::CurrentBreakpoint()
{
    return m_process->Breakpoints().FindByAddress(GetPC());
}

bool
MachThread::ShouldStop(bool &step_more)
{
    // See if this thread is at a breakpoint?
    DNBBreakpoint *bp = CurrentBreakpoint();

    if (bp)
    {
        // This thread is sitting at a breakpoint, ask the breakpoint
        // if we should be stopping here.
        return true;
    }
    else
    {
        if (m_arch_ap->StepNotComplete())
        {
            step_more = true;
            return false;
        }
        // The thread state is used to let us know what the thread was
        // trying to do. MachThread::ThreadWillResume() will set the
        // thread state to various values depending if the thread was
        // the current thread and if it was to be single stepped, or
        // resumed.
        if (GetState() == eStateRunning)
        {
            // If our state is running, then we should continue as we are in
            // the process of stepping over a breakpoint.
            return false;
        }
        else
        {
            // Stop if we have any kind of valid exception for this
            // thread.
            if (GetStopException().IsValid())
                return true;
        }
    }
    return false;
}
bool
MachThread::IsStepping()
{
    return GetState() == eStateStepping;
}


bool
MachThread::ThreadDidStop()
{
    // This thread has existed prior to resuming under debug nub control,
    // and has just been stopped. Do any cleanup that needs to be done
    // after running.

    // The thread state and breakpoint will still have the same values
    // as they had prior to resuming the thread, so it makes it easy to check
    // if we were trying to step a thread, or we tried to resume while being
    // at a breakpoint.

    // When this method gets called, the process state is still in the
    // state it was in while running so we can act accordingly.
    m_arch_ap->ThreadDidStop();


    // We may have suspended this thread so the primary thread could step
    // without worrying about race conditions, so lets restore our suspend
    // count.
    RestoreSuspendCountAfterStop();

    // Update the basic information for a thread
    MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);

    if (m_basic_info.suspend_count > 0)
        SetState(eStateSuspended);
    else
        SetState(eStateStopped);
    return true;
}

bool
MachThread::NotifyException(MachException::Data& exc)
{
    // Allow the arch specific protocol to process (MachException::Data &)exc
    // first before possible reassignment of m_stop_exception with exc.
    // See also MachThread::GetStopException().
    bool handled = m_arch_ap->NotifyException(exc);

    if (m_stop_exception.IsValid())
    {
        // We may have more than one exception for a thread, but we need to
        // only remember the one that we will say is the reason we stopped.
        // We may have been single stepping and also gotten a signal exception,
        // so just remember the most pertinent one.
        if (m_stop_exception.IsBreakpoint())
            m_stop_exception = exc;
    }
    else
    {
        m_stop_exception = exc;
    }

    return handled;
}


nub_state_t
MachThread::GetState()
{
    // If any other threads access this we will need a mutex for it
    PTHREAD_MUTEX_LOCKER (locker, m_state_mutex);
    return m_state;
}

void
MachThread::SetState(nub_state_t state)
{
    PTHREAD_MUTEX_LOCKER (locker, m_state_mutex);
    m_state = state;
    DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "", DNBStateAsString(state), m_unique_id);
}

nub_size_t
MachThread::GetNumRegistersInSet(int regSet) const
{
    if (regSet < m_num_reg_sets)
        return m_reg_sets[regSet].num_registers;
    return 0;
}

const char *
MachThread::GetRegisterSetName(int regSet) const
{
    if (regSet < m_num_reg_sets)
        return m_reg_sets[regSet].name;
    return NULL;
}

const DNBRegisterInfo *
MachThread::GetRegisterInfo(int regSet, int regIndex) const
{
    if (regSet < m_num_reg_sets)
        if (regIndex < m_reg_sets[regSet].num_registers)
            return &m_reg_sets[regSet].registers[regIndex];
    return NULL;
}
void
MachThread::DumpRegisterState(int regSet)
{
    if (regSet == REGISTER_SET_ALL)
    {
        for (regSet = 1; regSet < m_num_reg_sets; regSet++)
            DumpRegisterState(regSet);
    }
    else
    {
        if (m_arch_ap->RegisterSetStateIsValid(regSet))
        {
            const size_t numRegisters = GetNumRegistersInSet(regSet);
            uint32_t regIndex = 0;
            DNBRegisterValueClass reg;
            for (regIndex = 0; regIndex < numRegisters; ++regIndex)
            {
                if (m_arch_ap->GetRegisterValue(regSet, regIndex, &reg))
                {
                    reg.Dump(NULL, NULL);
                }
            }
        }
        else
        {
            DNBLog("%s: registers are not currently valid.", GetRegisterSetName(regSet));
        }
    }
}

const DNBRegisterSetInfo *
MachThread::GetRegisterSetInfo(nub_size_t *num_reg_sets ) const
{
    *num_reg_sets = m_num_reg_sets;
    return &m_reg_sets[0];
}

bool
MachThread::GetRegisterValue ( uint32_t set, uint32_t reg, DNBRegisterValue *value )
{
    return m_arch_ap->GetRegisterValue(set, reg, value);
}

bool
MachThread::SetRegisterValue ( uint32_t set, uint32_t reg, const DNBRegisterValue *value )
{
    return m_arch_ap->SetRegisterValue(set, reg, value);
}

nub_size_t
MachThread::GetRegisterContext (void *buf, nub_size_t buf_len)
{
    return m_arch_ap->GetRegisterContext(buf, buf_len);
}

nub_size_t
MachThread::SetRegisterContext (const void *buf, nub_size_t buf_len)
{
    return m_arch_ap->SetRegisterContext(buf, buf_len);
}

uint32_t
MachThread::SaveRegisterState ()
{
    return m_arch_ap->SaveRegisterState();
    
}
bool
MachThread::RestoreRegisterState (uint32_t save_id)
{
    return m_arch_ap->RestoreRegisterState(save_id);
}

uint32_t
MachThread::EnableHardwareBreakpoint (const DNBBreakpoint *bp)
{
    if (bp != NULL && bp->IsBreakpoint())
        return m_arch_ap->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize());
    return INVALID_NUB_HW_INDEX;
}

uint32_t
MachThread::EnableHardwareWatchpoint (const DNBBreakpoint *wp, bool also_set_on_task)
{
    if (wp != NULL && wp->IsWatchpoint())
        return m_arch_ap->EnableHardwareWatchpoint(wp->Address(), wp->ByteSize(), wp->WatchpointRead(), wp->WatchpointWrite(), also_set_on_task);
    return INVALID_NUB_HW_INDEX;
}

bool
MachThread::RollbackTransForHWP()
{
    return m_arch_ap->RollbackTransForHWP();
}

bool
MachThread::FinishTransForHWP()
{
    return m_arch_ap->FinishTransForHWP();
}

bool
MachThread::DisableHardwareBreakpoint (const DNBBreakpoint *bp)
{
    if (bp != NULL && bp->IsHardware())
        return m_arch_ap->DisableHardwareBreakpoint(bp->GetHardwareIndex());
    return false;
}

bool
MachThread::DisableHardwareWatchpoint (const DNBBreakpoint *wp, bool also_set_on_task)
{
    if (wp != NULL && wp->IsHardware())
        return m_arch_ap->DisableHardwareWatchpoint(wp->GetHardwareIndex(), also_set_on_task);
    return false;
}

uint32_t
MachThread::NumSupportedHardwareWatchpoints () const
{
    return m_arch_ap->NumSupportedHardwareWatchpoints();
}

bool
MachThread::GetIdentifierInfo ()
{
        // Don't try to get the thread info once and cache it for the life of the thread.  It changes over time, for instance
        // if the thread name changes, then the thread_handle also changes...  So you have to refetch it every time.
        mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
        kern_return_t kret = ::thread_info (m_mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
        return kret == KERN_SUCCESS;

    return false;
}


const char *
MachThread::GetName ()
{
    if (GetIdentifierInfo ())
    {
        int len = ::proc_pidinfo (m_process->ProcessID(), PROC_PIDTHREADINFO, m_ident_info.thread_handle, &m_proc_threadinfo, sizeof (m_proc_threadinfo));

        if (len && m_proc_threadinfo.pth_name[0])
            return m_proc_threadinfo.pth_name;
    }
    return NULL;
}


uint64_t 
MachThread::GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id)
{
    kern_return_t kr;
    thread_identifier_info_data_t tident;
    mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
    kr = thread_info (mach_port_id, THREAD_IDENTIFIER_INFO,
                      (thread_info_t) &tident, &tident_count);
    if (kr != KERN_SUCCESS)
    {
        return mach_port_id;
    }
    return tident.thread_id;
}

nub_addr_t
MachThread::GetPThreadT ()
{
    nub_addr_t pthread_t_value = INVALID_NUB_ADDRESS;
    if (MachPortNumberIsValid (m_mach_port_number))
    {
        kern_return_t kr;
        thread_identifier_info_data_t tident;
        mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
        kr = thread_info (m_mach_port_number, THREAD_IDENTIFIER_INFO,
                        (thread_info_t) &tident, &tident_count);
        if (kr == KERN_SUCCESS)
        {
            // Dereference thread_handle to get the pthread_t value for this thread.
            if (m_is_64_bit)
            {
                uint64_t addr;
                if (m_process->ReadMemory (tident.thread_handle, 8, &addr) == 8)
                {
                    if (addr != 0)
                    {
                        pthread_t_value = addr;
                    }
                }
            }
            else
            {
                uint32_t addr;
                if (m_process->ReadMemory (tident.thread_handle, 4, &addr) == 4)
                {
                    if (addr != 0)
                    {
                        pthread_t_value = addr;
                    }
                }
            }
        }
    }
    return pthread_t_value;
}

// Return this thread's TSD (Thread Specific Data) address.
// This is computed based on this thread's pthread_t value.
//
// We compute the TSD from the pthread_t by one of two methods.
// 
// If plo_pthread_tsd_base_offset is non-zero, this is a simple offset that we add to
// the pthread_t to get the TSD base address.
//
// Else we read a pointer from memory at pthread_t + plo_pthread_tsd_base_address_offset and
// that gives us the TSD address.
//
// These plo_pthread_tsd_base values must be read out of libpthread by lldb & provided to debugserver.

nub_addr_t
MachThread::GetTSDAddressForThread (uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
{
    nub_addr_t tsd_addr = INVALID_NUB_ADDRESS;
    nub_addr_t pthread_t_value = GetPThreadT();
    if (plo_pthread_tsd_base_offset != 0 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS)
    {
        tsd_addr = pthread_t_value + plo_pthread_tsd_base_offset;
    }
    else
    {
        if (plo_pthread_tsd_entry_size == 4)
        {
            uint32_t addr = 0;
            if (m_process->ReadMemory (pthread_t_value + plo_pthread_tsd_base_address_offset, 4, &addr) == 4)
            {
                if (addr != 0)
                {
                    tsd_addr = addr;
                }
            }
        }
        if (plo_pthread_tsd_entry_size == 4)
        {
            uint64_t addr = 0;
            if (m_process->ReadMemory (pthread_t_value + plo_pthread_tsd_base_address_offset, 8, &addr) == 8)
            {
                if (addr != 0)
                {
                    tsd_addr = addr;
                }
            }
        }
    }
    return tsd_addr;
}


nub_addr_t
MachThread::GetDispatchQueueT ()
{
    nub_addr_t dispatch_queue_t_value = INVALID_NUB_ADDRESS;
    if (MachPortNumberIsValid (m_mach_port_number))
    {
        kern_return_t kr;
        thread_identifier_info_data_t tident;
        mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
        kr = thread_info (m_mach_port_number, THREAD_IDENTIFIER_INFO,
                        (thread_info_t) &tident, &tident_count);
        if (kr == KERN_SUCCESS && tident.dispatch_qaddr != 0 && tident.dispatch_qaddr != INVALID_NUB_ADDRESS)
        {
            // Dereference dispatch_qaddr to get the dispatch_queue_t value for this thread's queue, if any.
            if (m_is_64_bit)
            {
                uint64_t addr;
                if (m_process->ReadMemory (tident.dispatch_qaddr, 8, &addr) == 8)
                {
                    if (addr != 0)
                        dispatch_queue_t_value = addr;
                }
            }
            else
            {
                uint32_t addr;
                if (m_process->ReadMemory (tident.dispatch_qaddr, 4, &addr) == 4)
                {
                    if (addr != 0)
                        dispatch_queue_t_value = addr;
                }
            }
        }
    }
    return dispatch_queue_t_value;
}


ThreadInfo::QoS
MachThread::GetRequestedQoS (nub_addr_t tsd, uint64_t dti_qos_class_index)
{
    ThreadInfo::QoS qos_value;
    if (MachPortNumberIsValid (m_mach_port_number) && m_pthread_qos_class_decode != nullptr)
    {
        uint64_t pthread_priority_value = 0;
        if (m_is_64_bit)
        {
            uint64_t pri;
            if (m_process->ReadMemory (tsd + (dti_qos_class_index * 8), 8, &pri) == 8)
            {
                pthread_priority_value = pri;
            }
        }
        else
        {
            uint32_t pri;
            if (m_process->ReadMemory (tsd + (dti_qos_class_index * 4), 4, &pri) == 4)
            {
                pthread_priority_value = pri;
            }
        }

        uint32_t requested_qos = m_pthread_qos_class_decode (pthread_priority_value, NULL, NULL);

        switch (requested_qos)
        {
            // These constants from <pthread/qos.h>
            case 0x21:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_USER_INTERACTIVE";
                qos_value.printable_name = "User Interactive";
                break;
            case 0x19:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_USER_INITIATED";
                qos_value.printable_name = "User Initiated";
                break;
            case 0x15:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_DEFAULT";
                qos_value.printable_name = "Default";
                break;
            case 0x11:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_UTILITY";
                qos_value.printable_name = "Utility";
                break;
            case 0x09:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_BACKGROUND";
                qos_value.printable_name = "Background";
                break;
            case 0x00:
                qos_value.enum_value = requested_qos;
                qos_value.constant_name = "QOS_CLASS_UNSPECIFIED";
                qos_value.printable_name = "Unspecified";
                break;
        }
    }
    return qos_value;
}
