Skip to content

Add basic support for threading functions in rexcrt#291

Draft
Minositu wants to merge 37 commits intorexglue:developmentfrom
Minositu:threadingcrt
Draft

Add basic support for threading functions in rexcrt#291
Minositu wants to merge 37 commits intorexglue:developmentfrom
Minositu:threadingcrt

Conversation

@Minositu
Copy link
Copy Markdown
Collaborator

Summary

Adds basic support for the basic thread functions in rexcrt.

tomcl7 and others added 30 commits April 10, 2026 14:27
…tion

Adds an API to install STFS content packages (CON/PIRS/LIVE) from arbitrary host paths. Mounts the package via StfsContainerDevice, extracts all files breadth-first into the standard content directory (0000000000000000/{title_id}/00000002/{filename}/), and writes a .header file with license mask for XAM enumeration.

Also extends WriteContentHeaderFile to write an optional license mask after the XCONTENT_AGGREGATE_DATA struct.
tomcl7 and others added 7 commits April 13, 2026 15:56
* feat(krnl): Add stubs for xbdm

This also resolves the ordinals relating to the xbdm functions. Closes rexglue#191
XGISessionDelete, XSessionStart, XSessionEnd, XSessionSearch, XSessionModify, XSessionSearchEx, XSessionGetDetails, XSessionMigrateHost, XSessionGetInvitationData, XSessionArbitrationRegister, XSessionSearchByID, XSessionModifySkill, XUserResetStatsView, "XUserReadStats, XSessionWriteStats, XSessionFlushStats, XInvalidateGamerTileCache, & XUserGetANID are now documented
@tomcl7 tomcl7 requested review from tomcl7 and removed request for tomcl7 April 18, 2026 20:00
if (!dwStackSize)
dwStackSize = REX_KERNEL_STATE()->GetExecutableModule()->stack_size();
dwStackSize = std::max((uint32_t)0x4000, ((dwStackSize + 0xFFF) & 0xFFFFF000));
dwCreationFlags = ((dwCreationFlags >> 2) & 1);
Copy link
Copy Markdown
Member

@tomcl7 tomcl7 Apr 18, 2026

Choose a reason for hiding this comment

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

Suggested change
dwCreationFlags = ((dwCreationFlags >> 2) & 1);
u32 x_flags = (dwCreationFlags & 0x4) ? X_CREATE_SUSPENDED : 0;

Win32 CREATE_SUSPENDED (0x4) -> Xbox X_CREATE_SUSPENDED (0x1).


auto thread = rex::system::object_ref<rex::system::XThread>(
new rex::system::XThread(REX_KERNEL_STATE(), dwStackSize, 0, lpStartAddress.guest_address(),
lpParameter.guest_address(), dwCreationFlags, true, false,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
lpParameter.guest_address(), dwCreationFlags, true, false,
lpParameter.guest_address(), x_flags, true, false,

Comment on lines +352 to +353
if (dwCreationFlags & 0x80)
return thread->guest_object();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if (dwCreationFlags & 0x80)
return thread->guest_object();

Win32 CreateThread always returns a HANDLE.


// Helper function in xam to format timeouts.
uint64_t* XapiFormatTimeOut(uint64_t* TimeOut, uint32_t Millis) {
if (Millis == -1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if (Millis == -1)
if (Millis == static_cast<uint32_t>(-1))

rex::system::XThread::GetCurrentThread()->Exit(exitCode);
}

// Helper function in xam to format timeouts.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
// Helper function in xam to format timeouts.
// Converts a Win32 millisecond timeout to a relative Xbox NT timeout (100 ns units).

uint64_t* XapiFormatTimeOut(uint64_t* TimeOut, uint32_t Millis) {
if (Millis == -1)
return nullptr;
*TimeOut = static_cast<uint64_t>(-1) * Millis;
Copy link
Copy Markdown
Member

@tomcl7 tomcl7 Apr 18, 2026

Choose a reason for hiding this comment

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

Suggested change
*TimeOut = static_cast<uint64_t>(-1) * Millis;
*TimeOut = static_cast<uint64_t>(-10000LL * static_cast<int64_t>(Millis));

Add the missing 10000× factor so timeouts are 100 ns units, not microseconds

uint64_t timeout_val;
uint64_t* timeout = XapiFormatTimeOut(&timeout_val, dwMilliseconds);

uint32_t result = 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
uint32_t result = 0;
uint32_t result = obj->Wait(3, 1, bAlertable, timeout);;

Comment on lines +382 to +395
while (!(result & 0x80000000)) {
result = obj->Wait(3, 1, bAlertable, timeout);

if (bAlertable && result == X_STATUS_USER_APC) {
rex::system::XThread::GetCurrentThread()->DeliverAPCs();
continue;
}

if (!bAlertable || result != X_STATUS_TIMEOUT) {
return result;
}
}

return -1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
while (!(result & 0x80000000)) {
result = obj->Wait(3, 1, bAlertable, timeout);
if (bAlertable && result == X_STATUS_USER_APC) {
rex::system::XThread::GetCurrentThread()->DeliverAPCs();
continue;
}
if (!bAlertable || result != X_STATUS_TIMEOUT) {
return result;
}
}
return -1;
if (bAlertable && result == X_STATUS_USER_APC) {
rex::system::XThread::GetCurrentThread()->DeliverAPCs();
}
return result;

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.

5 participants