by means other than OpenCL.
Do this using the Mac 'system_profiler' program, as suggested by Charlie.
Also:
- improve the comments in GPU detection code.
For something this complex, we need, at the minimum,
a comment saying what each function does.
- avoid field names like 'version' and 'name'.
Version of what? name of what?
For now, it's detected only via OpenCL (like Intel GPUs).
Eventually we'll detect via Metal as well.
Plan classes for Apple GPU must include 'apple_gpu' in their name.
The changes are mostly copy-and-paste of Intel GPU code.
I hate duplicate code but I don't know how to fix.
The client runs two "detection processes":
- GPU detection
- (Mac) check if in CPU emulation mode
The client was waiting indefinitely for these to exit.
If for some reason they don't exit, the client hangs.
Fix: wait no more than 10 sec for them to exit.
If still running, kill them and move on.
I took the opportunity to clean up the process-related code:
- add a time arg to get_exit_status().
If zero, wait indefinitely for the child to exit.
Else wait no more than that amount.
- get_exit_status() return an error code;
the exit status is returned via a parameter.
- run_program() no longer takes a time argument.
If you want to check for early exit, use get_exit_status()
- define PROCESS_ID as HANDLE (Win) or int (other)
so we can unify the process interface
- remove process_exists(). It wasn't used anywhere,
and get_exit_status(... 0) does the same thing.
- rename kill_program() to kill_process()
- don't use "prog" when you mean "pid"
lib/util.cpp had become a landfill of unrelated stuff
- move the process-related code to lib/proc_control.cpp
- move file-related code to lib/filesys.cpp
- move client mutex code to client/main.cpp
The client has 2 unrelated types of mutual exclusion:
thread level (between the main and throttle threads)
and process level (prevent 2 clients from running on a host).
- Rename "client_mutex" to "client_thread_mutex".
- parse.h: don't declare boinc_is_finite(); include the .h file
PR #3364 changed the way we clear structures.
This introduced a bug: HOST_INFO::clear_host_info()
intentionally didn't clear HOST_INFO::coprocs.
But it was replaced with HOST_INFO::clear(), which did.
This caused the client to lose GPU info.
Fix: restore HOST_INFO::clear_host_info(), and add a comment
to avoid future errors like this.
Also add some comments in GPU detection,
which is woefully lacking in them.
Instead: declare a static const instance (whose data members are zero)
and copy that.
This avoid the error-prone need to assign each member,
and it works even if there are virtual function tables.
Client path was quoted because on Windows run_program() concatenates
arguments to a single string. Without quoting any path with a space
would cause problems interpreting the command line.
What run_program() does with its parameters is really an implementation
detail of it and users of run_program() shouldn't need to know or care
about it.
Moving quoting into run_program() also removes the need to duplicate
quoting everywhere run_program() is used.
The program name or path to it needs to be valid filesystem name and
it's always the first in argv so quoting it in run_program() is trivial.
run_program() doesn't know which other arguments may contain paths and
quoting arbitrary arguments is harder so keep quoted_data_dir for now.
GPU detection code goes back and forth between program and data
directories but this is unnecessary because run_program() already takes
care of running the program in correct directory.
Fixes two "ignoring return value" warnings from GCC/GLIBC.
On Unixes, if GPU detection fails the client logs an error message
containing a raw value from waitpid() call. This raw value generally
requires writing an external program to decode it before it is useful
for troubleshooting.
Decode the raw value to something more useful to humans. Make a similar
change to Windows code too.
GPU detection tries to launch a copy of the client using argv[0] but
argv[0] doesn't always include path. If path is not included and current
directory is not the same as BOINC program directory then the GPU
detection fails.
Use full path to the client executable instead if possible. Quote the
path on Windows to handle paths with spaces.
Better for the debug version to do the same thing as release.
There's a #define you can change if you want GPU detection to happen in the main process.
We were using an int bitmap to store flags for the instances of a coproc.
Furthermore, because of the use of 2^n-1 to generate a bitmap of 1s,
the limit on instances was 31.
Use a long long for the bitmap instead, and don't use 2^n-1.
This increases the limit to 64.
For now, handle AMD/ATI, NVIDIA or Intel GPUs as before. But for other, "new" vendors, we treat each device as a separate resource, creating an entry for each instance in the COPROCS::coprocs[] array and copying the device name COPROC::opencl_prop.name into the COPROC::type field (instead of the vendor name.)
For devices from "new" vendors, set <gpu_type> field in init_data.xml file to the vendor string supplied by OpenCL. This should allow boinc_get_opencl_ids() to work correctly with these "new" devices without modification.