## 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.29 $
       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(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
     390     defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
     391     /*********
     392       For SCO, we need to increase the stack size, because the default is
     393       exceedingly small.  This also works on FreeBSD.  In Solaris, the
     394       stack size is 0, which is interpreted as the default, meaning 1
     395       Mbyte for 32-bit processes or 2 Mbyte for 64-bit processes.
     396       However, trying to *set* the stack size to 0 results in an error.
     397       Therefore, we don't want to set the size to 0.  Probably not a good
     398       idea in any event.  :) Linux doesn't support this function (as of
     399       the 2.4.2 kernel).
     400
     401       Note: see also modules/sk/cd_watchdog.c
     402      *********/
     403     dieif(pthread_attr_getstacksize(&attr, &ssize) != 0);
     404     if (ssize > 0) {
     405         dieif(pthread_attr_setstacksize(&attr, ssize * 4) != 0);
     406     }
     407 #endif
     408
     409     ret = pthread_create(&tid, &attr, do_function, arguments);
     410     if( ret !=0 ) die;
     411     pthread_attr_destroy(&attr);
     412
     413     return tid;
     414
     415 } /* TH_run() */
     416
     417
     418

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