int gencost(int netdistr[],register int total,register int hor) { register int mh; /* mh == (1+i) % hor */ register int v; int i,minh=BIG,minv=BIG,maxh=SMALL,maxv=SMALL,nsubarea=0,cost; for (mh=1,v=1,i=0; i<total; ++i) { if (netdistr[i] > 0) { ++nsubarea; if (v<minv) minv=v; if (v>maxv) maxv=v; if (mh<minh) minh=mh; if (mh>maxh) maxh=mh; } else if (netdistr[i] < 0) { fprintf(stderr,"gencost: netdistr[%1d] contains negative number: %1d\n", i,netdistr[i]); dumpcore(); } if (++mh>hor) { ++v; mh=1; } } cost=(1+maxv-minv)*(1+maxh-minh)+nsubarea; return(cost>0 ? cost : 0); }
int cost16x4(int netdistr[],int numparts) { if (numparts!=64) { fprintf(stderr,"\ncost16x4: numparts must be 64, not %1d\n",numparts); dumpcore(); } return(gencost(netdistr,64,16)); }
int cost5x4(int netdistr[],int numparts) { if (numparts!=20) { fprintf(stderr,"\ncost5x4: numparts must be 20, not %1d\n",numparts); dumpcore(); } return(gencost(netdistr,20,5)); }
int cost8x4(int netdistr[],int numparts) { if (numparts!=32) { fprintf(stderr,"\ncost8x4: numparts must be 32, not %1d\n",numparts); dumpcore(); } return(gencost(netdistr,32,8)); }
int cost3x3(int netdistr[],int numparts) { if (numparts!=9) { fprintf(stderr,"\ncost3x3: numparts must be 9, not %1d\n",numparts); dumpcore(); } return(gencost(netdistr,9,3)); }
int cost4x4(int netdistr[],int numparts) { if (numparts!=16) { fprintf(stderr,"\ncost4x4: numparts must be 16, not %1d\n",numparts); dumpcore(); } return(gencost(netdistr,16,4)); }
void free_server(aServer *serv) { aClient *cptr = serv->bcptr; /* decrement reference counter, and eventually free it */ if (--serv->refcnt <= 0) { if (serv->refcnt == -211001) { /* Loop detected, break it. * XXX: Remove loop detection before 2.11.0 - jv */ sendto_flag(SCH_DEBUG, "* %#x free_server loop %s *", serv, serv->namebuf); return; } /* Decrease (and possibly free) refcnt of the user struct * of who connected this server. */ if (serv->user) { int cnt = serv->refcnt; serv->refcnt = -211000; /* Loop detection */ free_user(serv->user); serv->user = NULL; serv->refcnt = cnt; } if (serv->refcnt < 0 || serv->prevs || serv->nexts || serv->bcptr || serv->user) { char buf[512]; sprintf(buf, "%d %p %p %p %p (%s)", serv->refcnt, (void *)serv->prevs, (void *)serv->nexts, (void *)serv->user, (void *)serv->bcptr, (serv->bcptr) ? serv->bcptr->name : "none"); #ifdef DEBUGMODE dumpcore("%#x server %s %s", cptr, cptr ? cptr->name : "<noname>", buf); servs.inuse--; #else sendto_flag(SCH_ERROR, "* %#x server %s %s *", cptr, cptr ? cptr->name : "<noname>", buf); #endif } MyFree(serv); } }
int main(int argc, char *argv[]) { pid_t pid; int r, status; if(argc != 2) { printf("usage: %s <pid>\n", argv[0]); return 1; } pid = atoi(argv[1]); if (ptrace(T_ATTACH, pid, 0, 0) != 0) { perror("ptrace(T_ATTACH)"); return 1; } if (waitpid(pid, &status, 0) != pid) { perror("waitpid"); return 1; } while (WIFSTOPPED(status) && WSTOPSIG(status) != SIGSTOP) { /* whatever happens here is fine */ ptrace(T_RESUME, pid, 0, WSTOPSIG(status)); if (waitpid(pid, &status, 0) != pid) { perror("waitpid"); return 1; } } if (!WIFSTOPPED(status)) { fprintf(stderr, "process died while attaching\n"); return 1; } r = dumpcore(pid); if (ptrace(T_DETACH, pid, 0, 0)) { fprintf(stderr, "warning, detaching failed (%s)\n", strerror(errno)); } return r; }
/* ** off_history ** This must be called when the client structure is about to ** be released. History mechanism keeps pointers to client ** structures and it must know when they cease to exist. This ** also implicitly calls AddHistory. */ void off_history(aClient *cptr) { Reg Link *uwas; /* ** If the client has uwas entry/ies, there are also entries in ** the whowas array which point back to it. ** They have to be removed, by pairs */ while ((uwas = cptr->user->uwas)) { if (was[uwas->value.i].ww_online != cptr) #ifdef DEBUGMODE dumpcore("was[%d]: %#x != %#x", uwas->value.i, was[uwas->value.i].ww_online, cptr); #else sendto_flag(SCH_ERROR, "was[%d]: %#x != %#x", uwas->value.i, was[uwas->value.i].ww_online, cptr); #endif /* ** using &me to make ww_online non NULL (nicknames to be ** locked). &me can safely be used, it is constant. */ was[uwas->value.i].ww_online = &me; cptr->user->uwas = uwas->next; free_link(uwas); istat.is_wwuwas--; } istat.is_wwusers++; if (cptr->user->away) { istat.is_wwaways++; istat.is_wwawaysmem += strlen(cptr->user->away) + 1; } return; }
int costquad(int netdistr[],int numparts) { static int quadcost[16]= { 0,0,0,1, 0,1,2,2, 0,2,1,2, 1,2,2,3 }; int bit=1,j,index; if (numparts!=4) { fprintf(stderr,"costquad: cannot compute cost for %1d partitions!\n",numparts); dumpcore(); } for (index=0,j=0; j<numparts; ++j, bit<<=1) if (netdistr[j]!=0) index+=bit; if (index>=16 || index<0) err(5,"costquad: internal error 657"); return(quadcost[index]); }
int runsilent(int argc,char **argv,int curargc) { if(argc > MAXCMD-1) { printf("Simulator run program, invoked with to many args (%d limit)\n", MAXCMD); return(1); } for(cmdcount = 1; curargc < argc; curargc++, cmdcount++) { cmdptrs[cmdcount] = argv[curargc]; } cmdptrs[cmdcount] = ""; if(run() == -1) { (void)dumpcore(); exit(1); } return(m88000.Regs[2]); }
/* ** add_history ** Add the currently defined name of the client to history. ** usually called before changing to a new name (nick). ** Client must be a fully registered user (specifically, ** the user structure must have been allocated). ** if nodelay is NULL, then the nickname will be subject to NickDelay */ void add_history(aClient *cptr, aClient *nodelay) { Reg aName *np; Reg Link *uwas; cptr->user->refcnt++; np = &was[ww_index]; if ((np->ww_online && (np->ww_online != &me)) && !(np->ww_user && np->ww_user->uwas)) #ifdef DEBUGMODE dumpcore("whowas[%d] %#x %#x %#x", ww_index, np->ww_online, np->ww_user, np->ww_user->uwas); #else sendto_flag(SCH_ERROR, "whowas[%d] %#x %#x %#x", ww_index, np->ww_online, np->ww_user, np->ww_user->uwas); #endif /* ** The entry to be overwritten in was[] is still online. ** its uwas has to be updated */ if (np->ww_online && (np->ww_online != &me)) { Reg Link **old_uwas; old_uwas = &(np->ww_user->uwas); /* (*old_uwas) should NEVER happen to be NULL. -krys */ while ((*old_uwas)->value.i != ww_index) old_uwas = &((*old_uwas)->next); uwas = *old_uwas; *old_uwas = uwas->next; free_link(uwas); free_user(np->ww_user); istat.is_wwuwas--; } else if (np->ww_user) { /* ** Testing refcnt here is quite ugly, and unexact. ** Nonetheless, the result is almost correct, and another ** ugly thing in free_server() shoud make it exact. ** The problem is that 1 anUser structure might be ** referenced several times from whowas[] but is only counted ** once. One knows when to add, not when to substract - krys */ if (np->ww_user->refcnt == 1) { istat.is_wwusers--; if (np->ww_user->away) { istat.is_wwaways--; istat.is_wwawaysmem -=strlen(np->ww_user->away) + 1; } } free_user(np->ww_user); } if (np->ww_logout != 0) { int elapsed = timeofday - np->ww_logout; /* some stats */ ircstp->is_wwcnt++; ircstp->is_wwt += elapsed; if (elapsed < ircstp->is_wwmt) ircstp->is_wwmt = elapsed; if (elapsed > ircstp->is_wwMt) ircstp->is_wwMt = elapsed; if (np->ww_online == NULL) { if (locked[lk_index].logout) { elapsed = timeofday - locked[lk_index].logout; /* some stats first */ ircstp->is_lkcnt++; ircstp->is_lkt += elapsed; if (elapsed < ircstp->is_lkmt) ircstp->is_lkmt = elapsed; if (elapsed > ircstp->is_lkMt) ircstp->is_lkMt = elapsed; } /* ** This nickname has to be locked, thus copy it to the ** lock[] array. */ strcpy(locked[lk_index].nick, np->ww_nick); locked[lk_index++].logout = np->ww_logout; if ((lk_index == lk_size) && (lk_size != ww_size)) { grow_locked(); } if (lk_index >= lk_size) lk_index = 0; } } if (nodelay == cptr) /* &me is NOT a valid value, see off_history() */ { /* ** The client is online, np->ww_online is going to point to ** it. The client user struct has to point to this entry ** as well for faster off_history() ** this uwas, and the ww_online form a pair. */ uwas = make_link(); istat.is_wwuwas++; /* ** because of reallocs, one can not store a pointer inside ** the array. store the index instead. */ uwas->value.i = ww_index; uwas->flags = timeofday; uwas->next = cptr->user->uwas; cptr->user->uwas = uwas; } np->ww_logout = timeofday; np->ww_user = cptr->user; np->ww_online = (nodelay != NULL) ? nodelay : NULL; strncpyzt(np->ww_nick, cptr->name, NICKLEN+1); strncpyzt(np->ww_info, cptr->info, REALLEN+1); ww_index++; if ((ww_index == ww_size) && (numclients > ww_size)) grow_whowas(); if (ww_index >= ww_size) ww_index = 0; return; }
/* ** free_user ** Decrease user reference count by one and release block, ** if count reaches 0 */ void free_user(anUser *user) { aServer *serv; aClient *cptr = user->bcptr; if (--user->refcnt <= 0) { /* Loop: This would be second deallocation of this structure. * XXX: Remove loop detection before 2.11.0 - jv */ if (user->refcnt == -211001) { sendto_flag(SCH_ERROR, "* %p free_user loop (%s!%s@%s) %p *", (void *)cptr, cptr ? cptr->name : "<noname>", user->username, user->host, user); return; } /* * sanity check */ if (user->joined || user->refcnt < 0 || user->invited || user->channel || user->uwas || user->bcptr) { char buf[512]; /*too many arguments for dumpcore() and sendto_flag()*/ sprintf(buf, "%p %p %p %p %d %d %p (%s)", (void *)user, (void *)user->invited, (void *)user->channel, (void *)user->uwas, user->joined, user->refcnt, (void *)user->bcptr, (user->bcptr) ? user->bcptr->name :"none"); #ifdef DEBUGMODE dumpcore("%p user (%s!%s@%s) %s", (void *)cptr, cptr ? cptr->name : "<noname>", user->username, user->host, buf); #else sendto_flag(SCH_ERROR, "* %p user (%s!%s@%s) %s *", (void *)cptr, cptr ? cptr->name : "<noname>", user->username, user->host, buf); #endif } if ((serv = user->servp)) { user->servp = NULL; /* to avoid some impossible loop */ user->refcnt = -211000; /* For loop detection */ free_server(serv); } if (user->away) { istat.is_away--; istat.is_awaymem -= (strlen(user->away) + 1); MyFree(user->away); } MyFree(user); #ifdef DEBUGMODE users.inuse--; #endif } }
int main(int argc,char *argv[]) { struct userdata ud; int rc; if (argc == 1) { fprintf(stderr,"usage: %s imagefile loadaddr ... \n",argv[0]); fprintf(stderr,"\tloadaddr = HHHH[r] where H = hexdigit,\n"); fprintf(stderr,"\t and r = r (for read only)\n"); return EXIT_FAILURE; } ud.memory = malloc(65536uL * sizeof(mc6809byte__t)); if (ud.memory == NULL) { perror("malloc()"); return EXIT_FAILURE; } ud.readonly = calloc(65536uL,sizeof(bool)); if (ud.readonly == NULL) { perror("malloc()"); free(ud.memory); return EXIT_FAILURE; } ud.cpu.user = &ud; ud.cpu.read = cpu_read; ud.cpu.write = cpu_write; ud.cpu.fault = cpu_fault; ud.dis.user = &ud; ud.dis.read = dis_read; ud.dis.fault = dis_fault; for ( int i = 1 ; i < argc ; i += 2 ) { if (!loadimage(&ud,argv[i],argv[i + 1])) { perror(argv[i]); free(ud.readonly); free(ud.memory); return EXIT_FAILURE; } } mc6809_reset(&ud.cpu); rc = mc6809_run(&ud.cpu); if (rc != 0) { switch(rc) { default: case MC6809_FAULT_INTERNAL_ERROR: fprintf(stderr,"An internal error occured that should not happen.\n"); break; case MC6809_FAULT_INSTRUCTION: fprintf(stderr,"Illegal instruction @ %04X\n",ud.cpu.pc.w - 1); break; case MC6809_FAULT_ADDRESS_MODE: fprintf(stderr,"Illegal addressing mode in instruction @ %04X\n",ud.cpu.instpc); break; case MC6809_FAULT_EXG: fprintf(stderr,"Undefined EXG behavior in instruction @ %04X\n",ud.cpu.instpc); break; case MC6809_FAULT_TFR: fprintf(stderr,"Undefined TFR behavior in instruction @ %04X\n",ud.cpu.instpc); break; case MC6809_FAULT_user: fprintf(stderr, "This can be used to signal other errors, but you should\n" "only see this if you check the source code.\n" ); break; } dumpcore(&ud); } free(ud.readonly); free(ud.memory); return rc; }