MagickCore  7.1.0
Convert, Edit, Or Compose Bitmap Images
thread.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % TTTTT H H RRRR EEEEE AAA DDDD %
6 % T H H R R E A A D D %
7 % T HHHHH RRRR EEE AAAAA D D %
8 % T H H R R E A A D D %
9 % T H H R R EEEEE A A DDDD %
10 % %
11 % %
12 % MagickCore Thread Methods %
13 % %
14 % Software Design %
15 % Cristy %
16 % March 2003 %
17 % %
18 % %
19 % Copyright @ 2003 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 ␌
38 /*
39  Include declarations.
40 */
41 #include "MagickCore/studio.h"
42 #include "MagickCore/memory_.h"
43 #include "MagickCore/thread_.h"
44 #include "MagickCore/thread-private.h"
45 ␌
46 /*
47  Typedef declarations.
48 */
49 typedef struct _MagickThreadValue
50 {
51  size_t
52  number_threads;
53 
54  void
55  **values,
56  (*destructor)(void *);
58 ␌
59 /*
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61 % %
62 % %
63 % %
64 % C r e a t e M a g i c k T h r e a d K e y %
65 % %
66 % %
67 % %
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69 %
70 % CreateMagickThreadKey() creates a thread-specific data key visible to all
71 % threads in the process.
72 %
73 % The format of the CreateMagickThreadKey method is:
74 %
75 % MagickThreadKey CreateMagickThreadKey(MagickThreadKey *key)
76 %
77 % A description of each parameter follows:
78 %
79 % o key: opaque objects used to locate thread-specific data.
80 %
81 % o destructor: associate an optional destructor with each key value.
82 %
83 */
84 MagickExport MagickBooleanType CreateMagickThreadKey(MagickThreadKey *key,
85  void (*destructor)(void *))
86 {
87 #if defined(MAGICKCORE_THREAD_SUPPORT)
88  return(pthread_key_create(key,destructor) == 0 ? MagickTrue : MagickFalse);
89 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
90  magick_unreferenced(destructor);
91  *key=TlsAlloc();
92  return(*key != TLS_OUT_OF_INDEXES ? MagickTrue : MagickFalse);
93 #else
94  {
96  **keys;
97 
98  keys=(MagickThreadValue **) key;
99  *keys=(MagickThreadValue *) AcquireMagickMemory(sizeof(**keys));
100  if (*keys != (MagickThreadValue *) NULL)
101  {
102  (*keys)->number_threads=GetOpenMPMaximumThreads();
103  (*keys)->values=AcquireQuantumMemory((*keys)->number_threads,
104  sizeof(void *));
105  if ((*keys)->values == (void *) NULL)
106  *keys=RelinquishMagickMemory(*keys);
107  else
108  (void) memset((*keys)->values,0,(*keys)->number_threads*
109  sizeof(void *));
110  (*keys)->destructor=destructor;
111  }
112  return((*keys != (MagickThreadValue *) NULL) ? MagickTrue : MagickFalse);
113  }
114 #endif
115 }
116 ␌
117 /*
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119 % %
120 % %
121 % %
122 % D e l e t e M a g i c k T h r e a d K e y %
123 % %
124 % %
125 % %
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 %
128 % DeleteMagickThreadKey() deletes a thread-specific data key.
129 %
130 % The format of the DeleteMagickThreadKey method is:
131 %
132 % MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
133 %
134 % A description of each parameter follows:
135 %
136 % o key: the thread key.
137 %
138 */
139 MagickExport MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
140 {
141 #if defined(MAGICKCORE_THREAD_SUPPORT)
142  return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse);
143 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
144  return(TlsFree(key) != 0 ? MagickTrue : MagickFalse);
145 #else
146  {
148  *keys;
149 
150  ssize_t
151  i;
152 
153  keys=(MagickThreadValue *) key;
154  for (i=0; i < (ssize_t) keys->number_threads; i++)
155  if ((keys->destructor != (void *) NULL) &&
156  (keys->values[i] != (void *) NULL))
157  {
158  keys->destructor(keys->values[i]);
159  keys->values[i]=(void *) NULL;
160  }
161  keys=(MagickThreadValue *) RelinquishMagickMemory(keys);
162  }
163  return(MagickTrue);
164 #endif
165 }
166 ␌
167 /*
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 % %
170 % %
171 % %
172 % G e t M a g i c k T h r e a d V a l u e %
173 % %
174 % %
175 % %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 %
178 % GetMagickThreadValue() returns the value currently bound to the specified
179 % key on behalf of the calling thread.
180 %
181 % The format of the GetMagickThreadValue method is:
182 %
183 % void *GetMagickThreadValue(MagickThreadKey key)
184 %
185 % A description of each parameter follows:
186 %
187 % o key: the thread key.
188 %
189 */
190 MagickExport void *GetMagickThreadValue(MagickThreadKey key)
191 {
192 #if defined(MAGICKCORE_THREAD_SUPPORT)
193  return(pthread_getspecific(key));
194 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
195  return(TlsGetValue(key));
196 #else
197  {
199  *keys;
200 
201  keys=(MagickThreadValue *) key;
202  return(keys->values[GetOpenMPThreadId()]);
203  }
204 #endif
205 }
206 ␌
207 /*
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 % %
210 % %
211 % %
212 % S e t M a g i c k T h r e a d V a l u e %
213 % %
214 % %
215 % %
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 %
218 % SetMagickThreadValue() binds a value to the specified key on behalf of the
219 % calling thread.
220 %
221 % The format of the SetMagickThreadValue method is:
222 %
223 % MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
224 % const void *value)
225 %
226 % A description of each parameter follows:
227 %
228 % o key: the thread key.
229 %
230 % o value: the value.
231 %
232 */
233 MagickExport MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
234  const void *value)
235 {
236 #if defined(MAGICKCORE_THREAD_SUPPORT)
237  return(pthread_setspecific(key,value) == 0 ? MagickTrue : MagickFalse);
238 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
239  return(TlsSetValue(key,(void *) value) != 0 ? MagickTrue : MagickFalse);
240 #else
241  {
243  *keys;
244 
245  keys=(MagickThreadValue *) key;
246  keys->values[GetOpenMPThreadId()]=(void *) value;
247  }
248  return(MagickTrue);
249 #endif
250 }