Skip to content

Feat/TLSFAlloc#105

Merged
Pistonight merged 6 commits into
mainfrom
feat/TLSFAlloc
May 20, 2026
Merged

Feat/TLSFAlloc#105
Pistonight merged 6 commits into
mainfrom
feat/TLSFAlloc

Conversation

@mchalupiak
Copy link
Copy Markdown
Collaborator

Integration of TLSF allocator

Copy link
Copy Markdown
Collaborator

@Pistonight Pistonight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Licesne file(s) need to be updated

@@ -5,25 +5,3 @@

#include <switch/types.h>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this header if it's just a single define?

#include <nn/os/os_Mutex.h>

namespace nn::os {
Mutex::~Mutex() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be implemented?

Comment thread packages/lib/src/alloc.cpp Outdated
void *ptr = allocator().Allocate(size, align);
if (ptr != nullptr) {
return (u8 *)ptr;
mem_mutex.Lock();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not unlocking? consider making a Scope lock wrapper

Comment thread packages/lib/src/alloc.cpp Outdated
return (u8 *)ptr;
mem_mutex.Lock();
if (!mem_initialized) {
allocator = tlsf_create_with_pool(bss_alloc, BSS_ALLOC_SIZE);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be slightly simpler to initialize the pool as part of the lib init then you don't need to track if it's initialized

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static-initialized memory in rust can't allocate so this will not get called before initialization

StandardAllocator();
StandardAllocator(void* address, size_t size);
StandardAllocator(void* address, size_t size, bool enableCache);
#include <megaton/__internal/tlsf.h>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's best to not expose tlsf.h, which is implementation detail

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exposed so that allocator can be initialized in init.cpp (without it the type pool_t and the function tlsf_create_with_pool are undefined). Is there a better approach to achieving this? I thought the header was appropriate because BSS_ALLOC_SIZE should only be defined in one place.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// __internal/alloc.h

namespace megaton::alloc {
void init_pool();
}

// alloc.cpp

static YOUR_GLOBAL_VARIABLES_HERE;
namespace megaton::alloc {
void init_pool() {
    allocator = tlsf_create_with_pool(..);
}
}

// init.cpp
void __megaton_librs_init() {
        megaton::alloc::init_pool();
}

If you imagine alloc.cpp and init.cpp as 2 classes, allocator is like a private field that should not be exposed, but it can be initialized via a public interface (a function)

Comment thread packages/lib/src/megaton/init.cpp Outdated

void __megaton_librs_init() {
allocator = tlsf_create_with_pool(bss_alloc, BSS_ALLOC_SIZE);
return;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can declare a megaton::alloc::init_pool in alloc.h then implementation detail will not be exposed (i.e. you don't need tlsf.h here or any of the extern symbols)


void Mutex::unlock() {
this->Unlock();
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does these need to be implemented? they should already be defined in the SDK

Copy link
Copy Markdown
Collaborator

@Pistonight Pistonight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nn::os::Mutex implementation should be removed, you should only need the header

@mchalupiak
Copy link
Copy Markdown
Collaborator Author

mchalupiak commented May 19, 2026

I take no issue with removing the nn::os::Mutex, but it was added as a result of an undefined symbol error we had encountered previously, specifically _ZN2nn2os5MutexD1Ev was not defined. The same is true of nn::os::Mutex::{lock,unlock}, as the undefined symbols _ZN2nn2os5Mutex6unlockEv and _ZN2nn2os5Mutex4lockEv are generated. I have confirmed that these errors still appear as well

@mchalupiak
Copy link
Copy Markdown
Collaborator Author

Additionally, should the init_allocator function be thread safe? In theory it should be called at init from a single threaded context so thread safety shouldn't be an issue

@Pistonight
Copy link
Copy Markdown
Collaborator

Ok I remember the dtor issue.. maybe try using std::mutex?
As for lock and unlock, they aren't in the symbols so not sure why it's in nnheades, maybe it was added in a later version

@Pistonight Pistonight merged commit 557b57b into main May 20, 2026
4 checks passed
@Pistonight Pistonight deleted the feat/TLSFAlloc branch May 20, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants