modules/th/thread.c

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

FUNCTIONS

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.26 $
   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                              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 #include <pthread.h>       /* Posix thread library */
  44 #include <stdio.h>
  45 #include <strings.h>
  46 
  47 #include "thread.h"
  48 /* #include "socket.h"
  49 #include "protocol_whois.h"
  50 #include "protocol_config.h"
  51 #include "protocol_mirror.h"
  52 #include "constants.h"
  53 #include "server.h"
  54 */
  55 #include "memwrap.h"
  56 
  57 
  58 /*+ String sizes +*/
  59 #define STR_S   63
  60 #define STR_M   255
  61 #define STR_L   1023
  62 #define STR_XL  4095
  63 #define STR_XXL 16383
  64 
  65 //typedef struct th_args {
  66 //      void *function;
  67 //      int sock;
  68 //} th_args;
  69 
  70 /*************************************************
  71 *                                                *
  72 *     Readers Writes Locks that favor READERS    *
  73 *                                                *
  74 *************************************************/
  75 /* TH_acquire_read_lock() */
  76 /*++++++++++++++++++++++++++++++++++++++
  77 
  78   Aquire a readers lock.
  79 
  80   rw_lock_t *prw_lock Readers writers lock.
  81 
  82   Reference: "Multithreaded Programming Techniques - Prasad p.192"
  83   More:
  84   +html+ <PRE>
  85   Author:
  86         ottrey
  87   +html+ </PRE>
  88   ++++++++++++++++++++++++++++++++++++++*/
  89 void TH_acquire_read_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
  90   pthread_mutex_lock(&prw_lock->rw_mutex);
  91 
  92   while (prw_lock->rw_count < 0) {
  93     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
  94   }
  95 
  96   ++prw_lock->rw_count;
  97   pthread_mutex_unlock(&prw_lock->rw_mutex);
  98 
  99 } /* TH_acquire_read_lock() */
 100 
 101 /* TH_release_read_lock() */
 102 /*++++++++++++++++++++++++++++++++++++++
 103 
 104   Release a readers lock.
 105 
 106   rw_lock_t *prw_lock Readers writers lock.
 107 
 108   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 109   More:
 110   +html+ <PRE>
 111   Author:
 112         ottrey
 113   +html+ </PRE>
 114   ++++++++++++++++++++++++++++++++++++++*/
 115 void TH_release_read_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 116   pthread_mutex_lock(&prw_lock->rw_mutex);
 117 
 118   --prw_lock->rw_count;
 119 
 120   if (!prw_lock->rw_count) {
 121     pthread_cond_signal(&prw_lock->rw_cond);
 122   }
 123 
 124   pthread_mutex_unlock(&prw_lock->rw_mutex);
 125 
 126 } /* TH_release_read_lock() */
 127 
 128 /* TH_acquire_write_lock() */
 129 /*++++++++++++++++++++++++++++++++++++++
 130 
 131   Aquire a writers lock.
 132 
 133   rw_lock_t *prw_lock Readers writers lock.
 134 
 135   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 136   More:
 137   +html+ <PRE>
 138   Author:
 139         ottrey
 140   +html+ </PRE>
 141   ++++++++++++++++++++++++++++++++++++++*/
 142 void TH_acquire_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 143   pthread_mutex_lock(&prw_lock->rw_mutex);
 144 
 145   while (prw_lock->rw_count != 0) {
 146     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
 147   }
 148 
 149   prw_lock->rw_count = -1;
 150   pthread_mutex_unlock(&prw_lock->rw_mutex);
 151 
 152 } /* TH_acquire_write_lock() */
 153 
 154 /* TH_release_write_lock() */
 155 /*++++++++++++++++++++++++++++++++++++++
 156 
 157   Release a writers lock.
 158 
 159   rw_lock_t *prw_lock Readers writers lock.
 160 
 161   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 162   More:
 163   +html+ <PRE>
 164   Author:
 165         ottrey
 166   +html+ </PRE>
 167   ++++++++++++++++++++++++++++++++++++++*/
 168 void TH_release_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 169   pthread_mutex_lock(&prw_lock->rw_mutex);
 170   prw_lock->rw_count = 0;
 171   pthread_mutex_unlock(&prw_lock->rw_mutex);
 172   pthread_cond_broadcast(&prw_lock->rw_cond);
 173 
 174 } /* TH_release_write_lock() */
 175 
 176 /* TH_init_read_write_lock() */
 177 /*++++++++++++++++++++++++++++++++++++++
 178 
 179   Initialize a readers/writers lock.
 180 
 181   rw_lock_t *prw_lock Readers writers lock.
 182 
 183   Side effect: the lock is set to open(?)
 184 
 185   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 186   More:
 187   +html+ <PRE>
 188   Author:
 189         ottrey
 190   +html+ </PRE>
 191   ++++++++++++++++++++++++++++++++++++++*/
 192 void TH_init_read_write_lock(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 193   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
 194   pthread_cond_init(&prw_lock->rw_cond, NULL);
 195   pthread_cond_init(&prw_lock->w_cond, NULL);
 196   prw_lock->rw_count = 0;
 197   prw_lock->w_count = 1; /* just in case one uses wrong interface */
 198 
 199 } /* TH_init_read_write_lock() */
 200 
 201 /*************************************************
 202 *                                                *
 203 *     Readers Writes Locks that favor WRITERS    *
 204 *                                                *
 205 *************************************************/
 206 /* TH_acquire_read_lockw() */
 207 /*++++++++++++++++++++++++++++++++++++++
 208 
 209   Aquire a readers lock.
 210 
 211   rw_lock_t *prw_lock Readers writers lock.
 212 
 213   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 214   More:
 215   +html+ <PRE>
 216   Author:
 217         ottrey
 218   +html+ </PRE>
 219   ++++++++++++++++++++++++++++++++++++++*/
 220 void TH_acquire_read_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 221   pthread_mutex_lock(&prw_lock->rw_mutex);
 222 
 223   while (prw_lock->w_count != 0) {
 224     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
 225   }
 226 
 227   ++prw_lock->rw_count;
 228   pthread_mutex_unlock(&prw_lock->rw_mutex);
 229 
 230 } /* TH_acquire_read_lockw() */
 231 
 232 /* TH_release_read_lockw() */
 233 /*++++++++++++++++++++++++++++++++++++++
 234 
 235   Release a readers lock.
 236 
 237   rw_lock_t *prw_lock Readers writers lock.
 238 
 239   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 240   More:
 241   +html+ <PRE>
 242   Author:
 243         ottrey
 244   +html+ </PRE>
 245   ++++++++++++++++++++++++++++++++++++++*/
 246 void TH_release_read_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 247   pthread_mutex_lock(&prw_lock->rw_mutex);
 248 
 249   --prw_lock->rw_count;
 250 
 251   if (!prw_lock->rw_count) {
 252     pthread_cond_signal(&prw_lock->rw_cond);
 253   }
 254 
 255   pthread_mutex_unlock(&prw_lock->rw_mutex);
 256 
 257 } /* TH_release_read_lockw() */
 258 
 259 /* TH_acquire_write_lockw() */
 260 /*++++++++++++++++++++++++++++++++++++++
 261 
 262   Aquire a writers lock.
 263 
 264   rw_lock_t *prw_lock Readers writers lock.
 265 
 266   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 267   More:
 268   +html+ <PRE>
 269   Author:
 270         ottrey
 271   +html+ </PRE>
 272   ++++++++++++++++++++++++++++++++++++++*/
 273 void TH_acquire_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 274   pthread_mutex_lock(&prw_lock->rw_mutex);
 275 
 276  /* check for writers */
 277   while (prw_lock->w_count != 0) {
 278     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
 279   }
 280 
 281   prw_lock->w_count = 1;
 282  
 283  /* wait until all readers are gone */
 284   while (prw_lock->rw_count != 0) {
 285     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
 286   }
 287  
 288   pthread_mutex_unlock(&prw_lock->rw_mutex);
 289 
 290 } /* TH_acquire_write_lockw() */
 291 
 292 /* TH_release_write_lockw() */
 293 /*++++++++++++++++++++++++++++++++++++++
 294 
 295   Release a writers lock.
 296 
 297   rw_lock_t *prw_lock Readers writers lock.
 298 
 299   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 300   More:
 301   +html+ <PRE>
 302   Author:
 303         ottrey
 304   +html+ </PRE>
 305   ++++++++++++++++++++++++++++++++++++++*/
 306 void TH_release_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 307   pthread_mutex_lock(&prw_lock->rw_mutex);
 308   prw_lock->w_count = 0;
 309   pthread_mutex_unlock(&prw_lock->rw_mutex);
 310   pthread_cond_broadcast(&prw_lock->w_cond);
 311 
 312 } /* TH_release_write_lockw() */
 313 
 314 /* TH_init_read_write_lockw() */
 315 /*++++++++++++++++++++++++++++++++++++++
 316 
 317   Initialize a readers/writers lock.
 318 
 319   rw_lock_t *prw_lock Readers writers lock.
 320 
 321   Side effect: the lock is set to open(?)
 322 
 323   Reference: "Multithreaded Programming Techniques - Prasad p.192"
 324   More:
 325   +html+ <PRE>
 326   Author:
 327         ottrey
 328   +html+ </PRE>
 329   ++++++++++++++++++++++++++++++++++++++*/
 330 void TH_init_read_write_lockw(rw_lock_t *prw_lock) { 
     /* [<][>][^][v][top][bottom][index][help] */
 331   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
 332   pthread_cond_init(&prw_lock->rw_cond, NULL);
 333   pthread_cond_init(&prw_lock->w_cond, NULL);
 334   prw_lock->rw_count = 0;
 335   prw_lock->w_count = 0;
 336 
 337 } /* TH_init_read_write_lockw() */
 338 
 339 
 340 
 341 /*************************************************
 342 *                                                *
 343 *     Other functions                            *
 344 *                                                *
 345 *************************************************/
 346 
 347 
 348 int TH_get_id(void) {
     /* [<][>][^][v][top][bottom][index][help] */
 349 
 350   return (int)pthread_self();
 351 
 352 } /* TH_get_id() */
 353 
 354 /* TH_to_string() */
 355 char *TH_to_string(void) {
     /* [<][>][^][v][top][bottom][index][help] */
 356   char *thread_info;
 357   char tmp[STR_L];
 358   char thread_info_buffer[STR_XL];
 359 
 360   strcpy(thread_info_buffer, "Thread = { ");
 361 
 362   sprintf(tmp, "[pthread_self] = \"%d\" ", pthread_self());
 363   strcat(thread_info_buffer, tmp);
 364   
 365   /*
 366   thread_name = (char *)pthread_getspecific(Name);
 367 
 368   if (thread_name == NULL ) {
 369     sprintf(tmp, "[Name] = \"%s\" ", "didn't work!");
 370   }
 371   else {
 372     sprintf(tmp, "[Name] = \"%s\" ", thread_name);
 373   }
 374   strcat(thread_info_buffer, tmp);
 375   */
 376   
 377   strcat(thread_info_buffer, "}");
 378   
 379   dieif( wr_malloc((void **)&thread_info, 
 380                    strlen(thread_info_buffer)+1) != UT_OK);  
 381 
 382   strcpy(thread_info, thread_info_buffer);
 383 
 384   return thread_info;
 385 } /* TH_to_string() */
 386 
 387 
 388 /*++++++++++++++++++++++++++++++++++++++
 389 
 390   This is the routine that creates a thread. 
 391 
 392    More:
 393   +html+ <PRE>
 394   Author:
 395         ottrey
 396         joao
 397         andrei
 398   +html+ </PRE>
 399   ++++++++++++++++++++++++++++++++++++++*/
 400 pthread_t TH_create(void *do_function(void *), void *arguments ) {
     /* [<][>][^][v][top][bottom][index][help] */
 401   pthread_t tid;
 402   pthread_attr_t attr;
 403   size_t ssize;
 404   int ret;
 405 
 406     /* Start a new thread. */
 407     pthread_attr_init(&attr);     /* initialize attr with default attributes */
 408     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 409 
 410 #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
 411     defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
 412     /*********
 413       For SCO, we need to increase the stack size, because the default is
 414       exceedingly small.  This also works on FreeBSD.  In Solaris, the
 415       stack size is 0, which is interpreted as the default, meaning 1
 416       Mbyte for 32-bit processes or 2 Mbyte for 64-bit processes.
 417       However, trying to *set* the stack size to 0 results in an error.
 418       Therefore, we don't want to set the size to 0.  Probably not a good
 419       idea in any event.  :) Linux doesn't support this function (as of
 420       the 2.4.2 kernel).
 421 
 422       Note: see also modules/sk/cd_watchdog.c
 423      *********/
 424     dieif(pthread_attr_getstacksize(&attr, &ssize) != 0);
 425     if (ssize > 0) {
 426         dieif(pthread_attr_setstacksize(&attr, ssize * 4) != 0);
 427     }
 428 #endif
 429 
 430     ret = pthread_create(&tid, &attr, do_function, arguments);
 431     if( ret !=0 ) die;
 432     pthread_attr_destroy(&attr);
 433 
 434     return tid;
 435 
 436 } /* TH_run() */
 437 
 438 
 439 

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