'data' does not point to a floating point if that is what you mean. Instead it points to a signed 32-bit fixed point number which is converted to a float by casting and then dividing by the number FIXEDPOINT_FACTOR which is probably a power of two.
Ah yeah, that's what I meant I just wanted to get at the raw byte representation of those numbers.
@billyfysh I can't build that beast for win32 for now, as well as creating simple test cases, but if it auto-fixed by the compiler flags, then let it be, all fine :)
Currently, the more important problem is killthread() test not working, and I tried to deal with network-related code that crashes all ways around, which also may be affected by threading.
I will clean all the stuff and put changes on GitHub one by one, so everyone can see what was changed, etc and what bugs left, so it will be easier to follow.
There some progress: normal FreeType fonts now, and threaded curl working for listing for servers, etc (but still issues with connecting and creating own servers) (click open in new tab for fullsize):
But fighting for now with some Lua related (probably) issue. Maybe some of you can help with ideas as always.
So, visually issue happens like that: when we run the game, it on the running asks via AmigaDOS to "please insert volume" for 4 files:
See at the end of file ":", so that why AmigaDOS ask for insert volume. That means that at the end of files somewhere in the code added ":" for some unknown reassons.
Now the logic of the game there easy: if you have a base pack of game, or additional games created, game on the running checking firstly if we have for our created games any of those 4 files (and load them if we have), and, if not, fallback to "base" ones.
The issue is that everything works as expected, but we have those requesters. Files when need it found and used, and when not, then not, but in any case, we always had those requesters, and does not matter if files there, or not there. Like, it just some additional stuff happen somewhere.
After some good hours of debugging, find out that from where those functions in lua called, and find out where is roots are :
int main() { struct stat st{}; return (stat("work:aaaa",&st) == 0); }
with -lunix or without , it then works as expected, no requesters.
If we compile that code:
Quote:
#include <stdio.h> #include <sys/stat.h>
int main() { struct stat st{}; return (stat("/aaaa",&st) == 0); }
Without -lunix, it also ok. But if we compile it with -lunix, then it asks for "insert volume aaaa:".
Not sure if it should react like this? At least that -lunix stuff was to help to translate Unix style patches to amiga ones..
Edited by kas1e on 2021/1/11 22:05:55 Edited by kas1e on 2021/1/11 22:18:11 Edited by kas1e on 2021/1/11 22:21:56 Edited by kas1e on 2021/1/11 22:32:25 Edited by kas1e on 2021/1/11 22:34:02
It's usual AmigaOS/Unix/Win32 paths mess :) Just sometimes adding -lunix deal with everything, sometimes not. And when not, you had to go through code and fix it. Or when you didn't use -lunix fix even more.
For example for now, when I remove -lunix, then it failed to do "rename()".
Works when I compile it with -lunix, and didn't work when I compile it without -lunix. But it's pure amiga patches! How it can be that rename() didn't work when we didn't use Unix patches in and fail, like there is a wrong path? And that the same and for clib2 and for newlib.
So what to do then? Keep -linux and only workaround that "/" thing, or remove -linux, and fix one by one failed functions or whatever else where issues will popup.
With this particular "rename()" issue we can of course just use AmigaDOS Rename(), and be done with it, but is it anyway some issues in rename() implementation on both clib2 and newlib?
And by the way, seems DOS's Rename() can't overwrite a file, while clib2's and newlib's rename() can. I.e. if we have already "test.txt", and want rename some other file to "test.txt" it will not from DOS's Rename(), while clib/newlib's rename() will overwrite it.
Edited by kas1e on 2021/1/12 13:51:34 Edited by kas1e on 2021/1/12 13:54:06 Edited by kas1e on 2021/1/12 13:59:07
In end i think i better go the "amiga paths" way, i.e. removing -lunix from linking line and fix amiga paths.
There from begining bunch of little problems:
1. rename() function behave differently
-- it didn't delete an exiting file with the same name to which we tried to rename -- on posix 0 is return if succes, on amigados 0 is return if _NOT_ succes.
That how i deal with:
#ifdef __amigaos4__
// AmigaDOS's Rename didn't overwrite an exiting destination file, so we mimic unix way: where rename() also delete a existing file with the same name.
// On linux if rename() succes 0 is return, on AmigaDOS 0 return if rename is failed instead. So we spaw a logic a bit:
IDOS->Delete(path.c_str());
rename_success = IDOS->Rename(tmp_file.c_str(), path.c_str()) != 0;
if (!rename_success) {
warningstream << "Failed to write to file: " << path.c_str() << std::endl;
// Remove the temporary file because moving it over the target file
// failed.
remove(tmp_file.c_str());
return false;
}
#else
rename_success = rename(tmp_file.c_str(), path.c_str()) == 0;
if (!rename_success) {
warningstream << "Failed to write to file: " << path.c_str() << std::endl;
// Remove the temporary file because moving it over the target file
// failed.
remove(tmp_file.c_str());
return false;
}
#endif
2. There were some "double slashes" in the pathes, causing by the lua scripts in the parts which load menu's textures. I think at first to fix it in lua scripts, but fixing data files kind of suck, so instead i add in the menu loading textures functions that:
#ifdef __amigaos4__
// function to replace X amount of bytes in the buffer on Y amount of byte
std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}
#endif
And then, in the int ModApiMainMenu::l_set_background(lua_State *L)
.....bablla ......
if (!lua_isnone(L, 4)) {
minsize = lua_tonumber(L, 4);
}
#ifdef __amigaos4__
// fix "//" in the paths.
// when compiling withot -lunix (for use amigados native paths), then "//" things will handled wrong.
// so find out if we had "//" in the path and replace it with one "/"
@All After we can loads fine with no -lunix, and no requesters appear and all seems to works correctly (in the menu, at least), the real problem is left: I can't connect to any server (just disconnected), and can't create my own server (going to "wait for the threads" busy looping).
IMHO that all related to remaining threading issues, and even if not, IMHO first step is to solve an issue with KillThread() unit-tests, which is here:
So that what happen when we just tried to pass KillThread() test:
I put printfs all over the ways in test-function inself:
void TestThreading::testThreadKill()
{
SimpleTestThread *thread = new SimpleTestThread(300);
printf("1\n");
UASSERT(thread->start() == true);
// kill()ing is quite violent, so let's make sure our victim is sleeping
// before we do this... so we don't corrupt the rest of the program's state
printf("2\n");
sleep_ms(100);
printf("3\n");
UASSERT(thread->kill() == true);
printf("4\n");
// The state of the thread object should be reset if all went well
UASSERT(thread->isRunning() == false);
printf("5\n");
UASSERT(thread->start() == true);
printf("6\n");
UASSERT(thread->stop() == true);
printf("7\n");
UASSERT(thread->wait() == true);
printf("8\n");
// kill() after already waiting should fail.
UASSERT(thread->kill() == false);
delete thread;
}
What we see in the console output that it's: 1,2,3 and never 4 or more.
On the serial with adding prints to our threading implementation we have that:
Quote:
Before ObtainSemaphore in __gthread_create After ObtainSemaphore in __gthread_create after findtask + strcutprocess_userData , but before Wait for the parent task after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F) Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread Waiting for thread
... busy forever ...
All is see is that first UASSERT(thread->kill() == true); didn't works.
And as a result, we have there: 1,2,3, and never 4. So, join() fail, again our majesty join() :)
In summary what we have with that test: test start a thread, then wait a bit, and send kill. Kill is just called pthread_cancel and then call internal wait() which check: if not joinable, then return false, but if joinable then tried to join. And we fail to join there with our forever busy "waiting for a thread" from native implementation.
I rewrote my posix semaphore implementation as a static library so it can more easily be linked to a program and only the needed functions will be used.
To stop another thread in a clean way on AmigaOS requires co-operation from the thread that is to be stopped, but the kill operation has to do this by force because of how it is designed.
It would be better if MineCraft used a semaphore or other similar construct to signal the threads to stop and then used join to wait for them to end similar to the SimpleThreadTest here:
I rewrote my posix semaphore implementation as a static library so it can more easily be linked to a program and only the needed functions will be used.
Oh cool! Can be used and with c and with c++ I assume with no probs?
Quote:
To stop another thread in a clean way on AmigaOS requires co-operation from the thread that is to be stopped, but the kill operation has to do this by force because of how it is designed.
So they remove the whole "kill()", a test case for, but still as you can see keep that "pthread_chancle + wait()" at the end of the destructor, which means it will the same halt for us. Just with testkill() test, I assume it can be easier to check when it works...
I don't use the very latest code of Minecraft, as the last one brings some new errors, so I stick for now with 5.0.1, but can easily replace threading the same as they have in the latest code. But then, this "pthread_cancel(getThreadHandle()); + wait()" still in their destructor, so will hangs the same when they want to "kill" threads.
If you have an idea on how to rewrite their Thread::~Thread() (or whole threading.cpp) so it will works as need it on amigaos4, i surely can happy donate a bit with no probs :)
PS. I currently clone to my Github 5.0.1 version and start adding amigaos4 changes, so hope today/tomorrow will be at the same sync with my current local code, so everyone can see what i change and how code looks like , etc.
Added all the fixes and stuff, plz check the history of commits just to see what I change, etc. Also already used there -lpsem , and that much better indeed. Can you maybe upload it on os4depot as well, like a usual SDK (i.e. semaphore in the SDK/local/newlib/include, libpsem.a to SDK/local/newlib/lib) , so we can just write in the README.md about AmigaOS4 build instructions that posix-semaphore library need to be download from os4depot, etc.
The only 1 thing that remains to commit is changes about getting rid of ipv6 support + custom GAI code (for those getaddrinfo/freeaddrinfo, etc), so I want to make them clean and via #ifdef __ipv6_build__ so in the commit history everything will be visibly well, and we can see if it's me fucked up something with network code, or still some other work needs to be done. Hope to do it tomorrow, just to not mess things today.
@Salas00 I go a more easy way with network code: just added dummy defines/structs for ipv6, so code compiles without changes, just in one header file those dummies, see
In the config file of the game, we do have "enable_ipv6=false", so this code of no use, but everything compiles without too many ifdefs everywhere. At least for now, for a start.
I also had to use my own "gai" library to make freeaddr/getinfoaddr/gai_stderr/etc works.
Now, when i tried to connect to any server or create my own one, then 50% of times we simple lockup. And 50% of time, we crash in the resolve function:
Which can happen easily due to my custom "gai" library and maybe dues to the code itself (i don't like that part where they Address::serializeString()).
@salas00 After putting prinfs with delays to resolver function, it seems that this one is fine. Things just lockup (i.e. crashes on serial, but visully lockup, with almost no crashlog on serial, just a little bit). And on serial it looks like this:
Waiting for thread
Before ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
Waiting for thread
Before ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F)
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F)
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F)
kernel 54.31 (5.1.2021) AmigaOne X5000 release
Machine model: 9 (AmigaOne X5000/20)
Dump of context at 0xEFDFC3E0
Trap type: DSI exception
DSISR: 00800000 DAR: 0000636C
No matching page found
Machine State (raw): 0x0002F030
Machine State (verbose): [Critical Ints on] [ExtInt on] [User] [IAT on] [DAT on]
Instruction pointer: in module kernel+0x00052FD0 (0x01852FD0)
Crashed process: minetest (0x6802FD80)
DSI verbose error description: Access to address 0x0000636C not allowed by page protection in user state (protection violation)
Access was a store operation
Exception Syndrome Register: 0x00800000
0: 0184AA8C 6387CA10 00000002 00006368 0000000C 00000000 00000030 6387CAE0
8: 02231CC0 0000000C ABADCAFE 1515EF18 3B353935 63895E40 6387CCB8 6387CD48
16: 5FFF43BC 1515E360 FD209660 00000000 0223B136 02230000 02230000 02008418
24: 0239ECC2 02230000 EFFF6944 63707098 63837FDC 0000636C EFFF6900 0223A968
CR: 55353595 XER: A000007E CTR: 0000000C LR: 0184AAC8
Waiting for thread
Before ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
After ObtainSemaphore in __gthread_entry
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F)
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
after while with (SIGBREAKF_CTRL_F) & SIGBREAKF_CTRL_F)
Before ObtainSemaphore in __gthread_create
after findtask + strcutprocess_userData , but before Wait for the parent task
After ObtainSemaphore in __gthread_create
kernel 54.31 (5.1.2021) AmigaOne X5000 release
Machine model: 9 (AmigaOne X5000/20)
Dump of context at 0xEFDFC3E0
Trap type: DSI exception
DSISR: 00800000 DAR: 00006F8B
No matching page found
Machine State (raw): 0x0002F030
Machine State (verbose): [Critical Ints on] [ExtInt on] [User] [IAT on] [DAT on]
Instruction pointer: in module kernel+0x00052FD0 (0x01852FD0)
Crashed process: minetest (0x6802FD80)
DSI verbose error description: Access to address 0x00006F8B not allowed by page protection in user state (protection violation)
Access was a store operation
Exception Syndrome Register: 0x00800000
0: 0184AA8C 63897410 00000002 00006F87 0000000C 00000000 00000030 638974E0
8: 02231CC0 0000000C ABADCAFE 8000000F 37355595 638AFE40 63763863 00000003
16: FFFFFFFF 63763840 63763862 00000000 0223B136 02230000 02230000 02008418
24: 0239ECC2 02230000 EFFF6944 6F8BF510 63852FDC 00006F8B EFFF6900 0223A968
CR: 55353595 XER: A000007E CTR: 0000000C LR: 0184AAC8
And seems for each operation it spawn a thread, etc. So after the "resolving" thread finished (and with correct values) it should start to connect to the server, but fail for some reasons (and as I can see, quite random ones, which may prove that there mess with threads going on).
So now everyone can build it once meet the requirements.
The only problem now is all that network code. Maybe in end, it's all matter of the src/network/connectionthreads.cpp ?
Just strange why it that randomly crashes/lockups when about to create a server or to connect to a server (so after resolve done, and then). And what I noticed that when I put Delays() to Resolve() when checking it, those Delays make Resolve() not crashes. Like, separate threads don't interact well with together and didn't know what/when one finished. But that only a guess...
I even tried to replace all sys/socket.h includes to sys/bsdsocket.h in all the source files in whole Minecraft code, so to use directly roadshow and not newlib, but still have exactly the same issues.
Wow ! Great... Is this project usable/able to run or near of? My kid is looking for minecraft-like game... Unfortunately ami x5k is mounted in his room
@Arthas Currently, we stuck on the issues with the threaded network code, and I need some help there from more skilled programmers.
In meanwhile there 2 Minecraft kind games already available for us: Barony port and AmiCraft. Through, of course, both of them not of the Minecraft quality
@Sinan The reason for this is that I for time being use my own "gai" link library which just contain those functions:
getaddrinfo() freeaddrinfo() gai_errror() + additional inet_aton() and inet_ntop()
I use my own one because os4 ones cause crashes which I report some time ago (issue happens with both, pure socket usage from newlib and with direct bsdsocket.library usage). I reported them, but not sure if Olaf fixed it or will fix, and even if, when it will be released. When I made the repo there was a hope it will be fixed/released in the public update, but probably not.
So will update the repo or upload libgai.a on os4depot in next days.