summaryrefslogtreecommitdiff
path: root/opencl
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2015-03-02 00:09:29 +0100
committerTor Lillqvist <tml@collabora.com>2015-03-02 11:24:08 +0000
commit0d4204e87f89839ee0b4ca33e1684626599e4315 (patch)
treef178541435598490b00f72c55b5da5426d80ecc7 /opencl
parent142094e78b82b4b4417ed0ef6d6698a40ee5f96f (diff)
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/14700 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tor Lillqvist <tml@collabora.com>
Diffstat (limited to 'opencl')
-rw-r--r--opencl/inc/opencl_device_selection.h26
1 files changed, 22 insertions, 4 deletions
diff --git a/opencl/inc/opencl_device_selection.h b/opencl/inc/opencl_device_selection.h
index 7e0754b4d1bc..14ec814682f3 100644
--- a/opencl/inc/opencl_device_selection.h
+++ b/opencl/inc/opencl_device_selection.h
@@ -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];