2014-05-10 03:11:18 +01:00
|
|
|
// Copyright 2014 Citra Emulator Project / PPSSPP Project
|
2014-12-17 05:38:14 +00:00
|
|
|
// Licensed under GPLv2 or any later version
|
2014-11-19 08:49:13 +00:00
|
|
|
// Refer to the license.txt file included.
|
2014-05-10 03:11:18 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2019-03-23 21:09:02 +00:00
|
|
|
#include <memory>
|
2014-12-22 06:32:03 +00:00
|
|
|
#include <string>
|
2016-12-04 03:38:14 +00:00
|
|
|
#include <unordered_map>
|
2014-12-22 06:32:03 +00:00
|
|
|
#include <vector>
|
2015-01-31 21:22:40 +00:00
|
|
|
#include <boost/container/flat_set.hpp>
|
2019-12-27 21:07:29 +00:00
|
|
|
#include <boost/serialization/export.hpp>
|
2019-08-12 17:01:33 +01:00
|
|
|
#include <boost/serialization/shared_ptr.hpp>
|
|
|
|
#include <boost/serialization/unordered_map.hpp>
|
|
|
|
#include <boost/serialization/vector.hpp>
|
2014-05-10 03:11:18 +01:00
|
|
|
#include "common/common_types.h"
|
2018-10-23 16:40:57 +01:00
|
|
|
#include "common/thread_queue_list.h"
|
2016-12-22 05:08:09 +00:00
|
|
|
#include "core/arm/arm_interface.h"
|
2018-10-23 16:57:59 +01:00
|
|
|
#include "core/core_timing.h"
|
2018-08-02 03:40:00 +01:00
|
|
|
#include "core/hle/kernel/object.h"
|
2017-05-29 23:45:30 +01:00
|
|
|
#include "core/hle/kernel/wait_object.h"
|
2014-10-23 04:20:01 +01:00
|
|
|
#include "core/hle/result.h"
|
2014-05-10 03:11:18 +01:00
|
|
|
|
2018-09-13 20:57:45 +01:00
|
|
|
namespace Kernel {
|
|
|
|
|
|
|
|
class Mutex;
|
|
|
|
class Process;
|
|
|
|
|
2017-09-27 00:26:09 +01:00
|
|
|
enum ThreadPriority : u32 {
|
2018-09-21 15:39:10 +01:00
|
|
|
ThreadPrioHighest = 0, ///< Highest thread priority
|
|
|
|
ThreadPrioUserlandMax = 24, ///< Highest thread priority for userland apps
|
|
|
|
ThreadPrioDefault = 48, ///< Default thread priority for userland apps
|
|
|
|
ThreadPrioLowest = 63, ///< Lowest thread priority
|
2014-05-17 05:56:00 +01:00
|
|
|
};
|
|
|
|
|
2015-03-24 03:55:21 +00:00
|
|
|
enum ThreadProcessorId : s32 {
|
2018-09-21 15:39:10 +01:00
|
|
|
ThreadProcessorIdDefault = -2, ///< Run thread on default core specified by exheader
|
|
|
|
ThreadProcessorIdAll = -1, ///< Run thread on either core
|
|
|
|
ThreadProcessorId0 = 0, ///< Run thread on core 0 (AppCore)
|
|
|
|
ThreadProcessorId1 = 1, ///< Run thread on core 1 (SysCore)
|
|
|
|
ThreadProcessorIdMax = 2, ///< Processor ID must be less than this
|
2014-05-17 05:56:00 +01:00
|
|
|
};
|
|
|
|
|
2018-09-21 15:39:10 +01:00
|
|
|
enum class ThreadStatus {
|
2018-07-20 02:39:05 +01:00
|
|
|
Running, ///< Currently running
|
|
|
|
Ready, ///< Ready to run
|
|
|
|
WaitArb, ///< Waiting on an address arbiter
|
|
|
|
WaitSleep, ///< Waiting due to a SleepThread SVC
|
|
|
|
WaitIPC, ///< Waiting for the reply from an IPC request
|
|
|
|
WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
|
|
|
|
WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true
|
|
|
|
WaitHleEvent, ///< Waiting due to an HLE handler pausing the thread
|
|
|
|
Dormant, ///< Created but not yet made ready
|
|
|
|
Dead ///< Run to completion, or forcefully terminated
|
2014-05-22 23:50:36 +01:00
|
|
|
};
|
|
|
|
|
2017-09-28 17:53:32 +01:00
|
|
|
enum class ThreadWakeupReason {
|
|
|
|
Signal, // The thread was woken up by WakeupAllWaitingThreads due to an object signal.
|
|
|
|
Timeout // The thread was woken up due to a wait timeout.
|
|
|
|
};
|
|
|
|
|
2020-01-06 20:03:40 +00:00
|
|
|
class Thread;
|
|
|
|
|
|
|
|
class WakeupCallback {
|
|
|
|
public:
|
|
|
|
virtual ~WakeupCallback() = default;
|
|
|
|
virtual void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
|
|
|
std::shared_ptr<WaitObject> object) = 0;
|
|
|
|
};
|
|
|
|
|
2018-10-23 14:57:59 +01:00
|
|
|
class ThreadManager {
|
|
|
|
public:
|
2018-11-21 04:50:00 +00:00
|
|
|
explicit ThreadManager(Kernel::KernelSystem& kernel);
|
2018-10-23 17:18:35 +01:00
|
|
|
~ThreadManager();
|
2018-10-23 16:57:59 +01:00
|
|
|
|
2018-10-23 15:32:23 +01:00
|
|
|
/**
|
|
|
|
* Creates a new thread ID
|
|
|
|
* @return The new thread ID
|
|
|
|
*/
|
|
|
|
u32 NewThreadId();
|
|
|
|
|
2018-10-23 16:40:57 +01:00
|
|
|
/**
|
|
|
|
* Gets the current thread
|
|
|
|
*/
|
|
|
|
Thread* GetCurrentThread() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reschedules to the next available thread (call after current thread is suspended)
|
|
|
|
*/
|
|
|
|
void Reschedule();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints the thread queue for debugging purposes
|
|
|
|
*/
|
|
|
|
void DebugThreadQueue();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether there are any threads that are ready to run.
|
|
|
|
*/
|
|
|
|
bool HaveReadyThreads();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Waits the current thread on a sleep
|
|
|
|
*/
|
|
|
|
void WaitCurrentThread_Sleep();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stops the current thread and removes it from the thread_list
|
|
|
|
*/
|
|
|
|
void ExitCurrentThread();
|
|
|
|
|
2018-10-23 17:18:35 +01:00
|
|
|
/**
|
|
|
|
* Get a const reference to the thread list for debug use
|
|
|
|
*/
|
2019-03-23 20:04:19 +00:00
|
|
|
const std::vector<std::shared_ptr<Thread>>& GetThreadList();
|
2018-10-23 17:18:35 +01:00
|
|
|
|
2019-02-01 16:23:39 +00:00
|
|
|
void SetCPU(ARM_Interface& cpu) {
|
|
|
|
this->cpu = &cpu;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<ARM_Interface::ThreadContext> NewContext() {
|
|
|
|
return cpu->NewContext();
|
|
|
|
}
|
|
|
|
|
2018-10-23 15:32:23 +01:00
|
|
|
private:
|
2018-10-23 16:40:57 +01:00
|
|
|
/**
|
|
|
|
* Switches the CPU's active thread context to that of the specified thread
|
|
|
|
* @param new_thread The thread to switch to
|
|
|
|
*/
|
|
|
|
void SwitchContext(Thread* new_thread);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pops and returns the next thread from the thread queue
|
|
|
|
* @return A pointer to the next ready thread
|
|
|
|
*/
|
|
|
|
Thread* PopNextReadyThread();
|
|
|
|
|
2018-10-23 16:57:59 +01:00
|
|
|
/**
|
|
|
|
* Callback that will wake up the thread it was scheduled for
|
|
|
|
* @param thread_id The ID of the thread that's been awoken
|
|
|
|
* @param cycles_late The number of CPU cycles that have passed since the desired wakeup time
|
|
|
|
*/
|
|
|
|
void ThreadWakeupCallback(u64 thread_id, s64 cycles_late);
|
|
|
|
|
2018-11-21 04:50:00 +00:00
|
|
|
Kernel::KernelSystem& kernel;
|
2019-02-01 16:23:39 +00:00
|
|
|
ARM_Interface* cpu;
|
2018-11-21 04:50:00 +00:00
|
|
|
|
2018-10-23 15:32:23 +01:00
|
|
|
u32 next_thread_id = 1;
|
2019-03-23 20:04:19 +00:00
|
|
|
std::shared_ptr<Thread> current_thread;
|
2018-10-23 16:40:57 +01:00
|
|
|
Common::ThreadQueueList<Thread*, ThreadPrioLowest + 1> ready_queue;
|
2018-10-23 16:57:59 +01:00
|
|
|
std::unordered_map<u64, Thread*> wakeup_callback_table;
|
|
|
|
|
|
|
|
/// Event type for the thread wake up event
|
2018-10-27 20:53:20 +01:00
|
|
|
Core::TimingEventType* ThreadWakeupEventType = nullptr;
|
2018-10-23 16:40:57 +01:00
|
|
|
|
2018-10-23 17:18:35 +01:00
|
|
|
// Lists all threadsthat aren't deleted.
|
2019-03-23 20:04:19 +00:00
|
|
|
std::vector<std::shared_ptr<Thread>> thread_list;
|
2018-10-23 17:18:35 +01:00
|
|
|
|
2018-10-23 16:40:57 +01:00
|
|
|
friend class Thread;
|
|
|
|
friend class KernelSystem;
|
2019-08-12 17:01:33 +01:00
|
|
|
|
|
|
|
friend class boost::serialization::access;
|
|
|
|
template <class Archive>
|
2019-12-27 21:07:29 +00:00
|
|
|
void serialize(Archive& ar, const unsigned int file_version) {
|
|
|
|
ar& next_thread_id;
|
|
|
|
ar& current_thread;
|
|
|
|
ar& ready_queue;
|
|
|
|
ar& wakeup_callback_table;
|
|
|
|
ar& thread_list;
|
2019-08-12 17:01:33 +01:00
|
|
|
}
|
2018-10-23 14:57:59 +01:00
|
|
|
};
|
|
|
|
|
2015-01-27 04:40:21 +00:00
|
|
|
class Thread final : public WaitObject {
|
2014-12-22 06:32:03 +00:00
|
|
|
public:
|
2019-12-27 18:52:33 +00:00
|
|
|
explicit Thread(KernelSystem&);
|
2019-03-23 20:04:19 +00:00
|
|
|
~Thread() override;
|
|
|
|
|
2016-09-18 01:38:01 +01:00
|
|
|
std::string GetName() const override {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
std::string GetTypeName() const override {
|
|
|
|
return "Thread";
|
|
|
|
}
|
2014-12-22 06:32:03 +00:00
|
|
|
|
2019-04-11 21:30:52 +01:00
|
|
|
static constexpr HandleType HANDLE_TYPE = HandleType::Thread;
|
2016-09-18 01:38:01 +01:00
|
|
|
HandleType GetHandleType() const override {
|
|
|
|
return HANDLE_TYPE;
|
|
|
|
}
|
2014-12-22 06:32:03 +00:00
|
|
|
|
Port various minor changes from yuzu PRs (#4725)
* common/thread: Remove unused functions
Many of these functions are carried over from Dolphin (where they aren't
used anymore). Given these have no use (and we really shouldn't be
screwing around with OS-specific thread scheduler handling from the
emulator, these can be removed.
The function for setting the thread name is left, however, since it can
have debugging utility usages.
* input_common/sdl: Use a type alias to shorten declaration of GetPollers
Just makes the definitions a little bit more tidy.
* input_common/sdl: Correct return values within implementations of GetPollers()
In both cases, we weren't actually returning anything, which is
undefined behavior.
* yuzu/debugger/graphics_surface: Fill in missing surface format listings
Fills in the missing surface types that were marked as unknown. The
order corresponds with the TextureFormat enum within
video_core/texture.h.
We also don't need to all of these strings as translatable (only the
first string, as it's an English word).
* yuzu/debugger/graphics_surface: Clean up connection overload deduction
We can utilize qOverload with the signal connections to make the
function deducing a little less ugly.
* yuzu/debugger/graphics_surface: Tidy up SaveSurface
- Use QStringLiteral where applicable.
- Use const where applicable
- Remove unnecessary precondition check (we already assert the pixbuf
being non null)
* yuzu/debugger/graphics_surface: Display error messages for file I/O errors
* core: Add missing override specifiers where applicable
Applies the override specifier where applicable. In the case of
destructors that are defaulted in their definition, they can
simply be removed.
This also removes the unnecessary inclusions being done in audin_u and
audrec_u, given their close proximity.
* kernel/thread: Make parameter of GetWaitObjectIndex() const qualified
The pointed to member is never actually modified, so it can be made
const.
* kernel/thread: Avoid sign conversion within GetCommandBufferAddress()
Previously this was performing a u64 + int sign conversion. When dealing
with addresses, we should generally be keeping the arithmetic in the
same signedness type.
This also gets rid of the static lifetime of the constant, as there's no
need to make a trivial type like this potentially live for the entire
duration of the program.
* kernel/codeset: Make CodeSet's memory data member a regular std::vector
The use of a shared_ptr is an implementation detail of the VMManager
itself when mapping memory. Because of that, we shouldn't require all
users of the CodeSet to have to allocate the shared_ptr ahead of time.
It's intended that CodeSet simply pass in the required direct data, and
that the memory manager takes care of it from that point on.
This means we just do the shared pointer allocation in a single place,
when loading modules, as opposed to in each loader.
* kernel/wait_object: Make ShouldWait() take thread members by pointer-to-const
Given this is intended as a querying function, it doesn't make sense to
allow the implementer to modify the state of the given thread.
2019-05-01 13:28:49 +01:00
|
|
|
bool ShouldWait(const Thread* thread) const override;
|
2017-01-01 21:53:22 +00:00
|
|
|
void Acquire(Thread* thread) override;
|
2014-12-22 06:32:03 +00:00
|
|
|
|
2015-01-26 06:56:17 +00:00
|
|
|
/**
|
|
|
|
* Gets the thread's current priority
|
|
|
|
* @return The current thread's priority
|
|
|
|
*/
|
2017-09-27 00:26:09 +01:00
|
|
|
u32 GetPriority() const {
|
2016-09-18 01:38:01 +01:00
|
|
|
return current_priority;
|
|
|
|
}
|
2015-01-26 06:56:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the thread's current priority
|
|
|
|
* @param priority The new priority
|
|
|
|
*/
|
2017-09-27 00:26:09 +01:00
|
|
|
void SetPriority(u32 priority);
|
2014-12-22 13:07:22 +00:00
|
|
|
|
2017-01-03 00:38:08 +00:00
|
|
|
/**
|
|
|
|
* Boost's a thread's priority to the best priority among the thread's held mutexes.
|
|
|
|
* This prevents priority inversion via priority inheritance.
|
|
|
|
*/
|
|
|
|
void UpdatePriority();
|
|
|
|
|
2015-04-03 23:40:16 +01:00
|
|
|
/**
|
|
|
|
* Temporarily boosts the thread's priority until the next time it is scheduled
|
|
|
|
* @param priority The new priority
|
|
|
|
*/
|
2017-09-27 00:26:09 +01:00
|
|
|
void BoostPriority(u32 priority);
|
2015-04-03 23:40:16 +01:00
|
|
|
|
2015-01-26 06:56:17 +00:00
|
|
|
/**
|
|
|
|
* Gets the thread's thread ID
|
|
|
|
* @return The thread's ID
|
|
|
|
*/
|
2016-09-18 01:38:01 +01:00
|
|
|
u32 GetThreadId() const {
|
|
|
|
return thread_id;
|
|
|
|
}
|
2015-05-25 19:34:09 +01:00
|
|
|
|
2015-01-26 06:56:17 +00:00
|
|
|
/**
|
|
|
|
* Resumes a thread from waiting
|
|
|
|
*/
|
2014-12-22 13:07:22 +00:00
|
|
|
void ResumeFromWait();
|
|
|
|
|
2015-01-31 01:07:54 +00:00
|
|
|
/**
|
2017-09-26 23:40:49 +01:00
|
|
|
* Schedules an event to wake up the specified thread after the specified delay
|
|
|
|
* @param nanoseconds The time this thread will be allowed to sleep for
|
|
|
|
*/
|
2015-01-31 01:07:54 +00:00
|
|
|
void WakeAfterDelay(s64 nanoseconds);
|
|
|
|
|
2015-01-17 07:03:44 +00:00
|
|
|
/**
|
2015-01-21 01:53:52 +00:00
|
|
|
* Sets the result after the thread awakens (from either WaitSynchronization SVC)
|
|
|
|
* @param result Value to set to the returned result
|
2015-01-17 07:03:44 +00:00
|
|
|
*/
|
2015-01-21 01:53:52 +00:00
|
|
|
void SetWaitSynchronizationResult(ResultCode result);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the output parameter value after the thread awakens (from WaitSynchronizationN SVC only)
|
|
|
|
* @param output Value to set to the output parameter
|
|
|
|
*/
|
|
|
|
void SetWaitSynchronizationOutput(s32 output);
|
2015-01-17 07:03:44 +00:00
|
|
|
|
2016-12-04 03:38:14 +00:00
|
|
|
/**
|
|
|
|
* Retrieves the index that this particular object occupies in the list of objects
|
2017-01-04 15:53:01 +00:00
|
|
|
* that the thread passed to WaitSynchronizationN, starting the search from the last element.
|
2016-12-04 03:38:14 +00:00
|
|
|
* It is used to set the output value of WaitSynchronizationN when the thread is awakened.
|
2017-01-04 15:53:01 +00:00
|
|
|
* When a thread wakes up due to an object signal, the kernel will use the index of the last
|
|
|
|
* matching object in the wait objects list in case of having multiple instances of the same
|
|
|
|
* object in the list.
|
2016-12-04 03:38:14 +00:00
|
|
|
* @param object Object to query the index of.
|
|
|
|
*/
|
Port various minor changes from yuzu PRs (#4725)
* common/thread: Remove unused functions
Many of these functions are carried over from Dolphin (where they aren't
used anymore). Given these have no use (and we really shouldn't be
screwing around with OS-specific thread scheduler handling from the
emulator, these can be removed.
The function for setting the thread name is left, however, since it can
have debugging utility usages.
* input_common/sdl: Use a type alias to shorten declaration of GetPollers
Just makes the definitions a little bit more tidy.
* input_common/sdl: Correct return values within implementations of GetPollers()
In both cases, we weren't actually returning anything, which is
undefined behavior.
* yuzu/debugger/graphics_surface: Fill in missing surface format listings
Fills in the missing surface types that were marked as unknown. The
order corresponds with the TextureFormat enum within
video_core/texture.h.
We also don't need to all of these strings as translatable (only the
first string, as it's an English word).
* yuzu/debugger/graphics_surface: Clean up connection overload deduction
We can utilize qOverload with the signal connections to make the
function deducing a little less ugly.
* yuzu/debugger/graphics_surface: Tidy up SaveSurface
- Use QStringLiteral where applicable.
- Use const where applicable
- Remove unnecessary precondition check (we already assert the pixbuf
being non null)
* yuzu/debugger/graphics_surface: Display error messages for file I/O errors
* core: Add missing override specifiers where applicable
Applies the override specifier where applicable. In the case of
destructors that are defaulted in their definition, they can
simply be removed.
This also removes the unnecessary inclusions being done in audin_u and
audrec_u, given their close proximity.
* kernel/thread: Make parameter of GetWaitObjectIndex() const qualified
The pointed to member is never actually modified, so it can be made
const.
* kernel/thread: Avoid sign conversion within GetCommandBufferAddress()
Previously this was performing a u64 + int sign conversion. When dealing
with addresses, we should generally be keeping the arithmetic in the
same signedness type.
This also gets rid of the static lifetime of the constant, as there's no
need to make a trivial type like this potentially live for the entire
duration of the program.
* kernel/codeset: Make CodeSet's memory data member a regular std::vector
The use of a shared_ptr is an implementation detail of the VMManager
itself when mapping memory. Because of that, we shouldn't require all
users of the CodeSet to have to allocate the shared_ptr ahead of time.
It's intended that CodeSet simply pass in the required direct data, and
that the memory manager takes care of it from that point on.
This means we just do the shared pointer allocation in a single place,
when loading modules, as opposed to in each loader.
* kernel/wait_object: Make ShouldWait() take thread members by pointer-to-const
Given this is intended as a querying function, it doesn't make sense to
allow the implementer to modify the state of the given thread.
2019-05-01 13:28:49 +01:00
|
|
|
s32 GetWaitObjectIndex(const WaitObject* object) const;
|
2016-12-04 03:38:14 +00:00
|
|
|
|
2015-01-26 06:56:17 +00:00
|
|
|
/**
|
|
|
|
* Stops a thread, invalidating it from further use
|
|
|
|
*/
|
|
|
|
void Stop();
|
|
|
|
|
2015-05-11 00:35:37 +01:00
|
|
|
/*
|
|
|
|
* Returns the Thread Local Storage address of the current thread
|
|
|
|
* @returns VAddr of the thread's TLS
|
|
|
|
*/
|
2016-09-18 01:38:01 +01:00
|
|
|
VAddr GetTLSAddress() const {
|
|
|
|
return tls_address;
|
|
|
|
}
|
2015-05-11 00:35:37 +01:00
|
|
|
|
2017-09-29 20:47:52 +01:00
|
|
|
/*
|
|
|
|
* Returns the address of the current thread's command buffer, located in the TLS.
|
|
|
|
* @returns VAddr of the thread's command buffer.
|
|
|
|
*/
|
|
|
|
VAddr GetCommandBufferAddress() const;
|
|
|
|
|
2016-12-04 14:58:36 +00:00
|
|
|
/**
|
|
|
|
* Returns whether this thread is waiting for all the objects in
|
|
|
|
* its wait list to become ready, as a result of a WaitSynchronizationN call
|
2017-01-04 15:44:38 +00:00
|
|
|
* with wait_all = true.
|
2016-12-04 14:58:36 +00:00
|
|
|
*/
|
2016-12-08 15:34:53 +00:00
|
|
|
bool IsSleepingOnWaitAll() const {
|
2018-07-20 02:39:05 +01:00
|
|
|
return status == ThreadStatus::WaitSynchAll;
|
2016-12-04 14:58:36 +00:00
|
|
|
}
|
|
|
|
|
2017-12-12 19:12:03 +00:00
|
|
|
std::unique_ptr<ARM_Interface::ThreadContext> context;
|
2014-12-22 06:32:03 +00:00
|
|
|
|
|
|
|
u32 thread_id;
|
|
|
|
|
2018-07-20 02:39:05 +01:00
|
|
|
ThreadStatus status;
|
|
|
|
VAddr entry_point;
|
|
|
|
VAddr stack_top;
|
2014-12-22 06:32:03 +00:00
|
|
|
|
2017-09-27 00:26:09 +01:00
|
|
|
u32 nominal_priority; ///< Nominal thread priority, as set by the emulated application
|
|
|
|
u32 current_priority; ///< Current thread priority, can be temporarily changed
|
2015-03-24 03:55:21 +00:00
|
|
|
|
|
|
|
u64 last_running_ticks; ///< CPU tick when thread was last running
|
2014-12-22 06:32:03 +00:00
|
|
|
|
|
|
|
s32 processor_id;
|
|
|
|
|
2016-04-19 23:12:48 +01:00
|
|
|
VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread
|
2015-05-11 00:43:59 +01:00
|
|
|
|
2015-01-31 21:22:40 +00:00
|
|
|
/// Mutexes currently held by this thread, which will be released when it exits.
|
2019-03-23 20:04:19 +00:00
|
|
|
boost::container::flat_set<std::shared_ptr<Mutex>> held_mutexes;
|
2015-01-18 18:25:51 +00:00
|
|
|
|
2017-01-03 00:38:08 +00:00
|
|
|
/// Mutexes that this thread is currently waiting for.
|
2019-03-23 20:04:19 +00:00
|
|
|
boost::container::flat_set<std::shared_ptr<Mutex>> pending_mutexes;
|
2017-01-03 00:38:08 +00:00
|
|
|
|
2020-01-06 20:03:40 +00:00
|
|
|
std::shared_ptr<Process> owner_process; ///< Process that owns this thread
|
2016-12-04 14:58:36 +00:00
|
|
|
|
2017-01-04 15:53:01 +00:00
|
|
|
/// Objects that the thread is waiting on, in the same order as they were
|
|
|
|
// passed to WaitSynchronization1/N.
|
2019-03-23 20:04:19 +00:00
|
|
|
std::vector<std::shared_ptr<WaitObject>> wait_objects;
|
2016-12-04 14:58:36 +00:00
|
|
|
|
2016-12-14 17:13:02 +00:00
|
|
|
VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
|
2016-12-04 03:38:14 +00:00
|
|
|
|
2014-12-22 06:32:03 +00:00
|
|
|
std::string name;
|
|
|
|
|
2017-09-28 17:53:32 +01:00
|
|
|
// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
|
|
|
|
// was waiting via WaitSynchronizationN then the object will be the last object that became
|
|
|
|
// available. In case of a timeout, the object will be nullptr.
|
2020-01-06 20:03:40 +00:00
|
|
|
std::shared_ptr<WakeupCallback> wakeup_callback;
|
2017-09-28 17:53:32 +01:00
|
|
|
|
2014-12-22 06:32:03 +00:00
|
|
|
private:
|
2018-10-23 14:57:59 +01:00
|
|
|
ThreadManager& thread_manager;
|
2019-08-12 17:01:33 +01:00
|
|
|
|
|
|
|
friend class boost::serialization::access;
|
|
|
|
template <class Archive>
|
|
|
|
void serialize(Archive& ar, const unsigned int file_version);
|
2014-12-22 06:32:03 +00:00
|
|
|
};
|
|
|
|
|
2015-01-26 06:56:17 +00:00
|
|
|
/**
|
|
|
|
* Sets up the primary application thread
|
2018-10-12 20:47:06 +01:00
|
|
|
* @param kernel The kernel instance on which the thread is created
|
2015-01-26 06:56:17 +00:00
|
|
|
* @param entry_point The address at which the thread should start execution
|
|
|
|
* @param priority The priority to give the main thread
|
2017-09-26 23:40:49 +01:00
|
|
|
* @param owner_process The parent process for the main thread
|
2015-01-26 06:56:17 +00:00
|
|
|
* @return A shared pointer to the main thread
|
|
|
|
*/
|
2019-03-23 20:04:19 +00:00
|
|
|
std::shared_ptr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority,
|
|
|
|
std::shared_ptr<Process> owner_process);
|
2014-05-14 03:00:11 +01:00
|
|
|
|
2017-09-26 23:40:49 +01:00
|
|
|
} // namespace Kernel
|
2019-12-22 23:37:17 +00:00
|
|
|
|
|
|
|
BOOST_CLASS_EXPORT_KEY(Kernel::Thread)
|
2019-12-27 18:52:33 +00:00
|
|
|
CONSTRUCT_KERNEL_OBJECT(Kernel::Thread)
|