Skip to content

Instantly share code, notes, and snippets.

@AXKuhta
Created July 1, 2020 12:59
Show Gist options
  • Save AXKuhta/db2c8b1d528bd99145372567051d4f4f to your computer and use it in GitHub Desktop.
Save AXKuhta/db2c8b1d528bd99145372567051d4f4f to your computer and use it in GitHub Desktop.
Misusing bbThreadSetData() and bbThreadGetData() in BlitzMax NG
' This code works on x64 windows, but fails on arm64
' That occurs because the upper 4 bytes of the pointer get cut off and arm relies on them
' I.e. 0x0000007f88799fc0 turns into 0xffffffff88799fc0 on arm
' On x64 it doesn't crash because the upper 4 bytes are just so happen to be unused
' I.e. 0000000003139FC0 still remains 0000000003139FC0
' You _can_ make it work on arm if you manually replace the higher 0xffffffff back to 0x0000007f
'
' This code is only for documenting purposes
Framework BRL.StandardIO
Import BRL.Threads
Import "thread_hack.c"
Extern
Function set_thread_data(data:SomeData)
Function get_thread_data:SomeData()
End Extern
Type SomeData
Field A:String
Field B:String
End Type
Local Inst:SomeData = New SomeData
Inst.A = "Hello"
Inst.B = "World"
set_thread_data(Inst)
Print "Data has been set. Will now attempt to recover it."
Print get_thread_data().A + get_thread_data().B
void set_thread_data(struct _m_test_SomeData_obj* data) {
printf("Got a pointer: %p\n", data);
bbThreadSetData(16, data);
}
struct _m_test_SomeData_obj* get_thread_data() {
struct _m_test_SomeData_obj* data;
data = (struct _m_test_SomeData_obj*)bbThreadGetData(16);
printf("Recovered a pointer: %p\n", data);
return data;
}
@AXKuhta
Copy link
Author

AXKuhta commented Jul 1, 2020

Forgot to mention, the entire point of this code is that data set by set_thread_data() and recovered by get_thread_data() will be unique to the caller thread. It's a hacky example on how you can implement Thread Local Storage, that's what it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment