📄 qospktio.c
字号:
/*
* 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 + -