一个性能带宽限制测试工具

#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h> 
#include <sys/timeb.h> 
#include <sys/time.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <string.h> 
#include <pthread.h> 
#include <signal.h>

#define BWCALC_SML              256
#define MAX_BW                  (1 << 18)
#define PAGE_SIZE               1024
#define ALIGN_DOWN(x, n)        (((x)) & ~((n) - 1ULL))

typedef unsigned long long      longlong;
typedef struct  _bw_ctrl_info{
    longlong    x0;
    unsigned long   y0;
    unsigned long   maxbw;
    unsigned long   rate;
}bw_ctrl_info, *pbw_ctrl_info;

static  bw_ctrl_info  bi;

longlong gettickcount()
{
    struct timeb tp;
    ftime(&tp);
    return ((longlong)tp.time) * 1000 + tp.millitm;
}
unsigned long   bw_ctrl_getcurrate(bw_ctrl_info *pbi)
{
    longlong tick = gettickcount() - pbi->x0;
    if(tick > (BWCALC_SML << 1))
        return 0;
    return pbi->rate;
}
                                                                                                       
int bwctl_filter(bw_ctrl_info *pbi, unsigned short len)
{
    longlong ll;
    longlong tick = gettickcount();

    if((pbi->y0 + (len << 3)) >  (((pbi->maxbw) / 1000) * (tick - pbi->x0)))
        return 0;
    pbi->y0 += (len << 3);
    ll = (longlong)pbi->y0;
    pbi->rate = (unsigned long)(ll * 1000 / (tick - pbi->x0));
    if((tick - pbi->x0)  >  BWCALC_SML){
        pbi->y0 = pbi->y0 * (BWCALC_SML >> 1) / (tick - pbi->x0);
        pbi->x0 = tick - (BWCALC_SML >> 1);
    }
    return 1;
}

int main(int argc, char *argv[])
{
    int                 i;
    char               *arg;
    char               *ptr;
    int                 num;
    int                 ret;
    void               *viraddr;
    size_t              map_length;
    unsigned int        val;
    unsigned long long  addr;
    unsigned long long  map_addr;
    unsigned long long  t1;
    unsigned long long  max_bw;
    unsigned long long  bar2Addr;
    unsigned int        unit_size   = 0;
    unsigned long long  unit_value  = 0;
    int                 mem_fd      = -1;
    unsigned int        count       = 0;

    t1 = gettickcount();
    bi.maxbw = MAX_BW;

    if ((argc < 2) || (argc > 3))
    {
        printf("invalid para\n");
        return -1;
    }

    if ((argv[1][0] == '0') && (argv[1][1] == 'x')) {
        bar2Addr = strtoull(&argv[1][2], NULL, 16);
    } else {
        bar2Addr = strtoull(&argv[1][0], NULL, 16);
    }

    if (argc == 3) {
        if ((argv[2][0] == '0') && (argv[2][1] == 'x')) {
            max_bw = strtoull(&argv[2][2], NULL, 16);
        } else {
            max_bw = strtoull(&argv[2][0], NULL, 16);
        }
        bi.maxbw = max_bw & ~(1024);
    }

    mem_fd = open("/dev/mem_map", O_RDWR);
    if (mem_fd < 0) {
        perror("open /dev/mem failed");
        return -3;
    }
    map_addr = ALIGN_DOWN(bar2Addr, PAGE_SIZE);
    map_length = bar2Addr - map_addr + 4;
    viraddr = mmap(NULL, map_length, PROT_WRITE, MAP_SHARED, mem_fd, map_addr);
    if (viraddr == MAP_FAILED) {
        perror("mmap failed");
        printf("mmap addr:0x%016llx size:0x%08lx failed\n", map_addr, map_length);
        close(mem_fd);
        return -4;
    }

    viraddr = (char*)viraddr + bar2Addr - map_addr;

    while(1){
        srand((unsigned)time(NULL));
        num = rand();
        val = num;
        *(unsigned int *)viraddr = (unsigned int)val;
        ret  =  bwctl_filter(&bi, 16+4);
        if(ret <= 0){
            usleep(10);
            continue;
        }
        count++;
        if((gettickcount() - t1) > 1000) {
            printf("\nnum = %x, rate = %8d kbps, count = %d",  num,  bw_ctrl_getcurrate(&bi)  >>  10, count);
            t1 = gettickcount();
            count = 0;
        }
    }

    ///< clean
    munmap(viraddr, map_length);
    close(mem_fd);

    return 0;
}
 

上一篇:SAP Spartacus 3.0的一些变化


下一篇:本地 maven + scala 跑spark wordcount