Navigation


Changeset 1060:13fc3fc9c789 in freeDiameter


Ignore:
Timestamp:
Apr 29, 2013, 6:15:34 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

New feature in fd_fifo to get timing statistics

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • extensions/dbg_interactive/queues.i

    r767 r1060  
    6767        int length() {
    6868                int l;
    69                 int ret = fd_fifo_length ( $self, &l );
     69                int ret = fd_fifo_length ( $self, &l, NULL );
    7070                if (ret != 0) {
    7171                        DI_ERROR(ret, NULL, NULL);
  • include/freeDiameter/libfdproto.h

    r1052 r1060  
    30373037 *  queue       : The queue from which to retrieve the number of elements.
    30383038 *  length      : Upon success, the current number of elements in the queue is stored here.
     3039 *  max         : the maximum number of elements as specified during creation. Can be NULL.
    30393040 *
    30403041 * DESCRIPTION:
     
    30453046 *  EINVAL      : A parameter is invalid.
    30463047 */
    3047 int fd_fifo_length ( struct fifo * queue, int * length );
     3048int fd_fifo_length ( struct fifo * queue, int * length, int * max);
    30483049int fd_fifo_length_noerr ( struct fifo * queue ); /* no error checking version */
     3050
     3051/*
     3052 * FUNCTION:    fd_fifo_getstats
     3053 *
     3054 * PARAMETERS:
     3055 *  queue       : The queue from which to retrieve the timings information.
     3056 *  total       : Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring)
     3057 *  blocking    : Cumulated time threads trying to post new items were blocked (queue full).
     3058 *  last        : For the last element retrieved from the queue, how long it take between posting (including blocking) and poping
     3059 * 
     3060 * DESCRIPTION:
     3061 *  Retrieve the timing information associated with a queue, for monitoring purpose.
     3062 *
     3063 * RETURN VALUE:
     3064 *  0           : The statistics have been updated.
     3065 *  EINVAL      : A parameter is invalid.
     3066 */
     3067int fd_fifo_getstats( struct fifo * queue, struct timespec * total, struct timespec * blocking, struct timespec * last);
     3068
    30493069
    30503070/*
  • libfdproto/fifo.c

    r974 r1060  
    7070        int             highest;/* The highest count value for which h_cb has been called */
    7171        int             highest_ever; /* The max count value this queue has reached (for tweaking) */
     72       
     73        struct timespec total_time;    /* Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) */
     74        struct timespec blocking_time; /* Cumulated time threads trying to post new items were blocked (queue full). */
     75        struct timespec last_time;     /* For the last element retrieved from the queue, how long it take between posting (including blocking) and poping */
     76       
     77};
     78
     79struct fifo_item {
     80        struct fd_list   item;
     81        struct timespec  posted_on;
    7282};
    7383
     
    130140                        queue->h_cb, queue->l_cb, queue->data,
    131141                        queue->highest_ever);
     142        fd_log_debug("   timings: total:%ld.%06ld, blocking:%ld.%06ld, last:%ld.%06ld",
     143                        (long)queue->total_time.tv_sec,(long)(queue->total_time.tv_nsec/1000),
     144                        (long)queue->blocking_time.tv_sec,(long)(queue->blocking_time.tv_nsec/1000),
     145                        (long)queue->last_time.tv_sec,(long)(queue->last_time.tv_nsec/1000) );
    132146       
    133147        if (dump_item) {
     
    135149                int i = 0;
    136150                for (li = queue->list.next; li != &queue->list; li = li->next) {
    137                         fd_log_debug("  [%i] item %p in fifo %p:", i++, li->o, queue);
    138                         (*dump_item)(level, li->o);
     151                        struct fifo_item * fi = (struct fifo_item *)li;
     152                        fd_log_debug("  [%i] item %p in fifo %p, posted:ld.%06ld",
     153                                i++, fi->item.o, queue, (long)fi->posted_on.tv_sec,(long)(fi->posted_on.tv_nsec/1000));
     154                        (*dump_item)(level, fi->item.o);
    139155                }
    140156        }
     
    251267
    252268/* Get the length of the queue */
    253 int fd_fifo_length ( struct fifo * queue, int * length )
    254 {
    255         TRACE_ENTRY( "%p %p", queue, length );
     269int fd_fifo_length ( struct fifo * queue, int * length, int * max )
     270{
     271        TRACE_ENTRY( "%p %p %p", queue, length, max );
    256272       
    257273        /* Check the parameters */
     
    264280        *length = queue->count;
    265281       
     282        if (max)
     283                *max = queue->max;
     284       
    266285        /* Unlock */
    267286        CHECK_POSIX(  pthread_mutex_unlock( &queue->mtx )  );
     
    270289        return 0;
    271290}
     291
     292/* Get the timings */
     293int fd_fifo_getstats( struct fifo * queue, struct timespec * total, struct timespec * blocking, struct timespec * last)
     294{
     295        TRACE_ENTRY( "%p %p %p %p", queue, total, blocking, last);
     296       
     297        /* Check the parameters */
     298        CHECK_PARAMS( CHECK_FIFO( queue ) );
     299       
     300        /* lock the queue */
     301        CHECK_POSIX(  pthread_mutex_lock( &queue->mtx )  );
     302       
     303        if (total)
     304                memcpy(total, &queue->total_time, sizeof(struct timespec));
     305       
     306        if (blocking)
     307                memcpy(blocking, &queue->blocking_time, sizeof(struct timespec));
     308       
     309        if (last)
     310                memcpy(last, &queue->last_time, sizeof(struct timespec));
     311       
     312        /* Unlock */
     313        CHECK_POSIX(  pthread_mutex_unlock( &queue->mtx )  );
     314       
     315        /* Done */
     316        return 0;
     317}
     318
    272319
    273320/* alternate version with no error checking */
     
    326373int fd_fifo_post_int ( struct fifo * queue, void ** item )
    327374{
    328         struct fd_list * new;
     375        struct fifo_item * new;
    329376        int call_cb = 0;
     377        struct timespec posted_on, queued_on;
    330378       
    331379        TRACE_ENTRY( "%p %p", queue, item );
     
    333381        /* Check the parameters */
    334382        CHECK_PARAMS( CHECK_FIFO( queue ) && item && *item );
     383       
     384        /* Get the timing of this call */
     385        CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &posted_on)  );
    335386       
    336387        /* lock the queue */
     
    353404       
    354405        /* Create a new list item */
    355         CHECK_MALLOC_DO(  new = malloc (sizeof (struct fd_list)) , {
     406        CHECK_MALLOC_DO(  new = malloc (sizeof (struct fifo_item)) , {
    356407                        pthread_mutex_unlock( &queue->mtx );
    357408                } );
    358409       
    359         fd_list_init(new, *item);
     410        fd_list_init(&new->item, *item);
    360411        *item = NULL;
    361412       
    362413        /* Add the new item at the end */
    363         fd_list_insert_before( &queue->list, new);
     414        fd_list_insert_before( &queue->list, &new->item);
    364415        queue->count++;
    365416        if (queue->highest_ever < queue->count)
     
    370421        }
    371422       
     423        /* store timing */
     424        memcpy(&new->posted_on, &posted_on, sizeof(struct timespec));
     425       
     426        /* update queue timing info "blocking time" */
     427        {
     428                long long blocked_ns;
     429                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &queued_on)  );
     430                blocked_ns = (queued_on.tv_sec - posted_on.tv_sec) * 1000000000;
     431                blocked_ns += (queued_on.tv_nsec - posted_on.tv_nsec);
     432                blocked_ns += queue->blocking_time.tv_nsec;
     433                queue->blocking_time.tv_sec += blocked_ns / 1000000000;
     434                queue->blocking_time.tv_nsec = blocked_ns % 1000000000;
     435        }
     436       
    372437        /* Signal if threads are asleep */
    373438        if (queue->thrs > 0) {
     
    394459{
    395460        void * ret = NULL;
    396         struct fd_list * li;
     461        struct fifo_item * fi;
     462        struct timespec now;
    397463       
    398464        ASSERT( ! FD_IS_LIST_EMPTY(&queue->list) );
    399465       
    400         fd_list_unlink(li = queue->list.next);
     466        fi = (struct fifo_item *)queue->list.next;
     467        fd_list_unlink(&fi->item);
    401468        queue->count--;
    402         ret = li->o;
    403         free(li);
     469        ret = fi->item.o;
     470       
     471        /* Update the timings */
     472        CHECK_SYS_DO(  clock_gettime(CLOCK_REALTIME, &now), goto skip_timing  );
     473        {
     474                long long elapsed = (now.tv_sec - fi->posted_on.tv_sec) * 1000000000;
     475                elapsed += now.tv_nsec - fi->posted_on.tv_nsec;
     476               
     477                queue->last_time.tv_sec = elapsed / 1000000000;
     478                queue->last_time.tv_nsec = elapsed % 1000000000;
     479               
     480                elapsed += queue->total_time.tv_nsec;
     481                queue->total_time.tv_sec += elapsed / 1000000000;
     482                queue->total_time.tv_nsec = elapsed % 1000000000;
     483        }
     484skip_timing:   
     485        free(fi);
    404486       
    405487        if (queue->thrs_push) {
  • tests/testfifo.c

    r972 r1060  
    217217        {
    218218                struct fifo * queue = NULL;
    219                 int count;
     219                int count, max;
    220220                struct msg * msg  = NULL;
    221221               
     
    224224               
    225225                /* Check the count is 0 */
    226                 CHECK( 0, fd_fifo_length(queue, &count) );
     226                CHECK( 0, fd_fifo_length(queue, &count, &max) );
    227227                CHECK( 0, count);
     228                CHECK( 0, max);
    228229               
    229230                /* Now enqueue */
     
    236237               
    237238                /* Check the count is 3 */
    238                 CHECK( 0, fd_fifo_length(queue, &count) );
     239                CHECK( 0, fd_fifo_length(queue, &count, &max) );
    239240                CHECK( 3, count);
     241                CHECK( 0, max);
    240242               
    241243                /* Retrieve the first message using fd_fifo_get */
    242244                CHECK( 0, fd_fifo_get(queue, &msg) );
    243245                CHECK( msg1, msg);
    244                 CHECK( 0, fd_fifo_length(queue, &count) );
     246                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    245247                CHECK( 2, count);
    246248               
     
    250252                CHECK( 0, fd_fifo_timedget(queue, &msg, &ts) );
    251253                CHECK( msg2, msg);
    252                 CHECK( 0, fd_fifo_length(queue, &count) );
     254                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    253255                CHECK( 1, count);
    254256               
     
    256258                CHECK( 0, fd_fifo_tryget(queue, &msg) );
    257259                CHECK( msg3, msg);
    258                 CHECK( 0, fd_fifo_length(queue, &count) );
     260                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    259261                CHECK( 0, count);
    260262               
    261263                /* Check that another meq_tryget does not block */
    262264                CHECK( EWOULDBLOCK, fd_fifo_tryget(queue, &msg) );
    263                 CHECK( 0, fd_fifo_length(queue, &count) );
     265                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    264266                CHECK( 0, count);
    265267               
     
    272274                }
    273275                CHECK( ETIMEDOUT, fd_fifo_timedget(queue, &msg, &ts) );
    274                 CHECK( 0, fd_fifo_length(queue, &count) );
     276                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    275277                CHECK( 0, count);
    276278               
     
    361363               
    362364                /* Check the count of the queue is back to 0 */
    363                 CHECK( 0, fd_fifo_length(queue, &count) );
     365                CHECK( 0, fd_fifo_length(queue, &count, NULL) );
    364366                CHECK( 0, count);
    365367               
Note: See TracChangeset for help on using the changeset viewer.