GraphicsMagick 的 OpenCL 开发记录(十七)

文章目录

  • 关于`LiberateMagickResource()`的闪退问题(一)
  • 关于`LiberateMagickResource()`的闪退问题(二)
  • 关于`LiberateMagickResource()`的闪退问题(三)

<2022-04-02 Sat>

关于LiberateMagickResource()的闪退问题(一)

我正在处理所有标注了TODO(ocl)的代码,在DestroyMagickCLCacheInfoAndPixels()函数里的代码:

// RelinquishMagickResource(MemoryResource,info->length); // TODO(ocl)
DestroyMagickCLCacheInfo(info);
// (void) RelinquishAlignedMemory(pixels); // TODO(ocl)

我这样处理之后:

// RelinquishMagickResource(MemoryResource,info->length);
LiberateMagickResource(MemoryResource,info->length);
DestroyMagickCLCacheInfo(info);
// (void) RelinquishAlignedMemory(pixels);
MagickFreeAlignedMemory(pixels);

程序闪退,打印的信息如下:

$ gm display ~/temp/1.png
gm display: abort due to signal 11 (SIGSEGV) "Segmentation Fault"...
Aborted (core dumped)

确认起因是因为使用了LiberateMagickResource(MemoryResource,info->length);这行代码。经过调试发现在GetAuthenticOpenCLBuffer()函数返回NULL后程序闪退。具体代码是:

if ((cache_info->type != MemoryCache)/*  || (cache_info->mapped != MagickFalse) */)
  return((cl_mem) NULL);

我这样修改好像不闪退了:

if ((cache_info->type != MemoryCache) || (cache_info->type != MapCache))
  return((cl_mem) NULL);

目前尚未理解LiberateMagickResource(MemoryResource,info->length);的用意,及像上面这样修改会不会引发什么新的问题。

注:必须清除.cache/ImageMagick里的所有文件才能出现闪退问题,即在跑openclbenchmark时会出现。

<2022-04-03 Sun>

关于LiberateMagickResource()的闪退问题(二)

理解了一下GraphicsMagickAcquireMagickResource()LiberateMagickResource()函数,它们实际上起到监视的作用,没有分配和释放资源的功能,包括InitializeMagickResources()函数,初始化内存分配的上限,磁盘上限等等,可以通过比如MAGICK_LIMIT_MEMORYMAGICK_LIMIT_DISK等环境变量来设置。

调试发现当在DestroyMagickCLCacheInfoAndPixels()函数中使用LiberateMagickResource()后:

// LiberateMagickResource()

case SummationLimit:
  {
    /*
      Limit depends on sum of previous allocations as well as
      the currently requested size.
    */
    LockSemaphoreInfo(info->semaphore);
    info->value-=size;
    value=info->value;
    UnlockSemaphoreInfo(info->semaphore);
    break;
  }

中的info->value-=size;可能会变成负值,这样的话,再次调用AcquireMagickResource()时可能返回失败,即:

// AcquireMagickResource()

case SummationLimit:
  {
    /*
      Limit depends on sum of previous allocations as well as
      the currently requested size.
    */
    LockSemaphoreInfo(info->semaphore);
    value=info->value+size;
    if ((info->maximum != ResourceInfinity) &&
        (value > (magick_uint64_t) info->maximum))
      {
        value=info->value;
        status=MagickFail;
      }
    else
      {
        info->value=value;
      }
    UnlockSemaphoreInfo(info->semaphore);
    break;
  }

这里的if分支,这样的话,需要找到为什么LiberateMagickResource()会将info->value的值搞成负数?

<2022-04-06 Wed>

关于LiberateMagickResource()的闪退问题(三)

info->value的值之所以为负数,原因其实很简单,不是AcquireMagickResource()调少了,就是LiberateMagickResource()调多了。

最终还是解决了这个问题,又是一个低级错误,一个自己给自己挖的坑,原ImageMagick中的代码是:

// IM's RelinquishPixelCachePixels()

#if defined(MAGICKCORE_OPENCL_SUPPORT)
      if (cache_info->opencl != (MagickCLCacheInfo) NULL)
        {
          cache_info->opencl=RelinquishMagickCLCacheInfo(cache_info->opencl,
            MagickTrue);
          cache_info->pixels=(Quantum *) NULL;
          break;
        }
#endif

这里的break;是关键。

你可能感兴趣的:(GraphicsMagick,的,OpenCL,开发,GraphicsMagick,ImageMagick,OpenCL,c++)