Changeset 1974

Show
Ignore:
Timestamp:
04/12/08 22:34:10 (7 months ago)
Author:
aturner
Message:

now I calculate how much time has passed since the last packet was sent, but I
still need to use the sleep-accellerator. refs #41

Location:
features/performance/src
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • features/performance/src/common/timer.h

    r1973 r1974  
    4343#include <math.h> 
    4444 
     45#ifdef HAVE_ABSOLUTE_TIME 
     46#include <CoreServices/CoreServices.h> 
     47#endif 
     48 
     49/* AbsoluteTime methods */ 
     50#ifndef NonZero 
     51#define NonZero(x) ((x).hi | (x).lo) 
     52#endif 
     53#ifndef SetZero 
     54#define SetZero(x) do { (x).hi = 0 ; (x).lo = 0; } while(0) 
     55#endif 
     56#ifndef CopyAbsolute 
     57#define CopyAbsolute(x, y) do { (x).lo = (y).lo ; (x).hi = (y).hi; } while (0) 
     58#endif 
     59#ifndef AbsoluteCmp 
     60#define AbsoluteCmp(left, right, cmp)       \ 
     61        (((left)->hi == (right)->hi) ?              \ 
     62        ((left)->lo cmp (right)->lo) :              \ 
     63        ((left)->hi cmp (right)->hi)) 
     64#endif 
     65 
    4566/* 
    4667 * 1 sec = 1,0000 millisec (ms) 
     
    7798 
    7899#ifndef ROUND_TIMESPEC_TO_MICROSEC(ts) 
    79 #define ROUND_TIMESPEC_TO_MICROSEC(ts)       \ 
    80     do {                                        \ 
    81         (ts)->tv_nsec = (lroundf((float)(ts)->tv_nsec / 1000) * 1000);   \ 
     100#define ROUND_TIMESPEC_TO_MICROSEC(ts)      \ 
     101    do {                                    \ 
     102        (ts)->tv_nsec = ((((ts)->tv_nsec / 1000) + ((ts)->tv_nsec % 1000 >= 500 ? 1 : 0)) * 1000);   \ 
    82103    } while (0) 
    83104#endif 
     
    170191        } while(0) 
    171192 
    172 #endif 
     193 
     194/*  
     195 * returns the amount of time that has passed since the  
     196 * last time you called this function. 
     197 */ 
     198static inline void 
     199get_delta_time(struct timespec *ret) 
     200{ 
     201/* OS X has absolute time */ 
     202#ifdef HAVE_ABSOLUTE_TIME 
     203    static AbsoluteTime last = {0, 0}; 
     204    AbsoluteTime now, delta; 
     205    Nanoseconds nano; 
     206     
     207    now = UpTime(); 
     208     
     209    if (! NonZero(last)) { 
     210        timesclear(ret); 
     211    } else { 
     212        delta = SubAbsoluteFromAbsolute(now, last); 
     213        nano = AbsoluteToNanoseconds(delta); 
     214        NANOSEC_TO_TIMESPEC(UnsignedWideToUInt64(nano) / 10, ret); 
     215    } 
     216 
     217    CopyAbsolute(last, now); 
     218     
     219/* Everyone else just uses gettimeofday */ 
     220#else 
     221    static struct timeval last = {0, 0}; 
     222    struct timeval now, delta; 
     223     
     224    gettimeofday(&now, NULL); 
     225    if (!timerisset(&last)) { 
     226        timeradd(&last, &now, &last); 
     227        timesclear(ret); 
     228    } else { 
     229        timersub(&now, &last, &delta); 
     230        last.tv_sec = now.tv_sec; 
     231        last.tv_nsec = now.tv_nsec; 
     232        TIMEVAL_TO_TIMESPEC(&delta, ret); 
     233    } 
     234#endif 
     235} 
     236 
     237#endif /* _TIMER_H_ */ 
  • features/performance/src/defines.h.in

    r1971 r1974  
    161161 
    162162/* struct timeval print structs */ 
    163 #define TIMEVAL_FORMAT "%lu.%06lu" 
     163#define TIMEVAL_FORMAT "%lus %luusec" 
     164#define TIMESPEC_FORMAT "%lus %lunsec" 
    164165 
    165166/* force a word or half-word swap on both Big and Little endian systems */ 
     
    227228        (tv)->tv_usec = (x) - ((tv)->tv_sec * 1000000);   \ 
    228229    } while(0) 
    229  
     230/* 
    230231#define NANOSEC_TO_TIMEVAL(x, tv)           \ 
    231232    do {                                    \ 
     
    238239        (ts)->tv_sec = (x) / 1000000000;      \ 
    239240        (ts)->tv_nsec = (x) - ((ts)->tv_sec * 1000000000);   \ 
     241    } while(0) 
     242*/ 
     243#define NANOSEC_TO_TIMEVAL(x, tv)           \ 
     244    do {                                    \ 
     245        (tv)->tv_sec =  (x) / 1000000000;      \ 
     246        (tv)->tv_usec = ((x) % 1000000000) / 1000);   \ 
     247    } while(0) 
     248 
     249#define NANOSEC_TO_TIMESPEC(x, ts)          \ 
     250    do {                                    \ 
     251        (ts)->tv_sec = (x) / 1000000000;      \ 
     252        (ts)->tv_nsec = (x) % 1000000000;   \ 
    240253    } while(0) 
    241254 
  • features/performance/src/send_packets.c

    r1973 r1974  
    7373static void do_sleep(struct timeval *time, struct timeval *last, int len,  
    7474    int accurate, sendpacket_t *sp, COUNTER counter); 
    75 static u_char *get_next_packet(pcap_t *pcap, struct pcap_pkthdr *pkthdr,  
     75static const u_char *get_next_packet(pcap_t *pcap, struct pcap_pkthdr *pkthdr,  
    7676    int file_idx, packet_cache_t **prev_packet); 
    7777static u_int32_t get_user_count(sendpacket_t *sp, COUNTER counter); 
     
    164164        /* 
    165165         * we have to cast the ts, since OpenBSD sucks 
    166          * had to be special and use bpf_timeval  
     166         * had to be special and use bpf_timeval. 
     167         * Only sleep if we're not in top speed mode (-t) 
    167168         */ 
    168         do_sleep((struct timeval *)&pkthdr.ts, &last, pktlen, options.accurate, sp, packetnum); 
    169              
     169         if (options.speed.mode != SPEED_TOPSPEED) 
     170            do_sleep((struct timeval *)&pkthdr.ts, &last, pktlen, options.accurate, sp, packetnum); 
     171         
    170172        /* write packet out on network */ 
    171173        if (sendpacket(sp, pktdata, pktlen) < (int)pktlen) 
    172174            warnx("Unable to send packet: %s", sendpacket_geterr(sp)); 
    173                  
     175 
    174176        /*  
    175177         * track the time of the "last packet sent".  Again, because of OpenBSD 
     
    199201 * will be updated as new entries are added (or retrieved) from the cache list. 
    200202 */ 
    201 static u_char * 
     203static const u_char * 
    202204get_next_packet(pcap_t *pcap, struct pcap_pkthdr *pkthdr, int file_idx,  
    203205    packet_cache_t **prev_packet) 
     
    238240                         * We should read the pcap file, and cache the results 
    239241                         */ 
    240                         pktdata = pcap_next(pcap, pkthdr); 
     242                        pktdata = (u_char *)pcap_next(pcap, pkthdr); 
    241243                        if (pktdata != NULL) { 
    242244                                if (*prev_packet == NULL) { 
     
    268270                 * Read pcap file as normal 
    269271                 */ 
    270                 pktdata = pcap_next(pcap, pkthdr); 
     272                pktdata = (u_char *)pcap_next(pcap, pkthdr); 
    271273        } 
    272274 
     275    /* this get's casted to a const on the way out */ 
    273276        return pktdata; 
    274277} 
     
    325328    static struct timeval totalsleep = { 0, 0 }; 
    326329#endif 
    327     static int adjuster_flipper = 0; 
    328 #ifdef HAVE_TCPREPLAY 
    329     struct timespec adjuster = { 0, OPT_VALUE_SLEEP_ACCEL * 1000 } 
    330 #else 
    331     struct timespec adjuster = { 0, ADJUSTER_OFFSET * 1000 }; 
    332 #endif 
    333     static struct timespec nap = { 0, 0 }; 
    334     static u_int32_t double_up = 0; 
     330    struct timespec adjuster = { 0, 0 }; 
     331    static struct timespec nap = { 0, 0 }, delta_time = {0, 0}; 
    335332    struct timeval nap_for, now, sleep_until; 
    336     struct timespec ignore, sleep, nap_this_time; 
     333    struct timespec nap_this_time; 
     334    static int32_t nsec_adjuster = -1, nsec_times = -1; 
    337335    float n; 
    338336    static u_int32_t send = 0;      /* accellerator.   # of packets to send w/o sleeping */ 
    339337    u_int64_t ppnsec; /* packets per usec */ 
     338 
     339 
     340#ifdef TCPREPLAY 
     341    adjuster.tv_nsec = OPT_VALUE_SLEEP_ACCEL * 1000; 
     342#else 
     343    adjuster.tv_nsec = ADJUSTER_OFFSET * 1000; 
     344#endif 
     345 
     346    dbgx(2, "Adjuster: " TIMEVAL_FORMAT, adjuster.tv_sec, adjuster.tv_nsec); 
    340347     
    341     /* just return if topspeed */ 
    342     if (options.speed.mode == SPEED_TOPSPEED) 
    343         return; 
    344  
    345348    /* acclerator time? */ 
    346349    if (send > 0) { 
     
    349352    } 
    350353         
    351     dbgx(3, "Last time: " TIMEVAL_FORMAT, last->tv_sec, last->tv_usec); 
    352  
    353     if (gettimeofday(&now, NULL) < 0) { 
     354    dbgx(4, "Last time: " TIMEVAL_FORMAT, last->tv_sec, last->tv_usec); 
     355 
     356    if (gettimeofday(&now, NULL) < 0) 
    354357        errx(1, "Error gettimeofday: %s", strerror(errno)); 
    355     } 
    356  
    357     dbgx(3, "Now time: " TIMEVAL_FORMAT, now.tv_sec, now.tv_usec); 
     358 
     359    dbgx(4, "Now time: " TIMEVAL_FORMAT, now.tv_sec, now.tv_usec); 
    358360 
    359361    /* First time through for this file */ 
     
    368370 
    369371    switch(options.speed.mode) { 
     372    /*  
     373     * If top speed, you shouldn't even be here, but handle it anyways 
     374     */ 
     375    case SPEED_TOPSPEED: 
     376        notice("you shouldn't call do_sleep() in top speed mode."); 
     377        return; 
     378        break; 
     379         
    370380    case SPEED_MULTIPLIER: 
    371381        /*  
     
    384394             */ 
    385395            timesclear(&nap); 
    386         } 
    387  
    388         /* round up/down as necessary */ 
    389         if (accurate != ACCURATE_ABS_TIME) 
    390             ROUND_TIMESPEC_TO_MICROSEC(&nap); 
    391          
     396        }         
    392397        break; 
    393398 
     
    402407            nap.tv_nsec = (n - nap.tv_sec)  * 1000000000; 
    403408             
    404             /* round up/down as necessary */ 
    405             if (accurate != ACCURATE_ABS_TIME) 
    406                 ROUND_TIMESPEC_TO_MICROSEC(&nap); 
    407  
    408409            dbgx(3, "packet size %d\t\tequals %f bps\t\tnap " TIMEVAL_FORMAT, len, n,  
    409410                nap.tv_sec, nap.tv_nsec); 
     
    424425        } 
    425426        break; 
    426  
     427         
    427428    case SPEED_ONEATATIME: 
    428429        /* do we skip prompting for a key press? */ 
     
    452453    nap_this_time.tv_nsec = nap.tv_nsec; 
    453454 
     455    if (accurate != ACCURATE_ABS_TIME) { 
     456 
     457        switch (options.speed.mode) { 
     458            /* Mbps & Multipler are dynamic timings, so we round to the nearest usec */ 
     459            case SPEED_MBPSRATE: 
     460            case SPEED_MULTIPLIER: 
     461                ROUND_TIMESPEC_TO_MICROSEC(&nap_this_time); 
     462                break; 
     463 
     464            /* Packets/sec is static, so we weight packets for .1usec accuracy */ 
     465            case SPEED_PACKETRATE: 
     466                if (nsec_adjuster < 0) 
     467                    nsec_adjuster = (nap_this_time.tv_nsec % 10000) / 1000; 
     468         
     469                /* update in the range of 0-9 */ 
     470                nsec_times = (nsec_times + 1) % 10; 
     471         
     472                if (nsec_times < nsec_adjuster) { 
     473                    /* sorta looks like a no-op, but gives us a nice round usec number */ 
     474                    nap_this_time.tv_nsec = (nap_this_time.tv_nsec / 1000 * 1000) + 1000; 
     475                } else { 
     476                    nap_this_time.tv_nsec -= (nap_this_time.tv_nsec % 1000); 
     477                } 
     478     
     479                dbgx(3, "(%ld)\tnsec_times = %ld\tnap adjust: %lu -> %lu", nsec_adjuster, nsec_times, nap.tv_nsec, nap_this_time.tv_nsec);             
     480                break; 
     481                 
     482            default: 
     483                errx(1, "Unknown/supported speed mode: %d", options.speed.mode); 
     484        } 
     485    } 
     486 
     487 
     488    get_delta_time(&delta_time); 
     489    dbgx(2, "delta: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec); 
     490 
     491    if (timesisset(&delta_time)) { 
     492        if (timescmp(&nap_this_time, &delta_time, >)) { 
     493            timessub(&nap_this_time, &delta_time, &nap_this_time); 
     494            dbgx(3, "timesub: %lu %lu", delta_time.tv_sec, delta_time.tv_nsec); 
     495        } else {  
     496            timesclear(&nap_this_time); 
     497            dbgx(3, "timesclear: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec); 
     498        } 
     499    } 
     500 
    454501    /* apply the adjuster... */ 
    455502    if (timesisset(&adjuster)) { 
    456503        if (timescmp(&nap_this_time, &adjuster, >)) { 
    457504            timessub(&nap_this_time, &adjuster, &nap_this_time); 
    458             dbgx(1, "adjusting nap_this_time by %lu nsec", adjuster.tv_nsec); 
    459505        } else {  
    460             dbg(1, "resetting nap_this_time to 0"); 
    461506            timesclear(&nap_this_time); 
    462507        } 
    463508    } 
    464509     
    465     /* don't sleep if nap = { 0, 0} */ 
     510    dbgx(2, "Sleeping: " TIMESPEC_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_nsec); 
     511 
     512    /* don't sleep if nap = {0, 0} */ 
    466513    if (!timesisset(&nap_this_time)) 
    467514        return; 
    468  
    469  
     515         
    470516    /* 
    471517     * Depending on the accurate method & packet rate computation method 
    472  
    473     /*  
    474518     * We have multiple methods of sleeping, pick the right one... 
    475519     */ 
     
    532576    dbgx(4, "Total sleep time: " TIMEVAL_FORMAT, totalsleep.tv_sec, totalsleep.tv_usec); 
    533577#endif 
     578 
     579    get_delta_time(&delta_time); 
     580    dbgx(2, "sleep delta: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec); 
     581 
    534582} 
    535583 
  • features/performance/src/sleep.h

    r1973 r1974  
    3333#include "config.h" 
    3434#include "defines.h" 
     35#include "common.h" 
    3536 
    3637#ifdef HAVE_SYS_SELECT  /* According to POSIX 1003.1-2001 */ 
     
    8384#ifdef HAVE_ABSOLUTE_TIME 
    8485#include <CoreServices/CoreServices.h> 
    85 #define NonZero(x) ((x).hi | (x).lo) 
    86  
    8786 
    8887/*