/src/imagemagick/MagickCore/thread.c
Line | Count | Source |
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 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/license/ % |
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 *); |
57 | | } MagickThreadValue; |
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 | 16 | { |
87 | 16 | #if defined(MAGICKCORE_THREAD_SUPPORT) |
88 | 16 | 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 | | { |
95 | | MagickThreadValue |
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=(void **) AcquireQuantumMemory((*keys)->number_threads, |
104 | | sizeof(void *)); |
105 | | if ((*keys)->values == (void **) NULL) |
106 | | *keys=(MagickThreadValue *) 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 | 16 | } |
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 | 0 | { |
141 | 0 | #if defined(MAGICKCORE_THREAD_SUPPORT) |
142 | 0 | return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse); |
143 | | #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
144 | | return(TlsFree(key) != 0 ? MagickTrue : MagickFalse); |
145 | | #else |
146 | | { |
147 | | MagickThreadValue |
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 | 0 | } |
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 | 15.5M | { |
192 | 15.5M | #if defined(MAGICKCORE_THREAD_SUPPORT) |
193 | 15.5M | return(pthread_getspecific(key)); |
194 | | #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
195 | | return(TlsGetValue(key)); |
196 | | #else |
197 | | { |
198 | | MagickThreadValue |
199 | | *keys; |
200 | | |
201 | | keys=(MagickThreadValue *) key; |
202 | | return(keys->values[GetOpenMPThreadId()]); |
203 | | } |
204 | | #endif |
205 | 15.5M | } |
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 | 133k | { |
236 | 133k | #if defined(MAGICKCORE_THREAD_SUPPORT) |
237 | 133k | 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 | | { |
242 | | MagickThreadValue |
243 | | *keys; |
244 | | |
245 | | keys=(MagickThreadValue *) key; |
246 | | keys->values[GetOpenMPThreadId()]=(void *) value; |
247 | | } |
248 | | return(MagickTrue); |
249 | | #endif |
250 | 133k | } |