mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2026-05-10 19:01:53 +00:00
System to specify thread types by the game
This commit is contained in:
parent
c91627740f
commit
9a9585d0f9
3 changed files with 84 additions and 18 deletions
|
|
@ -1,14 +1,10 @@
|
|||
#ifndef __RSP_STUFF_HPP__
|
||||
#define __RSP_STUFF_HPP__
|
||||
|
||||
// TODO: rename
|
||||
#ifndef __RSP_HPP__
|
||||
#define __RSP_HPP__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "ultra64.h"
|
||||
|
||||
// TODO: Move these to ultramodern namespace?
|
||||
|
||||
namespace ultramodern {
|
||||
namespace rsp {
|
||||
struct callbacks_t {
|
||||
|
|
|
|||
40
ultramodern/include/ultramodern/threads.hpp
Normal file
40
ultramodern/include/ultramodern/threads.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __THREADS_HPP__
|
||||
#define __THREADS_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ultra64.h"
|
||||
|
||||
namespace ultramodern {
|
||||
namespace threads {
|
||||
enum class GameThreadType {
|
||||
Normal,
|
||||
Temporary,
|
||||
Permanent
|
||||
};
|
||||
|
||||
struct callbacks_t {
|
||||
using get_game_thread_type_t = GameThreadType(OSThread* t);
|
||||
using get_game_thread_name_t = std::string(OSThread* t);
|
||||
|
||||
/**
|
||||
* TODO: document, I don't understand what this is used for.
|
||||
*/
|
||||
get_game_thread_type_t *get_game_thread_type;
|
||||
|
||||
/**
|
||||
* Allows specifying a custom name for each thread.
|
||||
*
|
||||
* If this function is not provided then the thread id will be used as the name.
|
||||
*/
|
||||
get_game_thread_name_t *get_game_thread_name;
|
||||
};
|
||||
|
||||
void set_callbacks(const callbacks_t& callbacks);
|
||||
|
||||
GameThreadType get_game_thread_type(OSThread* t);
|
||||
std::string get_game_thread_name(OSThread* t);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -7,11 +7,33 @@
|
|||
#include "ultramodern/ultramodern.hpp"
|
||||
#include "blockingconcurrentqueue.h"
|
||||
|
||||
#include "ultramodern/threads.hpp"
|
||||
|
||||
// Native APIs only used to set thread names for easier debugging
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static ultramodern::threads::callbacks_t threads_callbacks;
|
||||
|
||||
void ultramodern::threads::set_callbacks(const callbacks_t& callbacks) {
|
||||
threads_callbacks = callbacks;
|
||||
}
|
||||
|
||||
ultramodern::threads::GameThreadType ultramodern::threads::get_game_thread_type(OSThread* t) {
|
||||
if (threads_callbacks.get_game_thread_type == nullptr) {
|
||||
return GameThreadType::Normal;
|
||||
}
|
||||
return threads_callbacks.get_game_thread_type(t);
|
||||
}
|
||||
|
||||
std::string ultramodern::threads::get_game_thread_name(OSThread* t) {
|
||||
if (threads_callbacks.get_game_thread_name == nullptr) {
|
||||
return std::to_string(t->id);
|
||||
}
|
||||
return threads_callbacks.get_game_thread_name(t);
|
||||
}
|
||||
|
||||
extern "C" void bootproc();
|
||||
|
||||
thread_local bool is_main_thread = false;
|
||||
|
|
@ -165,15 +187,18 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
is_game_thread = true;
|
||||
|
||||
// Set the thread name
|
||||
ultramodern::set_native_thread_name("Game Thread " + std::to_string(self->id));
|
||||
ultramodern::set_native_thread_name("Game Thread " + ultramodern::threads::get_game_thread_name(self));
|
||||
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::High);
|
||||
|
||||
// TODO fix these being hardcoded (this is only used for quicksaving)
|
||||
if ((self->id == 2 && self->priority == 5) || self->id == 13) { // slowly, flashrom
|
||||
temporary_threads.fetch_add(1);
|
||||
}
|
||||
else if (self->id != 1 && self->id != 2) { // ignore idle and fault
|
||||
permanent_threads.fetch_add(1);
|
||||
switch (ultramodern::threads::get_game_thread_type(self)) {
|
||||
case ultramodern::threads::GameThreadType::Normal:
|
||||
break;
|
||||
case ultramodern::threads::GameThreadType::Temporary:
|
||||
temporary_threads.fetch_add(1);
|
||||
break;
|
||||
case ultramodern::threads::GameThreadType::Permanent:
|
||||
permanent_threads.fetch_add(1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Signal the initialized semaphore to indicate that this thread can be started.
|
||||
|
|
@ -183,7 +208,7 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
|
||||
// Wait until the thread is marked as running.
|
||||
wait_for_resumed(PASS_RDRAM thread_context);
|
||||
|
||||
|
||||
// Make sure the thread wasn't replaced or destroyed before it was started.
|
||||
if (self->context == thread_context) {
|
||||
debug_printf("[Thread] Thread started: %d\n", self->id);
|
||||
|
|
@ -206,10 +231,15 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
|
||||
// Dispose of this thread now that it's completed or terminated.
|
||||
ultramodern::cleanup_thread(thread_context);
|
||||
|
||||
// TODO fix these being hardcoded (this is only used for quicksaving)
|
||||
if ((self->id == 2 && self->priority == 5) || self->id == 13) { // slowly, flashrom
|
||||
temporary_threads.fetch_sub(1);
|
||||
|
||||
switch (ultramodern::threads::get_game_thread_type(self)) {
|
||||
case ultramodern::threads::GameThreadType::Normal:
|
||||
break;
|
||||
case ultramodern::threads::GameThreadType::Temporary:
|
||||
temporary_threads.fetch_sub(1);
|
||||
break;
|
||||
case ultramodern::threads::GameThreadType::Permanent:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue