• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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