1 /*
2 Copyright 1999-2021 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 #define magick_number_threads(source,destination,chunk,multithreaded) \
31 num_threads(GetMagickNumberThreads(source,destination,chunk,multithreaded))
32 #if defined(__clang__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 10))
33 #define MagickCachePrefetch(address,mode,locality) \
34 __builtin_prefetch(address,mode,locality)
35 #else
36 #define MagickCachePrefetch(address,mode,locality) \
37 magick_unreferenced(address); \
38 magick_unreferenced(mode); \
39 magick_unreferenced(locality);
40 #endif
41
42 #if defined(MAGICKCORE_THREAD_SUPPORT)
43 typedef pthread_mutex_t MagickMutexType;
44 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
45 typedef CRITICAL_SECTION MagickMutexType;
46 #else
47 typedef size_t MagickMutexType;
48 #endif
49
GetMagickNumberThreads(const Image * source,const Image * destination,const size_t chunk,int multithreaded)50 static inline int GetMagickNumberThreads(const Image *source,
51 const Image *destination,const size_t chunk,int multithreaded)
52 {
53 /*
54 Number of threads bounded by the amount of work and any thread resource
55 limit. The limit is 2 if the pixel cache type is not memory or
56 memory-mapped.
57 */
58 if (multithreaded == 0)
59 return(1);
60 if (((GetImagePixelCacheType(source) != MemoryCache) &&
61 (GetImagePixelCacheType(source) != MapCache)) ||
62 ((GetImagePixelCacheType(destination) != MemoryCache) &&
63 (GetImagePixelCacheType(destination) != MapCache)))
64 return((int) MagickMax(MagickMin(GetMagickResourceLimit(ThreadResource),2),1));
65 return((int) MagickMax(MagickMin((ssize_t) GetMagickResourceLimit(
66 ThreadResource),(ssize_t) (chunk)/64),1));
67 }
68
GetMagickThreadId(void)69 static inline MagickThreadType GetMagickThreadId(void)
70 {
71 #if defined(MAGICKCORE_THREAD_SUPPORT)
72 return(pthread_self());
73 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
74 return(GetCurrentThreadId());
75 #else
76 return(getpid());
77 #endif
78 }
79
GetMagickThreadSignature(void)80 static inline size_t GetMagickThreadSignature(void)
81 {
82 #if defined(MAGICKCORE_THREAD_SUPPORT)
83 {
84 union
85 {
86 pthread_t
87 id;
88
89 size_t
90 signature;
91 } magick_thread;
92
93 magick_thread.signature=0UL;
94 magick_thread.id=pthread_self();
95 return(magick_thread.signature);
96 }
97 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
98 return((size_t) GetCurrentThreadId());
99 #else
100 return((size_t) getpid());
101 #endif
102 }
103
IsMagickThreadEqual(const MagickThreadType id)104 static inline MagickBooleanType IsMagickThreadEqual(const MagickThreadType id)
105 {
106 #if defined(MAGICKCORE_THREAD_SUPPORT)
107 if (pthread_equal(id,pthread_self()) != 0)
108 return(MagickTrue);
109 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
110 if (id == GetCurrentThreadId())
111 return(MagickTrue);
112 #else
113 if (id == getpid())
114 return(MagickTrue);
115 #endif
116 return(MagickFalse);
117 }
118
119 /*
120 Lightweight OpenMP methods.
121 */
GetOpenMPMaximumThreads(void)122 static inline size_t GetOpenMPMaximumThreads(void)
123 {
124 #if defined(MAGICKCORE_OPENMP_SUPPORT)
125 return(omp_get_max_threads());
126 #else
127 return(1);
128 #endif
129 }
130
GetOpenMPThreadId(void)131 static inline int GetOpenMPThreadId(void)
132 {
133 #if defined(MAGICKCORE_OPENMP_SUPPORT)
134 return(omp_get_thread_num());
135 #else
136 return(0);
137 #endif
138 }
139
SetOpenMPMaximumThreads(const int threads)140 static inline void SetOpenMPMaximumThreads(const int threads)
141 {
142 #if defined(MAGICKCORE_OPENMP_SUPPORT)
143 omp_set_num_threads(threads);
144 #else
145 (void) threads;
146 #endif
147 }
148
SetOpenMPNested(const int value)149 static inline void SetOpenMPNested(const int value)
150 {
151 #if defined(MAGICKCORE_OPENMP_SUPPORT)
152 omp_set_nested(value);
153 #else
154 (void) value;
155 #endif
156 }
157
158 #if defined(__cplusplus) || defined(c_plusplus)
159 }
160 #endif
161
162 #endif
163