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