⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qospktio.c

📁 Vista 核心Rally技术之-LLTD 实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * LICENSE NOTICE.
 *
 * Use of the Microsoft Windows Rally Development Kit is covered under
 * the Microsoft Windows Rally Development Kit License Agreement,
 * which is provided within the Microsoft Windows Rally Development
 * Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
 * want a license from Microsoft to use the software in the Microsoft
 * Windows Rally Development Kit, you must (1) complete the designated
 * "licensee" information in the Windows Rally Development Kit License
 * Agreement, and (2) sign and return the Agreement AS IS to Microsoft
 * at the address provided in the Agreement.
 */

/*
 * Copyright (c) Microsoft Corporation 2005.  All rights reserved.
 * This software is provided with NO WARRANTY.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>

#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>

#include "globals.h"
#include "statemachines.h"
#include "packetio.h"

extern void *
fmt_base(uint8_t *buf, const etheraddr_t *srchw, const etheraddr_t *dsthw, lld2_tos_t tos,
	 topo_opcode_t g_opcode, uint16_t seqnum, bool_t use_broadcast);

extern void
tx_write(uint8_t *buf, size_t nbytes);

/* with only two linkages, this isn't really needed...  #include "qospktio.h" */

/********************************* U T I L I T Y   F U N C T I O N S **************************************/
static
void
stamp_time(uint64_t* pTime)
{
    struct timeval now;
    uint64_t	   temp;

    gettimeofday(&now, NULL);
    temp = now.tv_sec * (uint64_t)1000000UL;
    *pTime = temp + now.tv_usec;
}


static
void
get_raw_samples(void)
{
    FILE  *procdev;

    if ( (procdev = fopen("/proc/net/dev", "r")) != (FILE*) 0)
    {
        uint32_t     rbytes, rpkts, tbytes, tpkts;
        bool_t       cntrs_parsedOK = FALSE;
        char         ifname[16];
        
        rbytes = rpkts = tbytes = tpkts = -1;
        strncpy(ifname, g_interface, 14);
        strcat(ifname,":");

        while (fgets(g_buf, sizeof(g_buf)/sizeof(g_buf[0]), procdev) == g_buf)
        {
            char *ifn;

            if ((ifn=strstr(g_buf, ifname)) != 0)
            {
                int   skipcol;
                char *val = ifn;
                char  dummy[] = {"0 0 0 0 0 0"};

                val += strlen(ifname);
                rbytes = strtoul(val,&val,10);
                rpkts  = strtoul(val,&val,10);
                /* Skip over 6 more un-needed columns */
                for (skipcol=0;skipcol<6;skipcol++)
                {
                    long  discard;

                    discard = strtoul(val,&val,10);
                    if (*val == '\0')
                    {
                        warn("get_raw_samples: using dummy values due to parse error!\n");
                        val = dummy;
                        break;
                    }
                }
                /* "val" now points to the tx-byte-counter */
                tbytes = strtoul(val,&val,10);
                tpkts  = strtoul(val,NULL,10);
                cntrs_parsedOK = TRUE;
                break;  // out of "while (reading lines)..."
            }
        }
        if (cntrs_parsedOK)
        {
            warn("get_raw_samples: failed reading /proc/dev for device statistics!\n");
            g_rbytes = g_rpkts = g_tbytes = g_tpkts  = 0;
        } else {
            /* got a valid parse of the /proc/net/dev line for our device */
            g_rbytes = rbytes;
            g_rpkts  = rpkts;
            g_tbytes = tbytes;
            g_tpkts  = tpkts;
        }
        fclose(procdev);
    } else {
        warn("get_raw_samples: failed opening /proc/dev for device statistics!\n");
        g_rbytes = g_rpkts = g_tbytes = g_tpkts  = 0;
    }
    IF_TRACED(TRC_QOS)
	dbgprintf("qos perf-cntr: g_rbytes=" FMT_UINT32 "; g_rpkts=" FMT_UINT32 \
	          "; g_tbytes=" FMT_UINT32 "; g_tpkts=" FMT_UINT32 "\n",
	          g_rbytes, g_rpkts, g_tbytes, g_tpkts);
    END_TRACE
}


static
void
get_timestamp(uint64_t* pTime)
{
    struct timeval now;
    uint64_t	   temp;

    ioctl(g_osl->sock, SIOCGSTAMP, &now);
    temp = now.tv_sec * (uint64_t)1000000UL;
    *pTime = temp + now.tv_usec;
}


static qos_session_t*
qos_find_session(void)
{
    unsigned int i;

    for (i=0;i<MAX_QOS_SESSIONS;i++)
    {
        if (g_QosSessions[i].qssn_is_valid  &&
            ETHERADDR_EQUALS(&g_base_hdr->tbh_realsrc, &g_QosSessions[i].qssn_ctrlr_real))
        {
            return &g_QosSessions[i];
        }        
    }
    return  NULL;
}

static qosEventBucket_t*
qos_find_bucket(qos_session_t *pSsn)
{
    unsigned int i = pSsn->qssn_first_bucket;
    unsigned int j = i + pSsn->qssn_num_active_buckets;

    while (i < j)
    {
        qosEventBucket_t* bucket = &pSsn->qssn_evt_buckets[i & (MAX_QOS_BUCKETS - 1)];

        if (bucket->evt_seqNum == g_sequencenum)
        {
            return bucket;
        }

        i++;
    }

    return NULL;
}

/***************************** T I M E R   S E R V I C E   R O U T I N E S *****************************/
static
void
qos_inactivity_timeout(void *state)
{
    int			i;
    qos_session_t*	pSsn = &g_QosSessions[0];
    struct timeval	now;

    for (i=0; i<MAX_QOS_SESSIONS; i++, pSsn++)
    {
        if (pSsn->qssn_is_valid == TRUE)
        {
            if (pSsn->qssn_ticks_til_discard)        pSsn->qssn_ticks_til_discard--;
            if (pSsn->qssn_ticks_til_discard == 0)
            {
                pSsn->qssn_is_valid = FALSE;
                pSsn->qssn_num_active_buckets = 0;
            }
        }
    }

    /* repeats every 30 seconds - a session is killed after 4 ticks' inactivity */
    gettimeofday(&now, NULL);
    now.tv_sec += 30;
    g_qos_inactivity_timer = event_add(&now, qos_inactivity_timeout, /*state:*/NULL);
}


#define BYTE_SCALE_FACTOR 1024  // value for reducing counters
#define BYTE_SCALE        0     // equivalent value for response
#define PKT_SCALE_FACTOR  1     // value for reducing counters
#define PKT_SCALE         0     // equivalent value for response
static
void
interface_counter_recorder(void *state)
{
    struct timeval	now;

    if (--g_samples_remaining != 0)
    {
        qos_perf_sample *thisSample = &g_perf_samples[g_next_sample];

        uint32_t       rbytes = g_rbytes;
        uint32_t       rpkts  = g_rpkts;
        uint32_t       tbytes = g_tbytes;
        uint32_t       tpkts  = g_tpkts;
        uint32_t       delta;
    
        get_raw_samples();      // get current values for g_rbytes, g_rpkts, g_tbytes, g_tpkts

        delta = (g_rbytes-rbytes > 0)? (g_rbytes-rbytes) : 0;
        IF_TRACED(TRC_QOS)
            dbgprintf("qos perf-cntr: delta-rbytes=" FMT_UINT32, delta);
        END_TRACE
        thisSample->bytes_rcvd = delta / BYTE_SCALE_FACTOR;

        delta = (g_rpkts-rpkts > 0)?   (g_rpkts-rpkts) : 0;
        IF_TRACED(TRC_QOS)
            dbgprintf("  delta-rpkts=" FMT_UINT32, delta);
        END_TRACE
        thisSample->pkts_rcvd  = delta / PKT_SCALE_FACTOR;

        delta = (g_tbytes-tbytes > 0)? (g_tbytes-tbytes) : 0;
        IF_TRACED(TRC_QOS)
            dbgprintf("  delta-tbytes=" FMT_UINT32, delta);
        END_TRACE
        thisSample->bytes_sent = delta / BYTE_SCALE_FACTOR;

        delta = (g_tpkts-tpkts > 0)?   (g_tpkts-tpkts) : 0;
        IF_TRACED(TRC_QOS)
            dbgprintf("  delta-tpkts=" FMT_UINT32 "\n", delta);
        END_TRACE
        thisSample->pkts_sent  = delta / PKT_SCALE_FACTOR;

        stamp_time(&g_perf_timestamp);

        IF_TRACED(TRC_QOS)
            dbgprintf("qos perf-cntr: sample-rbytes=%d; sample-rpkts=%d; sample-tbytes=%d; sample-tpkts=%d\n",
                   thisSample->bytes_rcvd, thisSample->pkts_rcvd, thisSample->bytes_sent, thisSample->pkts_sent);
        END_TRACE

        g_next_sample++;
        g_next_sample = g_next_sample % 60;

        if (g_sample_count < 60)
        {
            g_sample_count++;
        }

        /* repeats every second - until the lease runs out */
        gettimeofday(&now, NULL);
        now.tv_sec += 1;
        g_qos_CTA_timer = event_add(&now, interface_counter_recorder, /*state:*/NULL);
    } else {
        IF_TRACED(TRC_QOS)
            dbgprintf("qos perf-cntr: lease has run out - zero'ing counters, and stopping the timer...\n");
        END_TRACE

        g_next_sample = 0;
        g_sample_count = 0;
    }
}


extern void qos_init(void);

void
qos_init(void)
{
    int			i;
    qos_session_t*	pSsn = &g_QosSessions[0];
    struct timeval	now;

    /* Initialize all the session structures */
    for (i=0; i<MAX_QOS_SESSIONS; i++, pSsn++)
    {
        pSsn->qssn_ticks_til_discard = 0;
        pSsn->qssn_first_bucket = 0;
        pSsn->qssn_num_active_buckets = 0;
        pSsn->qssn_is_valid = FALSE;
        memset(&pSsn->qssn_ctrlr_real, 0, sizeof(etheraddr_t));
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -