]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/cache.c
(no commit message)
[imagemagick] / MagickCore / cache.c
index 26ba6744e4366401dee5760f214cf8bf95373cb7..204f129f03ed9f1dddf050e671bd168ca9c14c09 100644 (file)
 %                       MagickCore Pixel Cache Methods                        %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1999                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -201,9 +201,9 @@ MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
       cache_info->synchronize=IsStringTrue(synchronize);
       synchronize=DestroyString(synchronize);
     }
-  cache_info->semaphore=AllocateSemaphoreInfo();
+  cache_info->semaphore=AcquireSemaphoreInfo();
   cache_info->reference_count=1;
-  cache_info->file_semaphore=AllocateSemaphoreInfo();
+  cache_info->file_semaphore=AcquireSemaphoreInfo();
   cache_info->debug=IsEventLogging();
   cache_info->signature=MagickSignature;
   return((Cache ) cache_info);
@@ -324,7 +324,8 @@ MagickPrivate const void *AcquirePixelCachePixels(const Image *image,
 */
 MagickPrivate MagickBooleanType CacheComponentGenesis(void)
 {
-  AcquireSemaphoreInfo(&cache_semaphore);
+  if (cache_semaphore == (SemaphoreInfo *) NULL)
+    cache_semaphore=AcquireSemaphoreInfo();
   return(MagickTrue);
 }
 \f
@@ -349,11 +350,11 @@ MagickPrivate MagickBooleanType CacheComponentGenesis(void)
 MagickPrivate void CacheComponentTerminus(void)
 {
   if (cache_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&cache_semaphore);
+    ActivateSemaphoreInfo(&cache_semaphore);
   LockSemaphoreInfo(cache_semaphore);
   instantiate_cache=MagickFalse;
   UnlockSemaphoreInfo(cache_semaphore);
-  DestroySemaphoreInfo(&cache_semaphore);
+  RelinquishSemaphoreInfo(&cache_semaphore);
 }
 \f
 /*
@@ -470,6 +471,29 @@ MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
 %
 */
 
+static inline void CopyPixels(Quantum *destination,const Quantum *source,
+  const MagickSizeType number_pixels)
+{
+#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
+  (void) memcpy(destination,source,(size_t) number_pixels*sizeof(*source));
+#else
+  {
+    register MagickOffsetType
+      i;
+
+    if ((number_pixels*sizeof(*source)) < MagickMaxBufferExtent)
+      {
+        (void) memcpy(destination,source,(size_t) number_pixels*
+          sizeof(*source));
+        return;
+      }
+    #pragma omp parallel for
+    for (i=0; i < (MagickOffsetType) number_pixels; i++)
+      destination[i]=source[i];
+  }
+#endif
+}
+
 static inline MagickSizeType MagickMin(const MagickSizeType x,
   const MagickSizeType y)
 {
@@ -516,26 +540,8 @@ static MagickBooleanType ClonePixelCacheRepository(
       (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
       (cache_info->metacontent_extent == clone_info->metacontent_extent))
     {
-      size_t
-        extent;
-
-      /*
-        Identical pixel cache morphology.
-      */
-      extent=cache_info->columns*cache_info->number_channels*cache_info->rows;
-#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
-      (void) memcpy(clone_info->pixels,cache_info->pixels,extent*
-        sizeof(*cache_info->pixels));
-#else
-      {
-        register size_t
-          i;
-
-        #pragma omp parallel for
-        for (i=0; i < extent; i++)
-          clone_info->pixels[i]=cache_info->pixels[i];
-      }
-#endif
+      CopyPixels(clone_info->pixels,cache_info->pixels,cache_info->columns*
+        cache_info->number_channels*cache_info->rows);
       if (cache_info->metacontent_extent != 0)
         (void) memcpy(clone_info->metacontent,cache_info->metacontent,
           cache_info->columns*cache_info->rows*clone_info->metacontent_extent*
@@ -595,6 +601,7 @@ static MagickBooleanType ClonePixelCacheRepository(
       clone_nexus[id],exception);
     if (pixels == (Quantum *) NULL)
       continue;
+    (void) ResetMagickMemory(clone_nexus[id]->pixels,0,clone_nexus[id]->length);
     if (optimize != MagickFalse)
       (void) memcpy(clone_nexus[id]->pixels,cache_nexus[id]->pixels,length*
         sizeof(Quantum));
@@ -681,8 +688,10 @@ static MagickBooleanType ClonePixelCacheRepository(
           clone_nexus[id],exception);
         if (pixels == (Quantum *) NULL)
           continue;
-        (void) memcpy(clone_nexus[id]->metacontent,cache_nexus[id]->metacontent,
-          length*sizeof(cache_nexus[id]->metacontent));
+        if (clone_nexus[id]->metacontent != (void *) NULL)
+          (void) memcpy(clone_nexus[id]->metacontent,
+            cache_nexus[id]->metacontent,length*
+            sizeof(cache_nexus[id]->metacontent));
         status=WritePixelCacheMetacontent(clone_info,clone_nexus[id],exception);
       }
     }
@@ -824,15 +833,17 @@ static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
         cache_info->pixels=(Quantum *) RelinquishAlignedMemory(
           cache_info->pixels);
       else
-        cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,
-          (size_t) cache_info->length);
+        {
+          (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+          cache_info->pixels=(Quantum *) NULL;
+        }
       RelinquishMagickResource(MemoryResource,cache_info->length);
       break;
     }
     case MapCache:
     {
-      cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,(size_t)
-        cache_info->length);
+      (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+      cache_info->pixels=(Quantum *) NULL;
       if (cache_info->mode != ReadMode)
         (void) RelinquishUniqueFileResource(cache_info->cache_filename);
       *cache_info->cache_filename='\0';
@@ -901,9 +912,9 @@ MagickPrivate Cache DestroyPixelCache(Cache cache)
   if (cache_info->random_info != (RandomInfo *) NULL)
     cache_info->random_info=DestroyRandomInfo(cache_info->random_info);
   if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->file_semaphore);
+    RelinquishSemaphoreInfo(&cache_info->file_semaphore);
   if (cache_info->semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->semaphore);
+    RelinquishSemaphoreInfo(&cache_info->semaphore);
   cache_info->signature=(~MagickSignature);
   cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
   cache=(Cache) NULL;
@@ -1478,7 +1489,12 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
     }
   if ((time_limit != MagickResourceInfinity) &&
       ((MagickSizeType) (time((time_t *) NULL)-cache_timestamp) >= time_limit))
-    ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+     {
+#if defined(ECANCELED)
+       errno=ECANCELED;
+#endif
+       ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+     }
   assert(image->cache != (Cache) NULL);
   cache_info=(CacheInfo *) image->cache;
   destroy=MagickFalse;
@@ -1497,7 +1513,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
             Clone pixel cache.
           */
           clone_image=(*image);
-          clone_image.semaphore=AllocateSemaphoreInfo();
+          clone_image.semaphore=AcquireSemaphoreInfo();
           clone_image.reference_count=1;
           clone_image.cache=ClonePixelCache(cache_info);
           clone_info=(CacheInfo *) clone_image.cache;
@@ -1515,7 +1531,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
                   image->cache=clone_image.cache;
                 }
             }
-          DestroySemaphoreInfo(&clone_image.semaphore);
+          RelinquishSemaphoreInfo(&clone_image.semaphore);
         }
       UnlockSemaphoreInfo(cache_info->semaphore);
     }
@@ -3176,6 +3192,21 @@ static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
     }
 }
 
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(SIGBUS)
+static void CacheSignalHandler(int status)
+{
+  ThrowFatalException(CacheFatalError,"UnableToExtendPixelCache");
+}
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
 static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
   const MapMode mode)
 {
@@ -3299,6 +3330,9 @@ static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
       if (status != 0)
         return(MagickFalse);
     }
+#endif
+#if defined(SIGBUS)
+  (void) signal(SIGBUS,CacheSignalHandler);
 #endif
   return(count != (MagickOffsetType) 1 ? MagickFalse : MagickTrue);
 }
@@ -3480,6 +3514,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               return(MagickTrue);
             }
         }
+      RelinquishMagickResource(DiskResource,cache_info->length);
       (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
         "CacheResourcesExhausted","`%s'",image->filename);
       return(MagickFalse);