1008dd426SIngo Weinhold/*
2fce4895dSRene Gollent * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
3008dd426SIngo Weinhold * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4008dd426SIngo Weinhold * Distributed under the terms of the MIT License.
5008dd426SIngo Weinhold */
6008dd426SIngo Weinhold
7fce4895dSRene Gollent#include "model/Thread.h"
8008dd426SIngo Weinhold
91851e9f3SIngo Weinhold#include <stdio.h>
101851e9f3SIngo Weinhold
11a81bb42aSIngo Weinhold#include "CpuState.h"
12a81bb42aSIngo Weinhold#include "StackTrace.h"
13b6aff5aaSIngo Weinhold#include "Team.h"
14a81bb42aSIngo Weinhold
15008dd426SIngo Weinhold
16ae53f490SIngo WeinholdThread::Thread(Team* team, thread_id threadID)
17008dd426SIngo Weinhold	:
18ae53f490SIngo Weinhold	fTeam(team),
19ae53f490SIngo Weinhold	fID(threadID),
20a81bb42aSIngo Weinhold	fState(THREAD_STATE_UNKNOWN),
2176ed6d72SRene Gollent	fReturnValueInfos(NULL),
22cc6b4a3cSRene Gollent	fStopRequestPending(false),
231851e9f3SIngo Weinhold	fStoppedReason(THREAD_STOPPED_UNKNOWN),
24a81bb42aSIngo Weinhold	fCpuState(NULL),
25a81bb42aSIngo Weinhold	fStackTrace(NULL)
26008dd426SIngo Weinhold{
27008dd426SIngo Weinhold}
28008dd426SIngo Weinhold
29008dd426SIngo Weinhold
30008dd426SIngo WeinholdThread::~Thread()
31008dd426SIngo Weinhold{
32a81bb42aSIngo Weinhold	if (fCpuState != NULL)
33c3e066cfSIngo Weinhold		fCpuState->ReleaseReference();
34a81bb42aSIngo Weinhold	if (fStackTrace != NULL)
35c3e066cfSIngo Weinhold		fStackTrace->ReleaseReference();
3676ed6d72SRene Gollent
3776ed6d72SRene Gollent	ClearReturnValueInfos();
3876ed6d72SRene Gollent	delete fReturnValueInfos;
39008dd426SIngo Weinhold}
40008dd426SIngo Weinhold
41008dd426SIngo Weinhold
42008dd426SIngo Weinholdstatus_t
43008dd426SIngo WeinholdThread::Init()
44008dd426SIngo Weinhold{
4576ed6d72SRene Gollent	fReturnValueInfos = new(std::nothrow) ReturnValueInfoList;
4676ed6d72SRene Gollent	if (fReturnValueInfos == NULL)
4776ed6d72SRene Gollent		return B_NO_MEMORY;
4876ed6d72SRene Gollent
49008dd426SIngo Weinhold	return B_OK;
50008dd426SIngo Weinhold}
51008dd426SIngo Weinhold
52008dd426SIngo Weinhold
53d9b10deaSIngo Weinholdbool
54d9b10deaSIngo WeinholdThread::IsMainThread() const
55d9b10deaSIngo Weinhold{
56d9b10deaSIngo Weinhold	return fID == fTeam->ID();
57d9b10deaSIngo Weinhold}
58d9b10deaSIngo Weinhold
59d9b10deaSIngo Weinhold
60008dd426SIngo Weinholdvoid
61008dd426SIngo WeinholdThread::SetName(const BString& name)
62008dd426SIngo Weinhold{
63008dd426SIngo Weinhold	fName = name;
64008dd426SIngo Weinhold}
65ae53f490SIngo Weinhold
66ae53f490SIngo Weinhold
67ae53f490SIngo Weinholdvoid
681851e9f3SIngo WeinholdThread::SetState(uint32 state, uint32 reason, const BString& info)
69ae53f490SIngo Weinhold{
70f1ea2af3SRene Gollent	if (state == fState && reason == fStoppedReason)
71a81bb42aSIngo Weinhold		return;
72a81bb42aSIngo Weinhold
73ae53f490SIngo Weinhold	fState = state;
741851e9f3SIngo Weinhold	fStoppedReason = reason;
751851e9f3SIngo Weinhold	fStoppedReasonInfo = info;
76a81bb42aSIngo Weinhold
77a81bb42aSIngo Weinhold	// unset CPU state and stack trace, if the thread isn't stopped
78a81bb42aSIngo Weinhold	if (fState != THREAD_STATE_STOPPED) {
79a81bb42aSIngo Weinhold		SetCpuState(NULL);
80a81bb42aSIngo Weinhold		SetStackTrace(NULL);
8176ed6d72SRene Gollent		ClearReturnValueInfos();
82cc6b4a3cSRene Gollent		fStopRequestPending = false;
83a81bb42aSIngo Weinhold	}
84b6aff5aaSIngo Weinhold
85b6aff5aaSIngo Weinhold	fTeam->NotifyThreadStateChanged(this);
86a81bb42aSIngo Weinhold}
87a81bb42aSIngo Weinhold
88a81bb42aSIngo Weinhold
89a81bb42aSIngo Weinholdvoid
90a81bb42aSIngo WeinholdThread::SetCpuState(CpuState* state)
91a81bb42aSIngo Weinhold{
92a81bb42aSIngo Weinhold	if (state == fCpuState)
93a81bb42aSIngo Weinhold		return;
94a81bb42aSIngo Weinhold
95a81bb42aSIngo Weinhold	if (fCpuState != NULL)
96c3e066cfSIngo Weinhold		fCpuState->ReleaseReference();
97a81bb42aSIngo Weinhold
98a81bb42aSIngo Weinhold	fCpuState = state;
99a81bb42aSIngo Weinhold
100a81bb42aSIngo Weinhold	if (fCpuState != NULL)
101c3e066cfSIngo Weinhold		fCpuState->AcquireReference();
102b6aff5aaSIngo Weinhold
103b6aff5aaSIngo Weinhold	fTeam->NotifyThreadCpuStateChanged(this);
104a81bb42aSIngo Weinhold}
105a81bb42aSIngo Weinhold
106b6aff5aaSIngo Weinhold
107a81bb42aSIngo Weinholdvoid
108a81bb42aSIngo WeinholdThread::SetStackTrace(StackTrace* trace)
109a81bb42aSIngo Weinhold{
110a81bb42aSIngo Weinhold	if (trace == fStackTrace)
111a81bb42aSIngo Weinhold		return;
112a81bb42aSIngo Weinhold
113a81bb42aSIngo Weinhold	if (fStackTrace != NULL)
114c3e066cfSIngo Weinhold		fStackTrace->ReleaseReference();
115a81bb42aSIngo Weinhold
116a81bb42aSIngo Weinhold	fStackTrace = trace;
117a81bb42aSIngo Weinhold
118a81bb42aSIngo Weinhold	if (fStackTrace != NULL)
119c3e066cfSIngo Weinhold		fStackTrace->AcquireReference();
120b6aff5aaSIngo Weinhold
121b6aff5aaSIngo Weinhold	fTeam->NotifyThreadStackTraceChanged(this);
122ae53f490SIngo Weinhold}
123cf2e209bSRene Gollent
124cc6b4a3cSRene Gollentvoid
125cc6b4a3cSRene GollentThread::SetStopRequestPending()
126cc6b4a3cSRene Gollent{
127cc6b4a3cSRene Gollent	fStopRequestPending = true;
128cc6b4a3cSRene Gollent}
129cc6b4a3cSRene Gollent
130cf2e209bSRene Gollent
13176ed6d72SRene Gollentstatus_t
13276ed6d72SRene GollentThread::AddReturnValueInfo(ReturnValueInfo* info)
133cf2e209bSRene Gollent{
13476ed6d72SRene Gollent	if (!fReturnValueInfos->AddItem(info))
13576ed6d72SRene Gollent		return B_NO_MEMORY;
13676ed6d72SRene Gollent
13776ed6d72SRene Gollent	info->AcquireReference();
13876ed6d72SRene Gollent	return B_OK;
139cf2e209bSRene Gollent}
140cf2e209bSRene Gollent
141029fcc4aSRene Gollent
142029fcc4aSRene Gollentvoid
14376ed6d72SRene GollentThread::ClearReturnValueInfos()
144029fcc4aSRene Gollent{
14576ed6d72SRene Gollent	for (int32 i = 0; i < fReturnValueInfos->CountItems(); i++)
14676ed6d72SRene Gollent		fReturnValueInfos->ItemAt(i)->ReleaseReference();
147029fcc4aSRene Gollent
14876ed6d72SRene Gollent	fReturnValueInfos->MakeEmpty();
149029fcc4aSRene Gollent}
150