/* start simulation, program loaded, processor precise state initialized */ void sim_main(void) { int i; md_inst_t inst; register md_addr_t addr; enum md_opcode op; register int is_write; enum md_fault_type fault; fprintf(stderr, "sim: ** starting functional simulation w/ caches **\n"); /* set up initial default next PC */ regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t); /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0)) dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC, sim_num_insn, ®s, mem); while (TRUE) { /* maintain $r0 semantics */ regs.regs_R[MD_REG_ZERO] = 0; #ifdef TARGET_ALPHA regs.regs_F.d[MD_REG_ZERO] = 0.0; #endif /* TARGET_ALPHA */ /* get the next instruction to execute */ if (itlb) cache_access(itlb, Read, IACOMPRESS(regs.regs_PC), NULL, ISCOMPRESS(sizeof(md_inst_t)), 0, NULL, NULL, 0); if (cache_il1) cache_access(cache_il1, Read, IACOMPRESS(regs.regs_PC), NULL, ISCOMPRESS(sizeof(md_inst_t)), 0, NULL, NULL, 0); MD_FETCH_INST(inst, mem, regs.regs_PC); /* keep an instruction count */ sim_num_insn++; /* set default reference address and access mode */ addr = 0; is_write = FALSE; /* set default fault - none */ fault = md_fault_none; /* decode the instruction */ MD_SET_OPCODE(op, inst); /* execute the instruction */ switch (op) { #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \ case OP: \ SYMCAT(OP,_IMPL); \ break; #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) \ case OP: \ panic("attempted to execute a linking opcode"); #define CONNECT(OP) #define DECLARE_FAULT(FAULT) \ { fault = (FAULT); break; } #include "machine.def" default: panic("attempted to execute a bogus opcode"); } if (fault != md_fault_none) fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC); if (MD_OP_FLAGS(op) & F_MEM) { sim_num_refs++; if (MD_OP_FLAGS(op) & F_STORE) is_write = TRUE; } /* update any stats tracked by PC */ for (i=0; i < pcstat_nelt; i++) { counter_t newval; int delta; /* check if any tracked stats changed */ newval = STATVAL(pcstat_stats[i]); delta = newval - pcstat_lastvals[i]; if (delta != 0) { stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta); pcstat_lastvals[i] = newval; } } /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_NPC, is_write ? ACCESS_WRITE : ACCESS_READ, addr, sim_num_insn, sim_num_insn)) dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, ®s, mem); /* go to the next instruction */ regs.regs_PC = regs.regs_NPC; regs.regs_NPC += sizeof(md_inst_t); /* finish early? */ if (max_insts && sim_num_insn >= max_insts) return; } }
/* register simulator-specific statistics */ void sim_reg_stats(struct stat_sdb_t *sdb) /* stats database */ { int i; /* register baseline stats */ stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, sim_num_insn, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores executed", &sim_num_refs, 0, NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); /* register cache stats */ if (cache_il1 && (cache_il1 != cache_dl1 && cache_il1 != cache_dl2)) cache_reg_stats(cache_il1, sdb); if (cache_il2 && (cache_il2 != cache_dl1 && cache_il2 != cache_dl2)) cache_reg_stats(cache_il2, sdb); if (cache_dl1) cache_reg_stats(cache_dl1, sdb); if (cache_dl2) cache_reg_stats(cache_dl2, sdb); if (itlb) cache_reg_stats(itlb, sdb); if (dtlb) cache_reg_stats(dtlb, sdb); for (i=0; i<pcstat_nelt; i++) { char buf[512], buf1[512]; struct stat_stat_t *stat; /* track the named statistical variable by text address */ /* find it... */ stat = stat_find_stat(sdb, pcstat_vars[i]); if (!stat) fatal("cannot locate any statistic named `%s'", pcstat_vars[i]); /* stat must be an integral type */ if (stat->sc != sc_int && stat->sc != sc_uint && stat->sc != sc_counter) fatal("`-pcstat' statistical variable `%s' is not an integral type", stat->name); /* register this stat */ pcstat_stats[i] = stat; pcstat_lastvals[i] = STATVAL(stat); /* declare the sparce text distribution */ sprintf(buf, "%s_by_pc", stat->name); sprintf(buf1, "%s (by text address)", stat->desc); pcstat_sdists[i] = stat_reg_sdist(sdb, buf, buf1, /* initial value */0, /* print fmt */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } ld_reg_stats(sdb); mem_reg_stats(mem, sdb); }
/* register simulator-specific statistics */ void sim_reg_stats(struct stat_sdb_t *sdb) { int i; stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, sim_num_insn, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores executed", &sim_num_refs, 0, NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); if (prof_ic) { /* instruction class profile */ ic_prof = stat_reg_dist(sdb, "sim_inst_class_prof", "instruction class profile", /* initial value */0, /* array size */ic_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_class_str, /* print fn */NULL); } if (prof_inst) { int i; char buf[512]; /* conjure up appropriate instruction description strings */ for (i=0; i < /* skip NA */OP_MAX-1; i++) { sprintf(buf, "%-8s %-6s", md_op2name[i+1], md_op2format[i+1]); inst_str[i] = mystrdup(buf); } /* instruction profile */ inst_prof = stat_reg_dist(sdb, "sim_inst_prof", "instruction profile", /* initial value */0, /* array size */ /* skip NA */OP_MAX-1, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_str, /* print fn */NULL); } if (prof_bc) { /* instruction branch profile */ bc_prof = stat_reg_dist(sdb, "sim_branch_prof", "branch instruction profile", /* initial value */0, /* array size */bc_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */branch_class_str, /* print fn */NULL); } if (prof_am) { /* instruction branch profile */ am_prof = stat_reg_dist(sdb, "sim_addr_mode_prof", "addressing mode profile", /* initial value */0, /* array size */md_amode_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */md_amode_str, /* print fn */NULL); } if (prof_seg) { /* instruction branch profile */ seg_prof = stat_reg_dist(sdb, "sim_addr_seg_prof", "load/store address segment profile", /* initial value */0, /* array size */seg_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */addr_seg_str, /* print fn */NULL); } if (prof_tsyms && sym_ntextsyms != 0) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ tsym_names = (char **)calloc(sym_ntextsyms, sizeof(char *)); for (i=0; i < sym_ntextsyms; i++) tsym_names[i] = sym_textsyms[i]->name; /* text symbol profile */ tsym_prof = stat_reg_dist(sdb, "sim_text_sym_prof", "text symbol profile", /* initial value */0, /* array size */sym_ntextsyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */tsym_names, /* print fn */NULL); } if (prof_dsyms && sym_ndatasyms != 0) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ dsym_names = (char **)calloc(sym_ndatasyms, sizeof(char *)); for (i=0; i < sym_ndatasyms; i++) dsym_names[i] = sym_datasyms[i]->name; /* data symbol profile */ dsym_prof = stat_reg_dist(sdb, "sim_data_sym_prof", "data symbol profile", /* initial value */0, /* array size */sym_ndatasyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */dsym_names, /* print fn */NULL); } if (prof_taddr) { /* text address profile (sparse profile), NOTE: a dense print format is used, its more difficult to read, but the profiles are *much* smaller, I've assumed that the profiles are read by programs, at least for your sake I hope this is the case!! */ taddr_prof = stat_reg_sdist(sdb, "sim_text_addr_prof", "text address profile", /* initial value */0, /* print format */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } for (i=0; i<pcstat_nelt; i++) { char buf[512], buf1[512]; struct stat_stat_t *stat; /* track the named statistical variable by text address */ /* find it... */ stat = stat_find_stat(sdb, pcstat_vars[i]); if (!stat) fatal("cannot locate any statistic named `%s'", pcstat_vars[i]); /* stat must be an integral type */ if (stat->sc != sc_int && stat->sc != sc_uint && stat->sc != sc_counter) fatal("`-pcstat' statistical variable `%s' is not an integral type", stat->name); /* register this stat */ pcstat_stats[i] = stat; pcstat_lastvals[i] = STATVAL(stat); /* declare the sparce text distribution */ sprintf(buf, "%s_by_pc", stat->name); sprintf(buf1, "%s (by text address)", stat->desc); pcstat_sdists[i] = stat_reg_sdist(sdb, buf, buf1, /* initial value */0, /* print format */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } ld_reg_stats(sdb); mem_reg_stats(mem, sdb); }
/* start simulation, program loaded, processor precise state initialized */ void sim_main(void) { int i; md_inst_t inst; register md_addr_t addr; register int is_write; enum md_opcode op; unsigned int flags; enum md_fault_type fault; fprintf(stderr, "sim: ** starting functional simulation **\n"); /* set up initial default next PC */ regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t); /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0)) dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC, sim_num_insn, ®s, mem); while (TRUE) { /* maintain $r0 semantics */ regs.regs_R[MD_REG_ZERO] = 0; #ifdef TARGET_ALPHA regs.regs_F.d[MD_REG_ZERO] = 0.0; #endif /* TARGET_ALPHA */ /* get the next instruction to execute */ mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t)); if (verbose) { myfprintf(stderr, "%10n @ 0x%08p: ", sim_num_insn, regs.regs_PC); md_print_insn(inst, regs.regs_PC, stderr); fprintf(stderr, "\n"); /* fflush(stderr); */ } /* keep an instruction count */ sim_num_insn++; /* set default reference address and access mode */ addr = 0; is_write = FALSE; /* set default fault - none */ fault = md_fault_none; /* decode the instruction */ MD_SET_OPCODE(op, inst); /* execute the instruction */ switch (op) { #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \ case OP: \ SYMCAT(OP,_IMPL); \ break; #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) \ case OP: \ panic("attempted to execute a linking opcode"); #define CONNECT(OP) #define DECLARE_FAULT(FAULT) \ { fault = (FAULT); break; } #include "machine.def" default: panic("attempted to execute a bogus opcode"); } if (MD_OP_FLAGS(op) & F_MEM) { sim_num_refs++; if (MD_OP_FLAGS(op) & F_STORE) is_write = TRUE; } /* * profile this instruction */ flags = MD_OP_FLAGS(op); if (prof_ic) { enum inst_class_t ic; /* compute instruction class */ if (flags & F_LOAD) ic = ic_load; else if (flags & F_STORE) ic = ic_store; else if (flags & F_UNCOND) ic = ic_uncond; else if (flags & F_COND) ic = ic_cond; else if (flags & F_ICOMP) ic = ic_icomp; else if (flags & F_FCOMP) ic = ic_fcomp; else if (flags & F_TRAP) ic = ic_trap; else panic("instruction has no class"); /* update instruction class profile */ stat_add_sample(ic_prof, (int)ic); } if (prof_inst) { /* update instruction profile */ stat_add_sample(inst_prof, (int)op - /* skip NA */1); } if (prof_bc) { enum branch_class_t bc; /* compute instruction class */ if (flags & F_CTRL) { if ((flags & (F_CALL|F_DIRJMP)) == (F_CALL|F_DIRJMP)) bc = bc_call_dir; else if ((flags & (F_CALL|F_INDIRJMP)) == (F_CALL|F_INDIRJMP)) bc = bc_call_indir; else if ((flags & (F_UNCOND|F_DIRJMP)) == (F_UNCOND|F_DIRJMP)) bc = bc_uncond_dir; else if ((flags & (F_UNCOND|F_INDIRJMP))== (F_UNCOND|F_INDIRJMP)) bc = bc_uncond_indir; else if ((flags & (F_COND|F_DIRJMP)) == (F_COND|F_DIRJMP)) bc = bc_cond_dir; else if ((flags & (F_COND|F_INDIRJMP)) == (F_COND|F_INDIRJMP)) bc = bc_cond_indir; else panic("branch has no class"); /* update instruction class profile */ stat_add_sample(bc_prof, (int)bc); } } if (prof_am) { enum md_amode_type am; /* update addressing mode pre-probe FSM */ MD_AMODE_PREPROBE(op, fsm); /* compute addressing mode */ if (flags & F_MEM) { /* compute addressing mode */ MD_AMODE_PROBE(am, op, fsm); /* update the addressing mode profile */ stat_add_sample(am_prof, (int)am); /* addressing mode pre-probe FSM, after all loads and stores */ MD_AMODE_POSTPROBE(fsm); } } if (prof_seg) { if (flags & F_MEM) { /* update instruction profile */ stat_add_sample(seg_prof, (int)bind_to_seg(addr)); } } if (prof_tsyms) { int tindex; /* attempt to bind inst address to a text segment symbol */ sym_bind_addr(regs.regs_PC, &tindex, /* !exact */FALSE, sdb_text); if (tindex >= 0) { if (tindex > sym_ntextsyms) panic("bogus text symbol index"); stat_add_sample(tsym_prof, tindex); } /* else, could not bind to a symbol */ } if (prof_dsyms) { int dindex; if (flags & F_MEM) { /* attempt to bind inst address to a text segment symbol */ sym_bind_addr(addr, &dindex, /* !exact */FALSE, sdb_data); if (dindex >= 0) { if (dindex > sym_ndatasyms) panic("bogus data symbol index"); stat_add_sample(dsym_prof, dindex); } /* else, could not bind to a symbol */ } } if (prof_taddr) { /* add regs_PC exec event to text address profile */ stat_add_sample(taddr_prof, regs.regs_PC); } /* update any stats tracked by PC */ for (i=0; i<pcstat_nelt; i++) { counter_t newval; int delta; /* check if any tracked stats changed */ newval = STATVAL(pcstat_stats[i]); delta = newval - pcstat_lastvals[i]; if (delta != 0) { stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta); pcstat_lastvals[i] = newval; } } /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_NPC, is_write ? ACCESS_WRITE : ACCESS_READ, addr, sim_num_insn, sim_num_insn)) dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, ®s, mem); /* go to the next instruction */ regs.regs_PC = regs.regs_NPC; regs.regs_NPC += sizeof(md_inst_t); /* finish early? */ if (max_insts && sim_num_insn >= max_insts) return; } }
int SSDP::Start(){ int ret = 0; u32 optval = 0; if(mMulticastSocket != INVALID_SOCKET || mUnicastSocket != INVALID_SOCKET){ ret = -9; goto EXIT; } // //Setup the Multicast Socket // mMulticastSocket = socket(PF_INET, SOCK_DGRAM, 0); STATNVAL(mMulticastSocket, INVALID_SOCKET, EXIT); //Set nonblocking optval = fcntl( mMulticastSocket, F_GETFL, 0 ); STATNVAL(optval, -1, CLEAN_AND_EXIT); ret = fcntl(mMulticastSocket, F_SETFL, optval | O_NONBLOCK); STATNVAL(ret, -1, CLEAN_AND_EXIT); //Source address mSrcaddr.sin_family = PF_INET; mSrcaddr.sin_port = 0; //Let the IP stack decide mSrcaddr.sin_addr.s_addr = INADDR_ANY; //Default multicast nic //Reuse port optval = 1; ret = setsockopt(mMulticastSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, 4); STATVAL(ret, 0, CLEAN_AND_EXIT); optval = 1; ret = setsockopt(mMulticastSocket, SOL_SOCKET, SO_REUSEPORT, (char*)&optval, 4); STATVAL(ret, 0, CLEAN_AND_EXIT); //Disable loopback optval = 0; ret = setsockopt(mMulticastSocket, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&optval, sizeof(int)); STATNVAL(ret, SOCKET_ERROR, CLEAN_AND_EXIT); //TTL optval = mTTL; ret = setsockopt(mMulticastSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&optval, sizeof(int)); STATNVAL(ret, SOCKET_ERROR, CLEAN_AND_EXIT); //Add membership mMreq.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDRESS); mMreq.imr_interface.s_addr = INADDR_ANY; ret = setsockopt(mMulticastSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mMreq, sizeof(struct ip_mreq)); STATNVAL(ret, SOCKET_ERROR, CLEAN_AND_EXIT); //Bind to all interface(s) ret = bind(mMulticastSocket, (struct sockaddr*)&mSrcaddr, sizeof(struct sockaddr)); if(ret < 0 && (errno == EACCES || errno == EADDRINUSE)) printf("address in use\n"); STATVAL(ret, 0, CLEAN_AND_EXIT); //Destination address mDstaddr.sin_family = PF_INET; mDstaddr.sin_addr.s_addr = inet_addr(SSDP_MCAST_ADDRESS); mDstaddr.sin_port = htons(SSDP_MCAST_PORT); // // Setup the Unicast Socket (We listen for Advertisements) // mUnicastSocket = socket(PF_INET, SOCK_DGRAM, 0); STATNVAL(mUnicastSocket, INVALID_SOCKET, EXIT); //Set nonblocking optval = fcntl( mUnicastSocket, F_GETFL, 0 ); STATNVAL(optval, -1, CLEAN_AND_EXIT); ret = fcntl(mUnicastSocket, F_SETFL, optval | O_NONBLOCK); STATNVAL(ret, -1, CLEAN_AND_EXIT); //Source address mUnicastSrcaddr.sin_family = PF_INET; mUnicastSrcaddr.sin_port = htons(SSDP_MCAST_PORT); mUnicastSrcaddr.sin_addr.s_addr = INADDR_ANY; //Default nic //Reuse port optval = 1; ret = setsockopt(mUnicastSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, 4); STATVAL(ret, 0, CLEAN_AND_EXIT); optval = 1; ret = setsockopt(mUnicastSocket, SOL_SOCKET, SO_REUSEPORT, (char*)&optval, 4); STATVAL(ret, 0, CLEAN_AND_EXIT); //Join Multicast group mMreqU.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDRESS); mMreqU.imr_interface.s_addr = INADDR_ANY; ret = setsockopt(mUnicastSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mMreqU, sizeof(struct ip_mreq)); STATNVAL(ret, SOCKET_ERROR, CLEAN_AND_EXIT); //Bind to all interface(s) ret = bind(mUnicastSocket, (struct sockaddr*)&mUnicastSrcaddr, sizeof(struct sockaddr)); if(ret < 0 && (errno == EACCES || errno == EADDRINUSE)) printf("address in use\n"); STATVAL(ret, 0, CLEAN_AND_EXIT); //Start the read thread pthread_attr_t attr; ret = pthread_attr_init(&attr); if(ret != 0){ goto CLEAN_AND_EXIT; } ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if(ret != 0){ pthread_attr_destroy(&attr); goto CLEAN_AND_EXIT; } ret = pthread_create(&mReadThread, &attr, SSDP::sReadLoop, (void*)this); pthread_attr_destroy(&attr); goto EXIT; CLEAN_AND_EXIT: close(mMulticastSocket); mMulticastSocket = INVALID_SOCKET; close(mUnicastSocket); mUnicastSocket = INVALID_SOCKET; EXIT: return ret; }