modules/ta/ta.c

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

FUNCTIONS

This source file includes following functions.
  1. ta_findonly_l
  2. ta_findcreate_l
  3. ta_remove_l
  4. ta_setactivity_l
  5. ta_print_header
  6. ta_printone_l
  7. TA_add
  8. TA_delete
  9. TA_setactivity
  10. TA_setcondat
  11. TA_increment
  12. TA_reset_counters
  13. TA_tostring
  14. TA_trigger

   1 /***************************************
   2   $Revision: 1.10 $
   3 
   4   thread accounting (ta). ta.c - functions to keep track of activities
   5                             of threads within the server
   6 
   7   Status: NOT REVUED, TESTED, COMPLETE
   8 
   9   Design and implementation by: Marek Bukowy
  10 
  11   ******************/ /******************
  12   Copyright (c) 1999,2000,2001                    RIPE NCC
  13  
  14   All Rights Reserved
  15   
  16   Permission to use, copy, modify, and distribute this software and its
  17   documentation for any purpose and without fee is hereby granted,
  18   provided that the above copyright notice appear in all copies and that
  19   both that copyright notice and this permission notice appear in
  20   supporting documentation, and that the name of the author not be
  21   used in advertising or publicity pertaining to distribution of the
  22   software without specific, written prior permission.
  23   
  24   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  25   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  26   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  27   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  28   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  29   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30   ***************************************/
  31 
  32 #define TA_IMPL
  33 #include "rip.h"
  34 
  35 
  36 /*++++++++++++++++++++++++++++++++++++++
  37 
  38   Finds a thread by thread_id. Assumes locked list.
  39 
  40   ta_str_t *ta_findonly_l     returns a pointer to the thread's record
  41 
  42   GList **list                thread list
  43 
  44   pthread_t thread_id         thread id
  45 
  46   ++++++++++++++++++++++++++++++++++++++*/
  47 static
  48 ta_str_t *ta_findonly_l( GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  49 {
  50   GList *item;
  51 
  52   /* try to find first */
  53   for(item = g_list_first(*list);
  54       item != NULL;
  55       item = g_list_next(item)) {
  56     ta_str_t *tas = (ta_str_t *) (item->data);
  57 
  58     if( tas->thread_id == thread_id ) {
  59       return tas;
  60     }
  61   }
  62   return NULL;
  63 }
  64 
  65 
  66 /*++++++++++++++++++++++++++++++++++++++
  67 
  68   Finds a thread by thread_id, or creates a new entry if there isn't one.
  69   Assumes locked list.
  70 
  71   ta_str_t *ta_findcreate_l   returns a pointer to the thread's record
  72 
  73   GList **list                thread list
  74 
  75   pthread_t thread_id         thread id
  76 
  77   ++++++++++++++++++++++++++++++++++++++*/
  78 static
  79 ta_str_t *ta_findcreate_l( GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81   ta_str_t *newtas;
  82 
  83   if( (newtas = ta_findonly_l(list, thread_id)) == NULL) {
  84     
  85     /* not found => add */  /* zero everything*/
  86     newtas = (ta_str_t *)UT_calloc(1, sizeof(ta_str_t));
  87     newtas->thread_id = thread_id;
  88     
  89     *list = g_list_append( *list, newtas );
  90   }
  91 
  92   return newtas;
  93 }
  94 
  95 
  96 
  97 /*++++++++++++++++++++++++++++++++++++++
  98   
  99   finds and removes an entry for a thread given by thread_id.
 100   Assumes locked list.
 101 
 102   GList **list                thread list
 103 
 104   pthread_t thread_id         thread id
 105 
 106   ++++++++++++++++++++++++++++++++++++++*/
 107 static
 108 void ta_remove_l(GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
 109 { 
 110  GList *item;
 111 
 112  for(item = g_list_first(*list);
 113      item != NULL;
 114      item = g_list_next(item)) {
 115    ta_str_t *tas = (ta_str_t *) (item->data);
 116 
 117    if( tas->thread_id == thread_id ) {
 118      *list = g_list_remove_link(*list, item);
 119      wr_clear_list( &item );
 120      break;
 121    }
 122  }
 123    
 124  return;
 125 }
 126 
 127 
 128 /*++++++++++++++++++++++++++++++++++++++
 129   
 130   sets the activity field in the given thread's record. 
 131   Truncates the string if too long.
 132 
 133   ta_str_t *tas        pointer to the thread's record
 134 
 135   char *activity       new value for the activity field
 136   ++++++++++++++++++++++++++++++++++++++*/
 137 static
 138 void ta_setactivity_l(ta_str_t *tas, char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
 139 {
 140   char *nl;
 141 
 142   strncpy(tas->activity, activity, TA_ACT_LEN-1);
 143   tas->activity[TA_ACT_LEN]=0;
 144   /* convert last newline to a space, if any */
 145   if( (nl=strrchr(tas->activity, '\n')) != NULL ) {
 146     *nl=' ';
 147   }
 148 }
 149 
 150 
 151 #define TA_HEADER "%-8s %15s %4s %4s %5s %5s %4s %6s %s\n"
 152 #define TA_FORMAT "%-8s %15s %4d %4lu %5.1f %5.1f %4d %6.3f %s\n"
 153 
 154 
 155 /*++++++++++++++++++++++++++++++++++++++
 156   
 157   prints a header for a list of threads to a specified buffer.
 158   The output is truncated if the buffer is too small.
 159 
 160   char *buf         pointer to the buffer
 161 
 162   unsigned length   buffer size
 163   ++++++++++++++++++++++++++++++++++++++*/
 164 static 
 165 void ta_print_header(char *buf, unsigned length)
     /* [<][>][^][v][top][bottom][index][help] */
 166 {
 167   snprintf(buf, length, TA_HEADER,
 168            "type", "from", "sock", "thr", "sess", "task", "#", 
 169            "avg", "current"
 170            ); 
 171 }
 172 
 173 
 174 /*++++++++++++++++++++++++++++++++++++++
 175   
 176   Formats the data from one thread's record to an entry for a list of
 177   threads.  Prints to a specified buffer. Calculates the average time
 178   spent per event as well as the lifetime of the thread. Checks the
 179   address of the peer on the socket. The output is truncated if the
 180   buffer is too small.
 181   
 182   ta_str_t *tas        pointer to the thread's record
 183 
 184   char *buf            pointer to the buffer
 185   
 186   unsigned length      buffer size
 187   
 188   ut_timer_t *reftime  current time 
 189 
 190   ++++++++++++++++++++++++++++++++++++++*/
 191 static
 192 void ta_printone_l(ta_str_t *tas, char *buf, unsigned length, 
     /* [<][>][^][v][top][bottom][index][help] */
 193                    ut_timer_t *reftime)
 194 {
 195   float session, task;  /* duration of the session/task */
 196   char *address = SK_getpeername(tas->sock); /* allocated! */
 197   /* can be NULL for example if the socket has just closed
 198      or the file descriptor is not a socket */
 199 
 200   session = UT_timediff( &tas->sessionstart, reftime );
 201   task    = UT_timediff( &tas->taskstart, reftime );
 202 
 203   snprintf(buf, length, TA_FORMAT ,
 204            tas->type,
 205            address ? address : "", 
 206            tas->sock, 
 207            (long unsigned)tas->thread_id, 
 208            session,
 209            task,
 210            tas->tasks,
 211            (tas->tasks > 0) ? session / tas->tasks : 0,
 212            tas->activity);
 213   
 214   if (address) {
 215     UT_free(address);
 216   }
 217 }
 218 
 219 
 220 /*++++++++++++++++++++++++++++++++++++++
 221   
 222   Public adding function - adds the current thread to the list,
 223   storing the given socket and type string along.
 224 
 225   int sock      associated socket (if any, or 0 if not)
 226 
 227   char *type    type string 
 228   
 229   ++++++++++++++++++++++++++++++++++++++*/
 230 void TA_add(int sock, char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 231 {
 232   ta_str_t *newtas;
 233   
 234   /* lock the list */
 235   pthread_mutex_lock( &ta_mutex );
 236   
 237   /* find/create node and set peer/thread_id */
 238   newtas = ta_findcreate_l( &ta_list, pthread_self());
 239   newtas->sock = sock;
 240   newtas->tasks = 0;
 241   newtas->condat = NULL;
 242   UT_timeget( &newtas->sessionstart );
 243   UT_timeget( &newtas->taskstart ); /* just to get it a reasonable value */
 244 
 245   snprintf(newtas->type, TA_TYPE_LEN, type);
 246   ta_setactivity_l(newtas,"--");
 247   
 248   /* unlock */
 249   pthread_mutex_unlock( &ta_mutex );
 250 }
 251 
 252 
 253 /*++++++++++++++++++++++++++++++++++++++
 254   
 255   Public deletion function - deletes the current thread from the list.
 256 
 257   ++++++++++++++++++++++++++++++++++++++*/
 258 void TA_delete(void)
     /* [<][>][^][v][top][bottom][index][help] */
 259 {
 260   /* lock the list */
 261   pthread_mutex_lock( &ta_mutex );
 262   
 263   /* find & remove */
 264   ta_remove_l( &ta_list, pthread_self() );
 265   
 266   /* unlock */
 267   pthread_mutex_unlock( &ta_mutex );
 268 }
 269 
 270 
 271 /*++++++++++++++++++++++++++++++++++++++
 272 
 273   Public activity-setting function - sets the current activity string
 274   for the current thread.
 275 
 276   char *activity     new value
 277   
 278   ++++++++++++++++++++++++++++++++++++++*/
 279 void TA_setactivity(char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
 280 {
 281   ta_str_t *newtas;
 282 
 283   /* lock the list */
 284   pthread_mutex_lock( &ta_mutex );
 285   
 286   /* find */
 287   newtas = ta_findcreate_l( &ta_list, pthread_self());
 288   
 289   /* set the activity field */
 290   ta_setactivity_l(newtas, activity);
 291 
 292   /* unlock */
 293   pthread_mutex_unlock( &ta_mutex );
 294 }
 295 
 296 
 297 /*++++++++++++++++++++++++++++++++++++++
 298   
 299   Public condat-setting function - associates a connection data
 300   structure with the current thread.
 301 
 302   sk_conn_st *condat    pointer to a connection data structure
 303 
 304   ++++++++++++++++++++++++++++++++++++++*/
 305 void TA_setcondat(sk_conn_st *condat)
     /* [<][>][^][v][top][bottom][index][help] */
 306 {
 307   ta_str_t *newtas;
 308 
 309   /* lock the list */
 310   pthread_mutex_lock( &ta_mutex );
 311   
 312   /* find */
 313   newtas = ta_findcreate_l( &ta_list, pthread_self());
 314   
 315   /* set the condat field */
 316   newtas->condat = condat;
 317 
 318   /* unlock */
 319   pthread_mutex_unlock( &ta_mutex );
 320 }
 321 
 322 
 323 /*++++++++++++++++++++++++++++++++++++++
 324   
 325    increments the event counter for the current thread.
 326 
 327   ++++++++++++++++++++++++++++++++++++++*/
 328 void TA_increment(void)
     /* [<][>][^][v][top][bottom][index][help] */
 329 {
 330   ta_str_t *newtas;
 331 
 332   /* lock the list */
 333   pthread_mutex_lock( &ta_mutex );
 334   
 335   /* find */
 336   newtas = ta_findcreate_l( &ta_list, pthread_self());
 337   /* increment task */
 338   newtas->tasks++;
 339   /* set task starting time */
 340   UT_timeget( &newtas->taskstart );
 341 
 342   /* unlock */
 343   pthread_mutex_unlock( &ta_mutex );
 344 }
 345 
 346 
 347 /*++++++++++++++++++++++++++++++++++++++
 348   
 349   resets the time and event counter of a specified thread.
 350 
 351   pthread_t thread_id     thread_id  
 352 
 353   ++++++++++++++++++++++++++++++++++++++*/
 354 void TA_reset_counters(pthread_t thread_id)
     /* [<][>][^][v][top][bottom][index][help] */
 355 {
 356   ta_str_t *tas;
 357 
 358   /* lock the list */
 359   pthread_mutex_lock( &ta_mutex );
 360 
 361   if( (tas = ta_findonly_l(&ta_list, thread_id)) != NULL) {
 362     UT_timeget( &tas->sessionstart );
 363     UT_timeget( &tas->taskstart ); /* just to get it a reasonable value */
 364     tas->tasks = 0;
 365   }
 366 
 367   pthread_mutex_unlock( &ta_mutex );
 368 }
 369 
 370 
 371 /*++++++++++++++++++++++++++++++++++++++
 372   
 373   Compiles a list of the threads' data records as text.
 374 
 375   char * TA_tostring      returns an allocated text, must be freed after use.
 376 
 377   ++++++++++++++++++++++++++++++++++++++*/
 378 char * TA_tostring(void)
     /* [<][>][^][v][top][bottom][index][help] */
 379 {
 380   GList *item;
 381   char *bigbuf = NULL;
 382   char smallbuf[TA_PRINT_LEN];
 383   ut_timer_t reftime;
 384 
 385   ta_print_header(smallbuf, TA_PRINT_LEN);
 386   bigbuf = (char *)UT_malloc(strlen(smallbuf)+2);
 387   strcpy(bigbuf, smallbuf);
 388   strcat(bigbuf, "\n");
 389   
 390   /* lock the list */
 391   pthread_mutex_lock( &ta_mutex );
 392   
 393   /* get reference time */
 394   UT_timeget( &reftime );
 395   
 396   /* iterate */
 397   for(item = g_list_first(ta_list);
 398       item != NULL;
 399       item = g_list_next(item)) {
 400     ta_str_t *tas = (ta_str_t *) (item->data);
 401     unsigned smalllen;
 402     unsigned biglen = ( bigbuf == NULL ) ? 0 : strlen(bigbuf);
 403 
 404     ta_printone_l(tas, smallbuf, TA_PRINT_LEN, &reftime);
 405     smalllen = strlen(smallbuf);
 406 
 407     bigbuf = (char *)UT_realloc(bigbuf, biglen+smalllen+3);
 408     
 409     strcat(bigbuf, smallbuf);
 410   }
 411   /* unlock */
 412   pthread_mutex_unlock( &ta_mutex );
 413   
 414   return bigbuf;
 415 }
 416 
 417 
 418 
 419 /*++++++++++++++++++++++++++++++++++++++
 420   
 421   Finds a thread of the matching type, socket file descriptor and thread id
 422   and executes the watchdog's triggers if it's defined.
 423   
 424   char *type                thread type string
 425 
 426   int sock                  socket #
 427 
 428   pthread_t thread_id       thread id
 429 
 430   ++++++++++++++++++++++++++++++++++++++*/
 431 void TA_trigger(char *type, int sock, pthread_t thread_id)
     /* [<][>][^][v][top][bottom][index][help] */
 432 { 
 433   ta_str_t *tas;
 434 
 435   /* lock the list */
 436   pthread_mutex_lock( &ta_mutex );
 437   
 438   if( (tas = ta_findonly_l(&ta_list, thread_id)) != NULL
 439       && tas->sock == sock
 440       && strcmp(tas->type, type) == 0
 441       && tas->condat != NULL
 442       && tas->condat->sock == sock
 443       ) {
 444     SK_watchtrigger(tas->condat);
 445   }
 446   
 447   /* unlock */
 448   pthread_mutex_unlock( &ta_mutex );
 449   
 450 }

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