precompile: fix a myriad of concurrency and cache handling mistakes (#59670)
* The PR for LOADING_CACHE failed to acquire the lock in many places it
was newly made mandatory.
* The stale_cache_key did not include many relevant parameters.
* The `isprecompiled` implementation failed to account for the preferred
stdlib logic of loading.
* The `isprecompiled` cache failed to account for either newly compiled
packages or other changes to the file system.
* After parallel precompile noticed a package fails, it would retry with
serial precompile, which was very pointless.
* Semaphore could be <= 0, leading to deadlock.
* After parallel precompile noticed a failure, it would crash, instead
of allowing the program to continue on to load the package normally. We
had tests for this, but they had gotten removed.