2020-04-19 23:04:05 +02:00
// SPDX-License-Identifier: MPL-2.0
2020-03-27 20:36:02 +01:00
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
2019-09-24 22:54:27 +02:00
# pragma once
2020-11-03 10:44:09 +01:00
# include <csetjmp>
2020-10-10 17:53:14 +02:00
# include <nce/guest.h>
2019-09-24 22:54:27 +02:00
# include "KSyncObject.h"
2020-10-07 17:41:13 +02:00
# include "KPrivateMemory.h"
2020-01-07 03:36:08 +01:00
# include "KSharedMemory.h"
2019-09-24 22:54:27 +02:00
2020-10-07 17:41:13 +02:00
namespace skyline {
namespace kernel : : type {
2020-04-22 19:02:27 +02:00
struct Priority {
i8 low ; //!< The low range of priority
i8 high ; //!< The high range of priority
/**
* @ param priority The priority range of the value
* @ param value The priority value to rescale
* @ return The rescaled priority value according to this range
*/
2020-10-07 17:41:13 +02:00
constexpr i8 Rescale ( const Priority & priority , i8 value ) const {
2020-04-22 19:02:27 +02:00
return static_cast < i8 > ( priority . low + ( ( static_cast < float > ( priority . high - priority . low ) / static_cast < float > ( priority . low - priority . high ) ) * ( static_cast < float > ( value ) - priority . low ) ) ) ;
}
/**
* @ param value The priority value to check for validity
* @ return If the supplied priority value is valid
*/
2020-10-07 17:41:13 +02:00
constexpr bool Valid ( i8 value ) const {
2020-04-22 19:02:27 +02:00
return ( value > = low ) & & ( value < = high ) ;
}
} ;
2020-10-07 17:41:13 +02:00
}
2020-04-22 19:02:27 +02:00
2020-10-07 17:41:13 +02:00
namespace constant {
2020-10-21 19:09:35 +02:00
constexpr u8 CoreCount { 4 } ; // The amount of cores an HOS process can be scheduled onto (User applications can only be on the first 3 cores, the last one is reserved for the system)
2020-10-07 17:41:13 +02:00
constexpr kernel : : type : : Priority HosPriority { 0 , 63 } ; //!< The range of priorities for Horizon OS
}
2019-09-24 22:54:27 +02:00
2020-10-07 17:41:13 +02:00
namespace kernel : : type {
2019-09-24 22:54:27 +02:00
/**
2020-10-07 17:41:13 +02:00
* @ brief KThread manages a single thread of execution which is responsible for running guest code and kernel code which is invoked by the guest
2019-09-24 22:54:27 +02:00
*/
2020-11-03 10:44:09 +01:00
class KThread : public KSyncObject , public std : : enable_shared_from_this < KThread > {
2020-10-07 17:41:13 +02:00
private :
KProcess * parent ;
std : : optional < std : : thread > thread ; //!< If this KThread is backed by a host thread then this'll hold it
2020-11-03 10:44:09 +01:00
pthread_t pthread { } ; //!< The pthread_t for the host thread running this guest thread
2019-09-24 22:54:27 +02:00
2020-10-07 17:41:13 +02:00
void StartThread ( ) ;
2019-09-24 22:54:27 +02:00
2020-10-07 17:41:13 +02:00
public :
2020-11-03 10:44:09 +01:00
std : : mutex mutex ; //!< Synchronizes all thread state changes
2020-10-17 13:38:27 +02:00
bool running { false } ;
2020-10-07 17:41:13 +02:00
std : : atomic < bool > cancelSync { false } ; //!< This is to flag to a thread to cancel a synchronization call it currently is in
2019-09-24 22:54:27 +02:00
2020-10-07 17:41:13 +02:00
KHandle handle ;
size_t id ; //!< Index of thread in parent process's KThread vector
2019-11-22 15:59:50 +01:00
2020-11-03 10:44:09 +01:00
nce : : ThreadContext ctx { } ; //!< The context of the guest thread during the last SVC
jmp_buf originalCtx ; //!< The context of the host thread prior to jumping into guest code
2020-10-07 17:41:13 +02:00
2020-11-03 10:44:09 +01:00
void * entry ;
2020-10-07 17:41:13 +02:00
u64 entryArgument ;
2020-11-03 10:44:09 +01:00
void * stackTop ;
2020-10-21 19:09:35 +02:00
2020-10-07 17:41:13 +02:00
i8 priority ;
2020-10-21 19:09:35 +02:00
i8 idealCore ;
i8 coreId ; //!< The CPU core on which this thread is running
std : : bitset < constant : : CoreCount > affinityMask { } ; //!< The CPU core on which this thread is running
2020-10-07 17:41:13 +02:00
2020-10-21 19:09:35 +02:00
KThread ( const DeviceState & state , KHandle handle , KProcess * parent , size_t id , void * entry , u64 argument , void * stackTop , i8 priority , i8 idealCore ) ;
2020-10-07 17:41:13 +02:00
~ KThread ( ) ;
/**
* @ param self If the calling thread should jump directly into guest code or if a new thread should be created for it
* @ note If the thread is already running then this does nothing
* @ note ' stack ' will be created if it wasn ' t set prior to calling this
*/
void Start ( bool self = false ) ;
2020-10-17 13:38:27 +02:00
/**
2020-11-03 10:44:09 +01:00
* @ param join Returns after the guest thread has joined rather than instantly
2020-10-17 13:38:27 +02:00
*/
2020-11-03 10:44:09 +01:00
void Kill ( bool join ) ;
2020-10-07 17:41:13 +02:00
void UpdatePriority ( i8 priority ) ;
} ;
}
2019-09-24 22:54:27 +02:00
}