27 June 2009
I'm puzzled by a few serious but not reproducible errors. The first one occurred many years ago and had to do with the collection of variables during compiling. Another bug occurred in compiling GLLs where the compiler complained about not being able to open the file to save the GLL. Again, another bug complained not being able to initialize a Hash table in a GLL. However, the bug didn't present itself each time the GLL was started. Then there is the bug where a subroutine call in a 22000 line program wouldn't compile because of a variable collection/initialization error. Why aren't these bugs reported more often? They seem to come up only occasionally. I'm starting to think the problem is related to thread-safety errors. The compiler intensively uses functions from the runtime GfaWin23.Ocx, especially the Hash functions. Everything the compiler collects, names, types, data, etc is stored in Hash tables. The Hash tables are actually pointers to a structure with pointers to allocated memory. There is a pointer to an array of strings containing the hash key name, a pointer to an array of data, an array of indices mapping the key to an index, and some more. To create a Hash table the runtime DLL must support thread safety, because another process/thread can not interfere with the allocation of a Hash table. I am not able to conclude that the Ocx is fully thread-safe in this respect. I have seen a lot of thread-protection functions in the runtime disassembly, but they are mostly string related. The Hash functions on the other hand don't provide a locking mechanism. The documentation (Multithread.pdf) states that GFA-BASIC 32 is not completely "reentrant". However which functions suffer from the lack of reentrancy isn't reported. Since these bugs only occur occasionally I wonder if this has to do with two or more threads executing a runtime function the same time. For instance, I believe the Val() function isn't thread-safe (I'm not sure, because it is hard to tell). But what if two processes or threads were calling it the same time? In the early days of the Microsoft C run-time library, math routines were nonnreentrant aswell, and accordingly did not save and restore the registers used on the 80x87 floating-point coprocessor. Why wouldn't GFA-BASIC 32 suffer the same? It didn't get tested that well. Maybe somebody may recognize these contemplations and may tell us about it.