modules/ta/ta.c

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

FUNCTIONS

This source file includes following functions.
  1. ta_findcreate_l
  2. ta_remove_l
  3. ta_setactivity_l
  4. ta_print_header
  5. ta_printone_l
  6. TA_add
  7. TA_delete
  8. TA_setactivity
  9. TA_increment
  10. TA_tostring

   1 /***************************************
   2   $Revision: 1.2 $
   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                              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 <ta.h>
  34 
  35 static
  36 ta_str_t *ta_findcreate_l( GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  37 {
  38   GList *item;
  39   ta_str_t *newtas;
  40 
  41   /* try to find first */
  42   for(item = g_list_first(*list);
  43       item != NULL;
  44       item = g_list_next(item)) {
  45     ta_str_t *tas = (ta_str_t *) (item->data);
  46 
  47     if( tas->thread_id == thread_id ) {
  48       return tas;
  49     }
  50   }
  51   
  52   /* not found => add */  /* zero everything*/
  53   dieif( !NOERR( wr_calloc( (void **) &newtas, 1, sizeof( ta_str_t ))));
  54   newtas->thread_id = thread_id;
  55 
  56   *list = g_list_append( *list, newtas );
  57 
  58   return newtas;
  59 }
  60 
  61 
  62 /* find and remove */
  63 static
  64 void ta_remove_l(GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  65 { 
  66  GList *item;
  67 
  68  for(item = g_list_first(*list);
  69      item != NULL;
  70      item = g_list_next(item)) {
  71    ta_str_t *tas = (ta_str_t *) (item->data);
  72 
  73    if( tas->thread_id == thread_id ) {
  74      *list = g_list_remove_link(*list, item);
  75      wr_clear_list( &item );
  76      break;
  77    }
  78  }
  79    
  80  return;
  81 }
  82 
  83 /* set the activity field */
  84 static
  85 void ta_setactivity_l(ta_str_t *tas, char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
  86 {
  87   char *nl;
  88 
  89   strncpy(tas->activity, activity, TA_ACT_LEN-1);
  90   tas->activity[TA_ACT_LEN]=0;
  91   /* convert last newline to a space, if any */
  92   if( (nl=strrchr(tas->activity, '\n')) != NULL ) {
  93     *nl=' ';
  94   }
  95 }
  96 
  97 
  98 #define TA_HEADER "%-8s %15s %4s %4s %5s %5s %4s %5s %s\n"
  99 #define TA_FORMAT "%-8s %15s %4d %4d %5.1f %5.1f %4d %5.2f %s\n"
 100 
 101 static 
 102 void ta_print_header(char *buf, int length)
     /* [<][>][^][v][top][bottom][index][help] */
 103 {
 104   snprintf(buf, length, TA_HEADER,
 105            "type", "from", "sock", "thr", "sess", "task", "#", 
 106            "avg", "current"
 107            ); 
 108 }
 109 
 110 /* fill in one entry */
 111 static
 112 void ta_printone_l(ta_str_t *tas, char *buf, int length, 
     /* [<][>][^][v][top][bottom][index][help] */
 113                    ut_timer_t *reftime)
 114 {
 115   float session, task;  /* duration of the session/task */
 116   char *address = SK_getpeername(tas->sock); /* allocated! */
 117   /* can be NULL for example if the socket has just closed
 118      or the file descriptor is not a socket */
 119 
 120   session = UT_timediff( &tas->sessionstart, reftime );
 121   task    = UT_timediff( &tas->taskstart, reftime );
 122 
 123   snprintf(buf, length, TA_FORMAT ,
 124            tas->type,
 125            address ? address : "", 
 126            tas->sock, 
 127            tas->thread_id, 
 128            session,
 129            task,
 130            tas->tasks,
 131            (tas->tasks > 0) ? session / tas->tasks : 0,
 132            tas->activity);
 133   
 134   if (address) {
 135     wr_free(address);
 136   }
 137 }
 138 
 139 /* PUBLIC adding function */
 140 void TA_add(int sock, char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 141 {
 142   ta_str_t *newtas;
 143   
 144   /* lock the list */
 145   pthread_mutex_lock( &ta_mutex );
 146   
 147   /* find/create node and set peer/thread_id */
 148   newtas = ta_findcreate_l( &ta_list, pthread_self());
 149   newtas->sock = sock;
 150   newtas->tasks = 0;
 151   UT_timeget( &newtas->sessionstart );
 152   UT_timeget( &newtas->taskstart ); /* just to get it a reasonable value */
 153 
 154   snprintf(newtas->type, TA_TYPE_LEN, type);
 155   ta_setactivity_l(newtas,"--");
 156   
 157   /* unlock */
 158   pthread_mutex_unlock( &ta_mutex );
 159 }
 160 
 161 
 162 /* PUBLIC deletion function */
 163 void TA_delete(void)
     /* [<][>][^][v][top][bottom][index][help] */
 164 {
 165   /* lock the list */
 166   pthread_mutex_lock( &ta_mutex );
 167   
 168   /* find & remove */
 169   ta_remove_l( &ta_list, pthread_self() );
 170   
 171   /* unlock */
 172   pthread_mutex_unlock( &ta_mutex );
 173 }
 174 
 175 
 176 /* PUBLIC activity-setting function */
 177 void TA_setactivity(char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179   ta_str_t *newtas;
 180 
 181   /* lock the list */
 182   pthread_mutex_lock( &ta_mutex );
 183   
 184   /* find */
 185   newtas = ta_findcreate_l( &ta_list, pthread_self());
 186   
 187   /* set the activity field */
 188   ta_setactivity_l(newtas, activity);
 189 
 190   /* unlock */
 191   pthread_mutex_unlock( &ta_mutex );
 192 }
 193 
 194 void TA_increment(void)
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196   ta_str_t *newtas;
 197 
 198   /* lock the list */
 199   pthread_mutex_lock( &ta_mutex );
 200   
 201   /* find */
 202   newtas = ta_findcreate_l( &ta_list, pthread_self());
 203   /* increment task */
 204   newtas->tasks++;
 205   /* set task starting time */
 206   UT_timeget( &newtas->taskstart );
 207 
 208   /* unlock */
 209   pthread_mutex_unlock( &ta_mutex );
 210 }
 211 
 212 char * TA_tostring(void)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214   GList *item;
 215   char *bigbuf = NULL;
 216   char smallbuf[TA_PRINT_LEN];
 217   ut_timer_t reftime;
 218 
 219   ta_print_header(smallbuf, TA_PRINT_LEN);
 220   dieif( !NOERR(wr_realloc( (void **) &bigbuf, strlen(smallbuf)+2 )));
 221   strcat(bigbuf, smallbuf);
 222   strcat(bigbuf, "\n");
 223   
 224   /* lock the list */
 225   pthread_mutex_lock( &ta_mutex );
 226   
 227   /* get reference time */
 228   UT_timeget( &reftime );
 229   
 230   /* iterate */
 231   for(item = g_list_first(ta_list);
 232       item != NULL;
 233       item = g_list_next(item)) {
 234     ta_str_t *tas = (ta_str_t *) (item->data);
 235     int smalllen;
 236     int biglen = ( bigbuf == NULL ) ? 0 : strlen(bigbuf);
 237 
 238     ta_printone_l(tas, smallbuf, TA_PRINT_LEN, &reftime);
 239     smalllen = strlen(smallbuf);
 240 
 241     dieif( !NOERR(wr_realloc( (void **) &bigbuf, biglen+smalllen+3 )));
 242     
 243     strcat(bigbuf, smallbuf);
 244   }
 245   /* unlock */
 246   pthread_mutex_unlock( &ta_mutex );
 247   
 248   return bigbuf;
 249 }

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