Kaydet (Commit) 0d4204e8 authored tarafından Giuseppe Bilotta's avatar Giuseppe Bilotta Kaydeden (comit) Tor Lillqvist

OpenCL: correctly handle platforms without devices

When an OpenCL platform has no devices (of the requested type), calls to
clGetDeviceIDs() are required to return with the error value
CL_DEVICE_NOT_FOUND.

Some platforms (e.g. Clover as of Mesa 10.4.2) do not touch their output
parameters in such cases, which means that in some conditions the `num`
variable where the number of devices of the platform should be stored
may be used uninitialized. This can lead to segmentations faults in the
subsequent calls to clGetDeviceInfo().

Simply reinitializing num to 0 is sufficient to prevent the segfault in
the case of Mesa, but proper error handling is included for
completeness.

Change-Id: Ia25192f6aa953838a545a9e7c9fca050d2703b60
Reviewed-on: https://gerrit.libreoffice.org/14700Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTor Lillqvist <tml@collabora.com>
üst 142094e7
......@@ -121,8 +121,17 @@ inline ds_status initDSProfile(ds_profile** p, const char* version)
numDevices = 0;
for (i = 0; i < (unsigned int)numPlatforms; i++)
{
cl_uint num;
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num);
cl_uint num = 0;
cl_int err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num);
if (err != CL_SUCCESS)
{
/* we want to catch at least the case when the call returns
* CL_DEVICE_NOT_FOUND (i.e. no devices), because some platforms
* don't set num to 0 in this case; but in fact this is a good
* thing to do for _any_ error returned by the call
*/
num = 0;
}
numDevices += num;
}
if (numDevices != 0)
......@@ -148,12 +157,21 @@ inline ds_status initDSProfile(ds_profile** p, const char* version)
next = 0;
for (i = 0; i < (unsigned int)numPlatforms; i++)
{
cl_uint num;
cl_uint num = 0;
unsigned j;
char vendor[256];
if (clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL) != CL_SUCCESS)
vendor[0] = '\0';
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices, devices, &num);
cl_int err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices, devices, &num);
if (err != CL_SUCCESS)
{
/* we want to catch at least the case when the call returns
* CL_DEVICE_NOT_FOUND (i.e. no devices), because some platforms
* don't set num to 0 in this case; but in fact this is a good
* thing to do for _any_ error returned by the call
*/
num = 0;
}
for (j = 0; j < num; j++, next++)
{
char buffer[DS_DEVICE_NAME_LENGTH];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment