Home | History | Annotate | Download | only in MagickCore
      1 /*
      2   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
      3   dedicated to making software imaging solutions freely available.
      4 
      5   You may not use this file except in compliance with the License.  You may
      6   obtain a copy of the License at
      7 
      8     https://imagemagick.org/script/license.php
      9 
     10   Unless required by applicable law or agreed to in writing, software
     11   distributed under the License is distributed on an "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13   See the License for the specific language governing permissions and
     14   limitations under the License.
     15 
     16   MagickCore private methods for internal threading.
     17 */
     18 #ifndef MAGICKCORE_THREAD_PRIVATE_H
     19 #define MAGICKCORE_THREAD_PRIVATE_H
     20 
     21 #include "MagickCore/cache.h"
     22 #include "MagickCore/image-private.h"
     23 #include "MagickCore/resource_.h"
     24 #include "MagickCore/thread_.h"
     25 
     26 #if defined(__cplusplus) || defined(c_plusplus)
     27 extern "C" {
     28 #endif
     29 
     30 /*
     31   Number of threads bounded by the amount of work and any thread resource limit.
     32   The limit is 2 if the pixel cache type is not memory or memory-mapped.
     33 */
     34 #define magick_number_threads(source,destination,chunk,multithreaded) \
     35   num_threads((multithreaded) == 0 ? 1 : \
     36     ((GetImagePixelCacheType(source) != MemoryCache) && \
     37      (GetImagePixelCacheType(source) != MapCache)) || \
     38     ((GetImagePixelCacheType(destination) != MemoryCache) && \
     39      (GetImagePixelCacheType(destination) != MapCache)) ? \
     40     MagickMax(MagickMin(GetMagickResourceLimit(ThreadResource),2),1) : \
     41     MagickMax(MagickMin((ssize_t) GetMagickResourceLimit(ThreadResource),(ssize_t) (chunk)/64),1))
     42 
     43 #if defined(__clang__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 10))
     44 #define MagickCachePrefetch(address,mode,locality) \
     45   __builtin_prefetch(address,mode,locality)
     46 #else
     47 #define MagickCachePrefetch(address,mode,locality) \
     48   magick_unreferenced(address); \
     49   magick_unreferenced(mode); \
     50   magick_unreferenced(locality);
     51 #endif
     52 
     53 #if defined(MAGICKCORE_THREAD_SUPPORT)
     54   typedef pthread_mutex_t MagickMutexType;
     55 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
     56   typedef CRITICAL_SECTION MagickMutexType;
     57 #else
     58   typedef size_t MagickMutexType;
     59 #endif
     60 
     61 static inline MagickThreadType GetMagickThreadId(void)
     62 {
     63 #if defined(MAGICKCORE_THREAD_SUPPORT)
     64   return(pthread_self());
     65 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
     66   return(GetCurrentThreadId());
     67 #else
     68   return(getpid());
     69 #endif
     70 }
     71 
     72 static inline size_t GetMagickThreadSignature(void)
     73 {
     74 #if defined(MAGICKCORE_THREAD_SUPPORT)
     75   {
     76     union
     77     {
     78       pthread_t
     79         id;
     80 
     81       size_t
     82         signature;
     83     } magick_thread;
     84 
     85     magick_thread.signature=0UL;
     86     magick_thread.id=pthread_self();
     87     return(magick_thread.signature);
     88   }
     89 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
     90   return((size_t) GetCurrentThreadId());
     91 #else
     92   return((size_t) getpid());
     93 #endif
     94 }
     95 
     96 static inline MagickBooleanType IsMagickThreadEqual(const MagickThreadType id)
     97 {
     98 #if defined(MAGICKCORE_THREAD_SUPPORT)
     99   if (pthread_equal(id,pthread_self()) != 0)
    100     return(MagickTrue);
    101 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
    102   if (id == GetCurrentThreadId())
    103     return(MagickTrue);
    104 #else
    105   if (id == getpid())
    106     return(MagickTrue);
    107 #endif
    108   return(MagickFalse);
    109 }
    110 
    111 /*
    112   Lightweight OpenMP methods.
    113 */
    114 static inline size_t GetOpenMPMaximumThreads(void)
    115 {
    116 #if defined(MAGICKCORE_OPENMP_SUPPORT)
    117   return(omp_get_max_threads());
    118 #else
    119   return(1);
    120 #endif
    121 }
    122 
    123 static inline int GetOpenMPThreadId(void)
    124 {
    125 #if defined(MAGICKCORE_OPENMP_SUPPORT)
    126   return(omp_get_thread_num());
    127 #else
    128   return(0);
    129 #endif
    130 }
    131 
    132 static inline void SetOpenMPMaximumThreads(const int threads)
    133 {
    134 #if defined(MAGICKCORE_OPENMP_SUPPORT)
    135   omp_set_num_threads(threads);
    136 #else
    137   (void) threads;
    138 #endif
    139 }
    140 
    141 static inline void SetOpenMPNested(const int value)
    142 {
    143 #if defined(MAGICKCORE_OPENMP_SUPPORT)
    144   omp_set_nested(value);
    145 #else
    146   (void) value;
    147 #endif
    148 }
    149 
    150 #if defined(__cplusplus) || defined(c_plusplus)
    151 }
    152 #endif
    153 
    154 #endif
    155