static void x86wdrestart(void) { Wd *wd; vlong r, t; runoncpu(0); t = interval(); wd = &x86wd; ilock(wd); switch(wd->model){ case P6: wrmsr(0xC1, -t); break; case P4: r = 0x0000000004FF8000LL; wrmsr(0x36C, r); lapicnmienable(); wrmsr(0x30C, -t); wrmsr(0x36C, 0x0000000000001000LL|r); break; case K6: case K8: wrmsr(0xC0010004, -t); break; } wd->ticks++; iunlock(wd); }
void* HiccupsInfo::runthread(void* vp) { ThrdStart* ts = (ThrdStart*)vp; int id = ts->thrdid_; int cpu; runoncpu(conf.cpus_[id]); if ((cpu = sched_getcpu()) < 0) { perror("sched_getcpu"); exit(1); } if (cpu != conf.cpus_[id]) { fprintf(stderr, "Thread %d: tid: %d, running on wrong cpu: %d, expected: %d\n", id, gettid(), cpu, conf.cpus_[id]); exit(1); } unsigned long sz = HPGSZ(sizeof(HiccupsInfo)); fprintf(stdout, "thread#: %3d tid: %d size %lu cpu[%d]: %d\n", id, gettid(), sz, id, conf.cpus_[id]); HiccupsInfo::hudatap_[id] = ts->hudata_ = (HiccupsInfo*)memzalloc(sz); ts->hudata_->cpuid_ = conf.cpus_[id]; ts->hudata_->id_ = id; ts->hudata_->bins_ = (HUbin*)memzalloc(conf.bins_ * sizeof(bins_[0])); ts->rv_ = ts->hudata_->run(); if (id) pthread_exit(0); return 0; }
static void x86wddisable(void) { Wd *wd; wd = &x86wd; ilock(wd); if(!wd->inuse){ /* * Can't error, called at boot by addwatchdog(). */ iunlock(wd); return; } iunlock(wd); runoncpu(0); ilock(wd); lapicnmidisable(); switch(wd->model){ case P6: wrmsr(0x186, 0); break; case P4: wrmsr(0x36C, 0); /* cccr0 */ wrmsr(0x3B8, 0); /* escr0 */ break; case K6: case K8: wrmsr(0xC0010000, 0); break; } wd->inuse = 0; iunlock(wd); }
static void x86wdenable(void) { Wd *wd; vlong r, t; int i, model; u32int evntsel; wd = &x86wd; ilock(wd); if(wd->inuse){ iunlock(wd); error(Einuse); } iunlock(wd); /* * keep this process on cpu 0 so we always see the same timers * and so that this will work even if all other cpus are shut down. */ runoncpu(0); /* * Check the processor is capable of doing performance * monitoring and that it has TSC, RDMSR/WRMSR and a local APIC. */ model = -1; if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0){ if(X86FAMILY(m->cpuidax) == 0x06) model = K6; else if(X86FAMILY(m->cpuidax) == 0x0F) model = K8; } else if(strncmp(m->cpuidid, "GenuineIntel", 12) == 0){ if(X86FAMILY(m->cpuidax) == 0x06) model = P6; else if(X86FAMILY(m->cpuidax) == 0x0F) model = P4; } if(model == -1 || (m->cpuiddx & (Cpuapic|Cpumsr|Tsc)) != (Cpuapic|Cpumsr|Tsc)) error(Enodev); ilock(wd); if(wd->inuse){ iunlock(wd); error(Einuse); } wd->model = model; wd->inuse = 1; wd->ticks = 0; /* * See the IA-32 Intel Architecture Software * Developer's Manual Volume 3: System Programming Guide, * Chapter 15 and the AMD equivalent for what all this * bit-whacking means. */ t = interval(); switch(model){ case P6: wrmsr(0x186, 0); /* evntsel */ wrmsr(0x187, 0); wrmsr(0xC1, 0); /* perfctr */ wrmsr(0xC2, 0); lapicnmienable(); evntsel = 0x00130000|0x79; wrmsr(0xC1, -t); wrmsr(0x186, 0x00400000|evntsel); break; case P4: rdmsr(0x1A0, &r); if(!(r & 0x0000000000000080LL)) return; for(i = 0; i < 18; i++) wrmsr(0x300+i, 0); /* perfctr */ for(i = 0; i < 18; i++) wrmsr(0x360+i, 0); /* ccr */ for(i = 0; i < 31; i++) wrmsr(0x3A0+i, 0); /* escr */ for(i = 0; i < 6; i++) wrmsr(0x3C0+i, 0); /* escr */ for(i = 0; i < 6; i++) wrmsr(0x3C8+i, 0); /* escr */ for(i = 0; i < 2; i++) wrmsr(0x3E0+i, 0); /* escr */ if(!(r & 0x0000000000001000LL)){ for(i = 0; i < 2; i++) wrmsr(0x3F1+i, 0); /* pebs */ } lapicnmienable(); wrmsr(0x3B8, 0x000000007E00000CLL); /* escr0 */ r = 0x0000000004FF8000ULL; wrmsr(0x36C, r); /* cccr0 */ wrmsr(0x30C, -t); wrmsr(0x36C, 0x0000000000001000LL|r); break; case K6: case K8: /* * PerfEvtSel 0-3, PerfCtr 0-4. */ for(i = 0; i < 8; i++) wrmsr(0xC0010000+i, 0); lapicnmienable(); evntsel = 0x00130000|0x76; wrmsr(0xC0010004, -t); wrmsr(0xC0010000, 0x00400000|evntsel); break; } iunlock(wd); }
int main(int argc, char *argv[]) { struct configuration config; parse_options(argc, argv, &config); int sock; /* Create the UDP socket */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { Die("Failed to create socket"); } set_socket_reuse(sock); int on = 1; setsockopt(sock, SOL_IP, IP_PKTINFO, &on, sizeof(on)); do_ts_sockopt(sock); struct sockaddr_in server_addr; make_address(config.server_ip, config.server_port, &server_addr); struct sockaddr_in client_addr; make_address(config.host_ip, config.host_port, &client_addr); if(bind(sock, (struct sockaddr*)&client_addr, sizeof(client_addr)) < 0){ Die("bind"); } struct sockaddr_in recv_addr; make_address(0, 0, &recv_addr); char buffer[config.msg_size]; unsigned int clientlen; clientlen = sizeof(client_addr); struct msghdr msg; struct iovec iov; char control[1024]; int got; iov.iov_base = buffer; iov.iov_len = config.msg_size; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_namelen = sizeof(struct sockaddr_in); msg.msg_control = control; msg.msg_controllen = 1024; msg.msg_name = &recv_addr; char pay_load[config.msg_size]; const int timestamp_per_sample = 1; size_t result_len = sizeof(struct timespec)*timestamp_per_sample*config.max_packets; struct timespec (*result)[timestamp_per_sample] = (struct timespec ((*)[timestamp_per_sample]))malloc(result_len); memset(result[0], 0, result_len); int i; runoncpu(3); for(i = 0; i < config.max_packets; i++){ do { got = recvmsg(sock, &msg, MSG_ERRQUEUE); } while (got < 0 && errno == EAGAIN); if(got >= 0){ keep_time(&msg, result[i]+1); }else{ DEBUG("Unable to get TX_TIMESTAMPING\n"); } } FILE* outfile; outfile = fopen("result_send_nic.txt", "w"); for(i = 0; i < config.max_packets; i++){ int j; for (j = 0; j < timestamp_per_sample; j++){ if (j < timestamp_per_sample-1){ fprintf(outfile, "%ld,%9ld,", result[i][j].tv_sec, result[i][j].tv_nsec); }else{ fprintf(outfile, "%ld,%9ld\n", result[i][j].tv_sec, result[i][j].tv_nsec); } } } close(outfile); close(sock); exit(0); }