Home | History | Annotate | Download | only in MagickCore
      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