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/* 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*/ 49typedef 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*/ 84MagickExport 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 { 95 MagickThreadValue 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*/ 139MagickExport 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 { 147 MagickThreadValue 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 } 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*/ 190MagickExport 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 { 198 MagickThreadValue 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*/ 233MagickExport 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 { 242 MagickThreadValue 243 *keys; 244 245 keys=(MagickThreadValue *) key; 246 keys->values[GetOpenMPThreadId()]=(void *) value; 247 } 248 return(MagickTrue); 249#endif 250} 251