@ -10,8 +10,10 @@
# include "common/common_types.h"
# include "common/common_types.h"
# include "common/logging/log.h"
# include "common/logging/log.h"
# include "common/serialization/boost_flat_set.h"
# include "common/serialization/boost_flat_set.h"
# include "common/settings.h"
# include "core/arm/arm_interface.h"
# include "core/arm/arm_interface.h"
# include "core/arm/skyeye_common/armstate.h"
# include "core/arm/skyeye_common/armstate.h"
# include "core/core.h"
# include "core/hle/kernel/errors.h"
# include "core/hle/kernel/errors.h"
# include "core/hle/kernel/kernel.h"
# include "core/hle/kernel/kernel.h"
# include "core/hle/kernel/mutex.h"
# include "core/hle/kernel/mutex.h"
@ -324,7 +326,7 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, u32
ResultVal < std : : shared_ptr < Thread > > KernelSystem : : CreateThread (
ResultVal < std : : shared_ptr < Thread > > KernelSystem : : CreateThread (
std : : string name , VAddr entry_point , u32 priority , u32 arg , s32 processor_id , VAddr stack_top ,
std : : string name , VAddr entry_point , u32 priority , u32 arg , s32 processor_id , VAddr stack_top ,
std : : shared_ptr < Process > owner_process ) {
std : : shared_ptr < Process > owner_process , bool make_ready ) {
// Check if priority is in ranged. Lowest priority -> highest priority id.
// Check if priority is in ranged. Lowest priority -> highest priority id.
if ( priority > ThreadPrioLowest ) {
if ( priority > ThreadPrioLowest ) {
LOG_ERROR ( Kernel_SVC , " Invalid thread priority: {} " , priority ) ;
LOG_ERROR ( Kernel_SVC , " Invalid thread priority: {} " , priority ) ;
@ -367,8 +369,11 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(
// to initialize the context
// to initialize the context
ResetThreadContext ( thread - > context , stack_top , entry_point , arg ) ;
ResetThreadContext ( thread - > context , stack_top , entry_point , arg ) ;
thread_managers [ processor_id ] - > ready_queue . push_back ( thread - > current_priority , thread . get ( ) ) ;
if ( make_ready ) {
thread - > status = ThreadStatus : : Ready ;
thread_managers [ processor_id ] - > ready_queue . push_back ( thread - > current_priority ,
thread . get ( ) ) ;
thread - > status = ThreadStatus : : Ready ;
}
return thread ;
return thread ;
}
}
@ -405,16 +410,36 @@ void Thread::BoostPriority(u32 priority) {
std : : shared_ptr < Thread > SetupMainThread ( KernelSystem & kernel , u32 entry_point , u32 priority ,
std : : shared_ptr < Thread > SetupMainThread ( KernelSystem & kernel , u32 entry_point , u32 priority ,
std : : shared_ptr < Process > owner_process ) {
std : : shared_ptr < Process > owner_process ) {
constexpr s64 sleep_app_thread_ns = 2'600'000'000LL ;
constexpr u32 system_module_tid_high = 0x00040130 ;
const bool is_lle_service =
static_cast < u32 > ( owner_process - > codeset - > program_id > > 32 ) = = system_module_tid_high ;
s64 sleep_time_ns = 0 ;
if ( ! is_lle_service & & kernel . GetAppMainThreadExtendedSleep ( ) ) {
if ( Settings : : values . delay_start_for_lle_modules ) {
sleep_time_ns = sleep_app_thread_ns ;
}
kernel . SetAppMainThreadExtendedSleep ( false ) ;
}
// Initialize new "main" thread
// Initialize new "main" thread
auto thread_res =
auto thread_res =
kernel . CreateThread ( " main " , entry_point , priority , 0 , owner_process - > ideal_processor ,
kernel . CreateThread ( " main " , entry_point , priority , 0 , owner_process - > ideal_processor ,
Memory : : HEAP_VADDR_END , owner_process ) ;
Memory : : HEAP_VADDR_END , owner_process , sleep_time_ns = = 0 );
std : : shared_ptr < Thread > thread = std : : move ( thread_res ) . Unwrap ( ) ;
std : : shared_ptr < Thread > thread = std : : move ( thread_res ) . Unwrap ( ) ;
thread - > context . fpscr =
thread - > context . fpscr =
FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC ; // 0x03C00010
FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC ; // 0x03C00010
if ( sleep_time_ns ! = 0 ) {
thread - > status = ThreadStatus : : WaitSleep ;
thread - > WakeAfterDelay ( sleep_time_ns ) ;
}
// Note: The newly created thread will be run when the scheduler fires.
// Note: The newly created thread will be run when the scheduler fires.
return thread ;
return thread ;
}
}