MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
thread.c
Go to the documentation of this file.
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 1999-2018 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://www.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"
45 
46 /*
47  Typedef declarations.
48 */
49 typedef struct _MagickThreadValue
50 {
51  size_t
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 */
85  void (*destructor)(void *))
86 {
87 #if defined(MAGICKCORE_THREAD_SUPPORT)
89 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
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 *) AcquireQuantumMemory(1,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 */
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  register 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  }
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 */
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 */
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 }
size_t number_threads
Definition: thread.c:52
#define pthread_key_create
Definition: vms.h:817
#define pthread_key_delete
Definition: vms.h:818
static size_t GetOpenMPMaximumThreads(void)
#define pthread_getspecific
Definition: vms.h:813
struct _MagickThreadValue MagickThreadValue
void ** values
Definition: thread.c:55
void(* destructor)(void *)
Definition: thread.c:56
MagickBooleanType
Definition: magick-type.h:156
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
static int GetOpenMPThreadId(void)
void * MagickThreadKey
Definition: thread_.h:42
MagickExport MagickBooleanType CreateMagickThreadKey(MagickThreadKey *key, void(*destructor)(void *))
Definition: thread.c:84
#define pthread_setspecific
Definition: vms.h:843
MagickExport void * GetMagickThreadValue(MagickThreadKey key)
Definition: thread.c:190
MagickExport MagickBooleanType SetMagickThreadValue(MagickThreadKey key, const void *value)
Definition: thread.c:233
MagickExport MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
Definition: thread.c:139
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
#define magick_unreferenced(x)
#define MagickExport