modules/th/thread.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. TH_acquire_read_lock
  2. TH_release_read_lock
  3. TH_acquire_write_lock
  4. TH_release_write_lock
  5. TH_init_read_write_lock
  6. TH_acquire_read_lockw
  7. TH_release_read_lockw
  8. TH_acquire_write_lockw
  9. TH_release_write_lockw
  10. TH_init_read_write_lockw
  11. TH_get_id
  12. TH_to_string
  13. TH_create

   1 /***************************************
   2   $Revision: 1.30 $
   3 
   4   Example code: A thread.
   5 
   6   Status: NOT REVUED, NOT TESTED
   7 
   8  Authors:       Chris Ottrey
   9                 Joao Damas
  10 
  11   +html+ <DL COMPACT>
  12   +html+ <DT>Online References:
  13   +html+ <DD><UL>
  14   +html+ </UL>
  15   +html+ </DL>
  16  
  17   ******************/ /******************
  18   Modification History:
  19         ottrey (02/03/1999) Created.
  20         ottrey (08/03/1999) Modified.
  21         ottrey (17/06/1999) Stripped down.
  22         joao   (22/06/1999) Redid thread startup
  23   ******************/ /******************
  24   Copyright (c) 1999,2000,2001,2002               RIPE NCC
  25  
  26   All Rights Reserved
  27   
  28   Permission to use, copy, modify, and distribute this software and its
  29   documentation for any purpose and without fee is hereby granted,
  30   provided that the above copyright notice appear in all copies and that
  31   both that copyright notice and this permission notice appear in
  32   supporting documentation, and that the name of the author not be
  33   used in advertising or publicity pertaining to distribution of the
  34   software without specific, written prior permission.
  35   
  36   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  37   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  38   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  39   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  40   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  41   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  42   ***************************************/
  43 
  44 #include "rip.h"
  45 
  46 #include <pthread.h>       /* Posix thread library */
  47 #include <stdio.h>
  48 #include <strings.h>
  49 
  50 //typedef struct th_args {
  51 //      void *function;
  52 //      int sock;
  53 //} th_args;
  54 
  55 /*************************************************
  56 *                                                *
  57 *     Readers Writes Locks that favor READERS    *
  58 *                                                *
  59 *************************************************/
  60 /* TH_acquire_read_lock() */
  61 /*++++++++++++++++++++++++++++++++++++++
  62 
  63   Aquire a readers lock.
  64 
  65   rw_lock_t *prw_lock Readers writers lock.
  66 
  67   Reference: "Multithreaded Programming Techniques - Prasad p.192"
  68   More:
  69   +html+ <PRE>
  70   Author:
  71         ottrey
  72   +html+ </PRE>
  73   ++++++++++++++++++++++++++++++++++++++*/
  74 void TH_acquire_read_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
  75   pthread_mutex_lock(&prw_lock->rw_mutex);
  76 
  77   while (prw_lock->rw_count < 0) {
  78     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
  79   }
  80 
  81   ++prw_lock->rw_count;
  82   pthread_mutex_unlock(&prw_lock->rw_mutex);
  83 
  84 } /* TH_acquire_read_lock() */
  85 
  86 /* TH_release_read_lock() */
  87 /*++++++++++++++++++++++++++++++++++++++
  88 
  89   Release a readers lock.
  90 
  91   rw_lock_t *prw_lock Readers writers lock.
  92 
  93   Reference: "Multithreaded Programming Techniques - Prasad p.192"
  94   More:
  95   +html+ <PRE>
  96   Author:
  97         ottrey
  98   +html+ </PRE>
  99   ++++++++++++++++++++++++++++++++++++++*/
 100 void TH_release_read_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 101   pthread_mutex_lock(&prw_lock->rw_mutex);
 102 
 103   --prw_lock->rw_count;
 104 
 105   if (!prw_lock->rw_count) {
 106     pthread_cond_signal(&prw_lock->rw_cond);
 107   }
 108 
 109   pthread_mutex_unlock(&prw_lock->rw_mutex);
 110 
 111 } /* TH_release_read_lock() */
 112 
 113 /* TH_acquire_write_lock() */
 114 /*++++++++++++++++++++++++++++++++++++++
 115 
 116   Aquire a writers lock.
 117 
 118   rw_lock_t *prw_lock Readers writers lock.
 119 
 120   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 121   More:
 122   +html+ <PRE>
 123   Author:
 124         ottrey
 125   +html+ </PRE>
 126   ++++++++++++++++++++++++++++++++++++++*/
 127 void TH_acquire_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 128   pthread_mutex_lock(&prw_lock->rw_mutex);
 129 
 130   while (prw_lock->rw_count != 0) {
 131     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
 132   }
 133 
 134   prw_lock->rw_count = -1;
 135   pthread_mutex_unlock(&prw_lock->rw_mutex);
 136 
 137 } /* TH_acquire_write_lock() */
 138 
 139 /* TH_release_write_lock() */
 140 /*++++++++++++++++++++++++++++++++++++++
 141 
 142   Release a writers lock.
 143 
 144   rw_lock_t *prw_lock Readers writers lock.
 145 
 146   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 147   More:
 148   +html+ <PRE>
 149   Author:
 150         ottrey
 151   +html+ </PRE>
 152   ++++++++++++++++++++++++++++++++++++++*/
 153 void TH_release_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 154   pthread_mutex_lock(&prw_lock->rw_mutex);
 155   prw_lock->rw_count = 0;
 156   pthread_mutex_unlock(&prw_lock->rw_mutex);
 157   pthread_cond_broadcast(&prw_lock->rw_cond);
 158 
 159 } /* TH_release_write_lock() */
 160 
 161 /* TH_init_read_write_lock() */
 162 /*++++++++++++++++++++++++++++++++++++++
 163 
 164   Initialize a readers/writers lock.
 165 
 166   rw_lock_t *prw_lock Readers writers lock.
 167 
 168   Side effect: the lock is set to open(?)
 169 
 170   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 171   More:
 172   +html+ <PRE>
 173   Author:
 174         ottrey
 175   +html+ </PRE>
 176   ++++++++++++++++++++++++++++++++++++++*/
 177 void TH_init_read_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 178   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
 179   pthread_cond_init(&prw_lock->rw_cond, NULL);
 180   pthread_cond_init(&prw_lock->w_cond, NULL);
 181   prw_lock->rw_count = 0;
 182   prw_lock->w_count = 1; /* just in case one uses wrong interface */
 183 
 184 } /* TH_init_read_write_lock() */
 185 
 186 /*************************************************
 187 *                                                *
 188 *     Readers Writes Locks that favor WRITERS    *
 189 *                                                *
 190 *************************************************/
 191 /* TH_acquire_read_lockw() */
 192 /*++++++++++++++++++++++++++++++++++++++
 193 
 194   Aquire a readers lock.
 195 
 196   rw_lock_t *prw_lock Readers writers lock.
 197 
 198   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 199   More:
 200   +html+ <PRE>
 201   Author:
 202         ottrey
 203   +html+ </PRE>
 204   ++++++++++++++++++++++++++++++++++++++*/
 205 void TH_acquire_read_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 206   pthread_mutex_lock(&prw_lock->rw_mutex);
 207 
 208   while (prw_lock->w_count != 0) {
 209     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
 210   }
 211 
 212   ++prw_lock->rw_count;
 213   pthread_mutex_unlock(&prw_lock->rw_mutex);
 214 
 215 } /* TH_acquire_read_lockw() */
 216 
 217 /* TH_release_read_lockw() */
 218 /*++++++++++++++++++++++++++++++++++++++
 219 
 220   Release a readers lock.
 221 
 222   rw_lock_t *prw_lock Readers writers lock.
 223 
 224   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 225   More:
 226   +html+ <PRE>
 227   Author:
 228         ottrey
 229   +html+ </PRE>
 230   ++++++++++++++++++++++++++++++++++++++*/
 231 void TH_release_read_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 232   pthread_mutex_lock(&prw_lock->rw_mutex);
 233 
 234   --prw_lock->rw_count;
 235 
 236   if (!prw_lock->rw_count) {
 237     pthread_cond_signal(&prw_lock->rw_cond);
 238   }
 239 
 240   pthread_mutex_unlock(&prw_lock->rw_mutex);
 241 
 242 } /* TH_release_read_lockw() */
 243 
 244 /* TH_acquire_write_lockw() */
 245 /*++++++++++++++++++++++++++++++++++++++
 246 
 247   Aquire a writers lock.
 248 
 249   rw_lock_t *prw_lock Readers writers lock.
 250 
 251   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 252   More:
 253   +html+ <PRE>
 254   Author:
 255         ottrey
 256   +html+ </PRE>
 257   ++++++++++++++++++++++++++++++++++++++*/
 258 void TH_acquire_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 259   pthread_mutex_lock(&prw_lock->rw_mutex);
 260 
 261  /* check for writers */
 262   while (prw_lock->w_count != 0) {
 263     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
 264   }
 265 
 266   prw_lock->w_count = 1;
 267  
 268  /* wait until all readers are gone */
 269   while (prw_lock->rw_count != 0) {
 270     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
 271   }
 272  
 273   pthread_mutex_unlock(&prw_lock->rw_mutex);
 274 
 275 } /* TH_acquire_write_lockw() */
 276 
 277 /* TH_release_write_lockw() */
 278 /*++++++++++++++++++++++++++++++++++++++
 279 
 280   Release a writers lock.
 281 
 282   rw_lock_t *prw_lock Readers writers lock.
 283 
 284   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 285   More:
 286   +html+ <PRE>
 287   Author:
 288         ottrey
 289   +html+ </PRE>
 290   ++++++++++++++++++++++++++++++++++++++*/
 291 void TH_release_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 292   pthread_mutex_lock(&prw_lock->rw_mutex);
 293   prw_lock->w_count = 0;
 294   pthread_mutex_unlock(&prw_lock->rw_mutex);
 295   pthread_cond_broadcast(&prw_lock->w_cond);
 296 
 297 } /* TH_release_write_lockw() */
 298 
 299 /* TH_init_read_write_lockw() */
 300 /*++++++++++++++++++++++++++++++++++++++
 301 
 302   Initialize a readers/writers lock.
 303 
 304   rw_lock_t *prw_lock Readers writers lock.
 305 
 306   Side effect: the lock is set to open(?)
 307 
 308   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 309   More:
 310   +html+ <PRE>
 311   Author:
 312         ottrey
 313   +html+ </PRE>
 314   ++++++++++++++++++++++++++++++++++++++*/
 315 void TH_init_read_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 316   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
 317   pthread_cond_init(&prw_lock->rw_cond, NULL);
 318   pthread_cond_init(&prw_lock->w_cond, NULL);
 319   prw_lock->rw_count = 0;
 320   prw_lock->w_count = 0;
 321 
 322 } /* TH_init_read_write_lockw() */
 323 
 324 
 325 
 326 /*************************************************
 327 *                                                *
 328 *     Other functions                            *
 329 *                                                *
 330 *************************************************/
 331 
 332 
 333 int TH_get_id(void) {
     /* [<][>][^][v][top][bottom][index][help] */
 334 
 335   return (int)pthread_self();
 336 
 337 } /* TH_get_id() */
 338 
 339 /* TH_to_string() */
 340 char *TH_to_string(void) {
     /* [<][>][^][v][top][bottom][index][help] */
 341   char tmp[STR_L];
 342   char thread_info_buffer[STR_XL];
 343 
 344   strcpy(thread_info_buffer, "Thread = { ");
 345 
 346   sprintf(tmp, "[pthread_self] = \"%lu\" ", (long unsigned)pthread_self());
 347   strcat(thread_info_buffer, tmp);
 348   
 349   /*
 350   thread_name = (char *)pthread_getspecific(Name);
 351 
 352   if (thread_name == NULL ) {
 353     sprintf(tmp, "[Name] = \"%s\" ", "didn't work!");
 354   }
 355   else {
 356     sprintf(tmp, "[Name] = \"%s\" ", thread_name);
 357   }
 358   strcat(thread_info_buffer, tmp);
 359   */
 360   
 361   strcat(thread_info_buffer, "}");
 362   
 363   return UT_strdup(thread_info_buffer);
 364 } /* TH_to_string() */
 365 
 366 
 367 /*++++++++++++++++++++++++++++++++++++++
 368 
 369   This is the routine that creates a thread. 
 370 
 371    More:
 372   +html+ <PRE>
 373   Author:
 374         ottrey
 375         joao
 376         andrei
 377   +html+ </PRE>
 378   ++++++++++++++++++++++++++++++++++++++*/
 379 pthread_t TH_create(void *do_function(void *), void *arguments ) {
     /* [<][>][^][v][top][bottom][index][help] */
 380   pthread_t tid;
 381   pthread_attr_t attr;
 382   size_t ssize;
 383   int ret;
 384 
 385     /* Start a new thread. */
 386     pthread_attr_init(&attr);     /* initialize attr with default attributes */
 387     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 388 
 389 #if defined(SCO)
 390     /*********
 391       For SCO, we need to increase the stack size, because the default is
 392       exceedingly small.
 393 
 394       Note: see also modules/sk/cd_watchdog.c
 395      *********/
 396     dieif(pthread_attr_getstacksize(&attr, &ssize) != 0);
 397     if (ssize > 0) {
 398         dieif(pthread_attr_setstacksize(&attr, ssize * 4) != 0);
 399     }
 400 #endif
 401 
 402     ret = pthread_create(&tid, &attr, do_function, arguments);
 403     if( ret !=0 ) die;
 404     pthread_attr_destroy(&attr);
 405 
 406     return tid;
 407 
 408 } /* TH_run() */
 409 
 410 
 411 

/* [<][>][^][v][top][bottom][index][help] */