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-2016 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 % http://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 /* 40 Include declarations. 41 */ 42 #include "MagickCore/studio.h" 43 #include "MagickCore/memory_.h" 44 #include "MagickCore/thread_.h" 45 #include "MagickCore/thread-private.h" 46 47 /* 49 Typedef declarations. 50 */ 51 typedef struct _MagickThreadValue 52 { 53 size_t 54 number_threads; 55 56 void 57 **values, 58 (*destructor)(void *); 59 } MagickThreadValue; 60 61 /* 63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 % % 65 % % 66 % % 67 % C r e a t e M a g i c k T h r e a d K e y % 68 % % 69 % % 70 % % 71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 % 73 % CreateMagickThreadKey() creates a thread-specific data key visible to all 74 % threads in the process. 75 % 76 % The format of the CreateMagickThreadKey method is: 77 % 78 % MagickThreadKey CreateMagickThreadKey(MagickThreadKey *key) 79 % 80 % A description of each parameter follows: 81 % 82 % o key: opaque objects used to locate thread-specific data. 83 % 84 % o destructor: associate an optional destructor with each key value. 85 % 86 */ 87 MagickExport MagickBooleanType CreateMagickThreadKey(MagickThreadKey *key, 88 void (*destructor)(void *)) 89 { 90 #if defined(MAGICKCORE_THREAD_SUPPORT) 91 return(pthread_key_create(key,destructor) == 0 ? MagickTrue : MagickFalse); 92 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 93 magick_unreferenced(destructor); 94 *key=TlsAlloc(); 95 return(*key != TLS_OUT_OF_INDEXES ? MagickTrue : MagickFalse); 96 #else 97 { 98 MagickThreadValue 99 **keys; 100 101 keys=(MagickThreadValue **) key; 102 *keys=(MagickThreadValue *) AcquireQuantumMemory(1,sizeof(*keys)); 103 if (*keys != (MagickThreadValue *) NULL) 104 { 105 (*keys)->number_threads=GetOpenMPMaximumThreads(); 106 (*keys)->values=AcquireQuantumMemory((*keys)->number_threads, 107 sizeof(void *)); 108 if ((*keys)->values == (void *) NULL) 109 *keys=RelinquishMagickMemory(*keys); 110 else 111 (void) memset((*keys)->values,0,(*keys)->number_threads* 112 sizeof(void *)); 113 (*keys)->destructor=destructor; 114 } 115 return((*keys != (MagickThreadValue *) NULL) ? MagickTrue : MagickFalse); 116 } 117 #endif 118 } 119 120 /* 122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 123 % % 124 % % 125 % % 126 % D e l e t e M a g i c k T h r e a d K e y % 127 % % 128 % % 129 % % 130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 131 % 132 % DeleteMagickThreadKey() deletes a thread-specific data key. 133 % 134 % The format of the DeleteMagickThreadKey method is: 135 % 136 % MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key) 137 % 138 % A description of each parameter follows: 139 % 140 % o key: the thread key. 141 % 142 */ 143 MagickExport MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key) 144 { 145 #if defined(MAGICKCORE_THREAD_SUPPORT) 146 return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse); 147 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 148 return(TlsFree(key) != 0 ? MagickTrue : MagickFalse); 149 #else 150 { 151 MagickThreadValue 152 *keys; 153 154 register ssize_t 155 i; 156 157 keys=(MagickThreadValue *) key; 158 for (i=0; i < (ssize_t) keys->number_threads; i++) 159 if ((keys->destructor != (void *) NULL) && 160 (keys->values[i] != (void *) NULL)) 161 { 162 keys->destructor(keys->values[i]); 163 keys->values[i]=(void *) NULL; 164 } 165 keys=(MagickThreadValue *) RelinquishMagickMemory(keys); 166 } 167 return(MagickTrue); 168 #endif 169 } 170 171 /* 173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 174 % % 175 % % 176 % % 177 % G e t M a g i c k T h r e a d V a l u e % 178 % % 179 % % 180 % % 181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 182 % 183 % GetMagickThreadValue() returns the value currently bound to the specified 184 % key on behalf of the calling thread. 185 % 186 % The format of the GetMagickThreadValue method is: 187 % 188 % void *GetMagickThreadValue(MagickThreadKey key) 189 % 190 % A description of each parameter follows: 191 % 192 % o key: the thread key. 193 % 194 */ 195 MagickExport void *GetMagickThreadValue(MagickThreadKey key) 196 { 197 #if defined(MAGICKCORE_THREAD_SUPPORT) 198 return(pthread_getspecific(key)); 199 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 200 return(TlsGetValue(key)); 201 #else 202 { 203 MagickThreadValue 204 *keys; 205 206 keys=(MagickThreadValue *) key; 207 return(keys->values[GetOpenMPThreadId()]); 208 } 209 #endif 210 } 211 212 /* 214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 215 % % 216 % % 217 % % 218 % S e t M a g i c k T h r e a d V a l u e % 219 % % 220 % % 221 % % 222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 223 % 224 % SetMagickThreadValue() binds a value to the specified key on behalf of the 225 % calling thread. 226 % 227 % The format of the SetMagickThreadValue method is: 228 % 229 % MagickBooleanType SetMagickThreadValue(MagickThreadKey key, 230 % const void *value) 231 % 232 % A description of each parameter follows: 233 % 234 % o key: the thread key. 235 % 236 % o value: the value. 237 % 238 */ 239 MagickExport MagickBooleanType SetMagickThreadValue(MagickThreadKey key, 240 const void *value) 241 { 242 #if defined(MAGICKCORE_THREAD_SUPPORT) 243 return(pthread_setspecific(key,value) == 0 ? MagickTrue : MagickFalse); 244 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 245 return(TlsSetValue(key,(void *) value) != 0 ? MagickTrue : MagickFalse); 246 #else 247 { 248 MagickThreadValue 249 *keys; 250 251 keys=(MagickThreadValue *) key; 252 keys->values[GetOpenMPThreadId()]=(void *) value; 253 } 254 return(MagickTrue); 255 #endif 256 } 257