static Key * parsechain(const char *s, const char *e, Key *spec) { const char *p, *q; Key *chain = NULL, *last = NULL; XPRINTF("Parsing chain from: '%s'\n", s); for (p = s; p < e; p = (*q == ':' ? q + 1 : q)) { Key *k; for (q = p; q < e && (isalnum(*q) || isblank(*q) || *q == '_' || *q == '+'); q++) ; if (q < e && *q != ':') q = e; k = ecalloc(1, sizeof(*k)); *k = *spec; if (!parsekey(p, q, k)) { freekey(k); freechain(chain); chain = last = NULL; break; } chain = chain ? : k; if (last) { last->func = &k_chain; last->chain = k; } last = k; } if (chain) XPRINTF("Parsed chain: %s\n", showchain(chain)); return chain; }
void addchain(Key *k) { Key **kp; XPRINTF("Adding chain: %s ...\n", showchain(k)); for (kp = &scr->keylist; *kp; kp = &(*kp)->cnext) if ((*kp)->mod == k->mod && (*kp)->keysym == k->keysym) break; if (*kp) { XPRINTF("Overlapping key definition %s\n", XKeysymToString(k->keysym)); if ((*kp)->chain && k->chain) mergechain(*kp, k); else { XPRINTF("Overriding previous key definition: %s!\n", showchain(k)); k->cnext = (*kp)->cnext; (*kp)->cnext = NULL; freechain(*kp); *kp = k; } XPRINTF("... added chain: %s\n", showchain(*kp)); } else { XPRINTF("Adding new key %s\n", XKeysymToString(k->keysym)); k->cnext = scr->keylist; scr->keylist = k; XPRINTF("... added chain: %s\n", showchain(k)); } }
/* * (*kp) and k have the same mod and keysym. Both have a non-null ->chain. * if there is a key in the (*kp)->chain list (*lp) that has the same mod and * keysm as k->chain, then free (*lp) and set its location to *kp->chain */ static void mergechain(Key *c, Key *k) { Key **lp; Key *next = k->chain; XPRINTF("Merging chain %s\n", showchain(k)); XPRINTF(" into chain %s\n", showchain(c)); k->chain = NULL; freekey(k); k = next; for (lp = &c->chain; *lp; lp = &(*lp)->cnext) if ((*lp)->mod == k->mod && (*lp)->keysym == k->keysym) break; if (*lp) { if ((*lp)->chain && k->chain) mergechain(*lp, k); else { XPRINTF("Overriding previous key alternate %s!\n", showchain(k)); k->cnext = (*lp)->cnext; (*lp)->cnext = NULL; freechain(*lp); *lp = k; } } else { k->cnext = NULL; *lp = k; } }
static int freechain(WlzLLink *l) { if (l != NULL) { freechain(l->l_link); AlcFree((char *) l); } return( 0 ); }
void freekeys(void) { Key *k, *knext; knext = scr->keylist; scr->keylist = NULL; while ((k = knext)) { knext = k->cnext; k->cnext = NULL; XPRINTF("Freeing key chain: %s\n", showchain(k)); freechain(k); } }
void freechain(Key *k) { Key *c, *cnext; if (k) { XPRINTF("Freeing chain: %p: %s\n", k, showchain(k)); cnext = k->chain; k->chain = NULL; while ((c = cnext)) { cnext = c->cnext; c->cnext = NULL; freechain(c); } freekey(k); } }
/* * Load the device policy. * The device policy currently makes nu distinction between the * block and characters devices; that is generally not a problem * as the names of those devices cannot clash. */ int devpolicy_load(int nitems, size_t sz, devplcysys_t *uitmp) { int i, j; int nmaj = 0; major_t lastmajor; devplcysys_t *items; size_t mem; major_t curmaj; devplcyent_t **last, *de; tableent_t *newpolicy, *oldpolicy; devplcy_t *newnull, *newdflt, *oldnull, *olddflt; int oldcnt; int lastlen; int lastwild; #ifdef lint /* Lint can't figure out that the "i == 1" test protects all */ lastlen = 0; lastwild = 0; lastmajor = 0; #endif /* * The application must agree with the kernel on the size of each * item; it must not exceed the maximum number and must be * at least 1 item in size. */ if (sz != sizeof (devplcysys_t) || nitems > maxdevpolicy || nitems < 1) return (EINVAL); mem = nitems * sz; items = kmem_alloc(mem, KM_SLEEP); if (copyin(uitmp, items, mem)) { kmem_free(items, mem); return (EFAULT); } /* Check for default policy, it must exist and be sorted first */ if (items[0].dps_maj != DEVPOLICY_DFLT_MAJ) { kmem_free(items, mem); return (EINVAL); } /* * Application must deliver entries sorted. * Sorted meaning here: * In major number order * For each major number, we first need to have the explicit * entries, then the wild card entries, longest first. */ for (i = 1; i < nitems; i++) { int len, wild; char *tmp; curmaj = items[i].dps_maj; len = strlen(items[i].dps_minornm); wild = len > 0 && (tmp = strchr(items[i].dps_minornm, '*')) != NULL; /* Another default major, string too long or too many ``*'' */ if (curmaj == DEVPOLICY_DFLT_MAJ || len >= sizeof (items[i].dps_minornm) || wild && strchr(tmp + 1, '*') != NULL) { kmem_free(items, mem); return (EINVAL); } if (i == 1 || lastmajor < curmaj) { lastmajor = curmaj; nmaj++; } else if (lastmajor > curmaj || lastwild > wild || lastwild && lastlen < len) { kmem_free(items, mem); return (EINVAL); } lastlen = len; lastwild = wild; } if (AU_AUDITING()) audit_devpolicy(nitems, items); /* * Parse the policy. We create an array for all major numbers * and in each major number bucket we'll have a linked list of * entries. Each item may contain either a lo,hi minor pair * or a string/wild card matching a minor node. */ if (nmaj > 0) newpolicy = kmem_zalloc(nmaj * sizeof (tableent_t), KM_SLEEP); /* * We want to lock out concurrent updates but we don't want to * lock out device opens while we still need to allocate memory. * As soon as we allocate new devplcy_t's we commit to the next * generation number, so we must lock out other updates from here. */ mutex_enter(&policymutex); /* New default and NULL policy */ newnull = dpget(); if (priv_isemptyset(&items[0].dps_rdp) && priv_isemptyset(&items[0].dps_wrp)) { newdflt = newnull; dphold(newdflt); } else { newdflt = dpget(); newdflt->dp_rdp = items[0].dps_rdp; newdflt->dp_wrp = items[0].dps_wrp; } j = -1; /* Userland made sure sorting was ok */ for (i = 1; i < nitems; i++) { de = parse_policy(&items[i], newnull, newdflt); if (j == -1 || curmaj != items[i].dps_maj) { j++; newpolicy[j].t_major = curmaj = items[i].dps_maj; last = &newpolicy[j].t_ent; } *last = de; last = &de->dpe_next; } /* Done parsing, throw away input */ kmem_free(items, mem); /* Lock out all devpolicy_find()s */ rw_enter(&policyrw, RW_WRITER); /* Install the new global data */ oldnull = nullpolicy; nullpolicy = newnull; olddflt = dfltpolicy; dfltpolicy = newdflt; oldcnt = ntabent; ntabent = nmaj; totitems = nitems; oldpolicy = devpolicy; devpolicy = newpolicy; /* Force all calls by devpolicy_find() */ devplcy_gen++; /* Reenable policy finds */ rw_exit(&policyrw); mutex_exit(&policymutex); /* Free old stuff */ if (oldcnt != 0) { for (i = 0; i < oldcnt; i++) freechain(oldpolicy[i].t_ent); kmem_free(oldpolicy, oldcnt * sizeof (*oldpolicy)); } dpfree(oldnull); dpfree(olddflt); return (0); }
extern void save_xsch(FILE* xsch_stream, lofig_list* lofig, ptype_list* long_path, int color_mode) { long color; ptype_list* ptype, *ptype2=NULL; float delay=0, delay_out=0; char mes[1024]; char* signame = NULL; locon_list* locon; losig_list* losig; float gradient=1; int count; loins_list* loins; char *source, *dest=NULL, *last_sig; chain_list* chain, *loinschain=NULL; chain_list* lofigchain; losig_list* losig_aux; /*build gradient*/ if (long_path && color_mode==XSCH_GRADIENT) { /*get time of last entry*/ count=1; for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) count++; if (!ptype->DATA) { fprintf(stderr,"save_xsch: compute error\n"); exit(1); } delay=ptype->TYPE; gradient=delay/((float)XSCH_COLOR_MAX); } /*color for signals*/ for (losig=lofig->LOSIG; losig; losig=losig->NEXT) { if (!losig->NAMECHAIN || !losig->NAMECHAIN->DATA) { fprintf(stderr,"save_xsch: no name for signal\n"); exit(1); } signame=losig->NAMECHAIN->DATA; if (isvdd(signame) || isvss(signame)) continue; if (losig->TYPE==EXTERNAL) { /*search external output*/ ptype=getptype(losig->USER,LOFIGCHAIN); for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; if (locon->TYPE==EXTERNAL && locon->DIRECTION!=IN) break; } if (lofigchain) delay=getdelay(output_name(signame)); else delay=getdelay(signame); } else delay=getdelay(signame); switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay,gradient); break; case XSCH_CRITICAL_PATH: default: color=XSCH_NEUTRAL_COLOR; break; } flush_losig(xsch_stream, signame, color, delay, losig->TYPE); } /*color for instances*/ for (loins=lofig->LOINS; loins; loins=loins->NEXT) { /*search signal output*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,loins->INSNAME); exit(1); } if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) break; } if (!locon) { fprintf(stderr,"save_xsch: no output found for '%s'\n",loins->INSNAME); exit(1); } losig=locon->SIG; signame=losig->NAMECHAIN->DATA; delay=getdelay(loins->INSNAME); switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay,gradient); break; case XSCH_CRITICAL_PATH: default: /*is instance in critical path?*/ for (ptype=long_path; ptype; ptype=ptype->NEXT) { if ((char*)ptype->DATA!=signame) continue; /*if output and input signals belong to critical path, then instance belongs*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue; losig_aux=locon->SIG; /*is signal in critical path?*/ for (ptype2=long_path; ptype2; ptype2=ptype2->NEXT) { if ((char*)ptype2->DATA==losig_aux->NAMECHAIN->DATA) break; } if (ptype2) break; } ptype=ptype2; /*found?*/ break; } /*build critical path list*/ if (ptype) loinschain=addchain(loinschain,loins); if (ptype) color=XSCH_RED_COLOR; else color=XSCH_NEUTRAL_COLOR; } flush_loins(xsch_stream, loins->INSNAME, color, delay); } /*color for connectors*/ for (locon=lofig->LOCON; locon; locon=locon->NEXT) { if (isvdd(locon->NAME) || isvss(locon->NAME)) continue; switch (locon->DIRECTION) { case IN: delay_out=getdelay(locon->NAME); sprintf(mes, "%d ps",(int)delay_out); break; case OUT: case TRISTATE: delay_out=getdelay(output_name(locon->NAME)); sprintf(mes, "%d ps",(int)delay_out); break; case INOUT: case TRANSCV: delay=getdelay(locon->NAME); delay_out=getdelay(output_name(locon->NAME)); sprintf(mes, "%d ps on input; %d ps on output",(int)delay,(int)delay_out); break; } switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay_out,gradient); break; case XSCH_CRITICAL_PATH: default: /* seek if signal is in a long path*/ for (ptype=long_path; ptype; ptype=ptype->NEXT) { if ((char*)ptype->DATA==locon->NAME) break; } if (ptype) color=XSCH_RED_COLOR; else color=XSCH_NEUTRAL_COLOR; } flush_stream_special(xsch_stream, locon->NAME, color, mes); } /*critical path*/ if (loinschain && long_path && color_mode==XSCH_CRITICAL_PATH) { source=NULL; last_sig=NULL; for (ptype=long_path; ptype; ptype=ptype->NEXT) { signame=ptype->DATA; for (chain=loinschain; chain; chain=chain->NEXT) { loins=chain->DATA; /*search signal output*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) { losig=locon->SIG; if (losig->NAMECHAIN->DATA==signame) { dest=loins->INSNAME; break; } } } if (locon) break; } /*if no instance found it is external connector. it has the same name than signal*/ if (!locon) dest=signame; if (source) flush_path(xsch_stream, source, last_sig, dest, XSCH_RED_COLOR, delay, INTERNAL); source=dest; last_sig=signame; } /*for last signal search output*/ if (losig) { ptype=getptype(losig->USER,LOFIGCHAIN); for (chain=ptype->DATA; chain; chain=chain->NEXT) { locon=chain->DATA; /*port of circuit*/ if (locon->TYPE==EXTERNAL) {dest=locon->NAME; break;} loins=locon->ROOT; /*register input if no error*/ if (locon->DIRECTION==IN || locon->DIRECTION==INOUT || locon->DIRECTION==TRANSCV) {dest=loins->INSNAME; break;} } flush_path(xsch_stream, source, signame, dest, XSCH_RED_COLOR, delay, losig->TYPE); } } freechain(loinschain); }
static void chainFree(void) { (void )freechain(allocthings.orig_base); }
static int insert_buffer(losig_list* losig, lofig_list* lofig, int optim_level, long index) { double capa, init_capa; cell_list* buffer; chain_list* namechain, *sigchain=NULL; char* signame; lofig_list* model; losig_list* losig_buf; loins_list* loins_buf; locon_list* locon; losig_list* losig_vdd=NULL, *losig_vss=NULL, *losig_aux; ptype_list* ptype, *buffer_ptype; double delay, best_delay, init_delay; loins_list* loins; chain_list* lofigchain,*newlofigchain=NULL; int buffer_is_better=0, change=1; /*flags*/ chain_list* pred; chain_list* temp; buffer=getCellbuffer(); /*no buffer in library*/ if (!buffer) return 0; if (!losig->NAMECHAIN) { fprintf(stderr,"insert_buffer: no name on signal\n"); autexit(1); } best_delay=critical_delay(lofig); init_capa=getcapacitance(losig->NAMECHAIN->DATA); /*add buffer to netlist*/ signame=getautoname(losig->NAMECHAIN->DATA); namechain=addchain(NULL,signame); losig_buf=addlosig(lofig,index,namechain,INTERNAL); putcapacitance(signame,0); putdelay(signame,0); model=getlofig(buffer->BEFIG->NAME,'A'); /*search vdd and vss*/ for (locon=lofig->LOCON; locon; locon=locon->NEXT) { if (isvdd(locon->NAME)) losig_vdd=locon->SIG; if (isvss(locon->NAME)) losig_vss=locon->SIG; } /*build list of signal*/ for (locon=model->LOCON;locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,model->NAME); autexit(1); } if (isvdd(locon->NAME)) losig_aux=losig_vdd; else if (isvss(locon->NAME)) losig_aux=losig_vss; else if (locon->DIRECTION==OUT) losig_aux=losig_buf; else if (locon->DIRECTION==IN) losig_aux=losig; else { fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME); autexit(1); } sigchain=addchain(sigchain,losig_aux); } sigchain=reverse(sigchain); loins_buf=addloins(lofig,signame,model,sigchain); freechain(sigchain); /*to check changes*/ init_delay=getdelay(losig->NAMECHAIN->DATA); init_capa=getcapacitance(losig->NAMECHAIN->DATA); loins_capacitance(loins_buf,1/*add capa*/); /*lofigchain*/ for (locon=loins_buf->LOCON;locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,loins_buf->INSNAME); autexit(1); } if (isvdd(locon->NAME)) losig_aux=losig_vdd; else if (isvss(locon->NAME)) losig_aux=losig_vss; else if (locon->DIRECTION==OUT) losig_aux=losig_buf; else if (locon->DIRECTION==IN) losig_aux=losig; else { fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME); autexit(1); } ptype=getptype(losig_aux->USER,LOFIGCHAIN); if (!ptype) losig_aux->USER=addptype(losig_aux->USER,LOFIGCHAIN,addchain(NULL,locon)); else ptype->DATA=addchain(ptype->DATA,locon); } /*move all instance after buffer*/ ptype=getptype(losig->USER,LOFIGCHAIN); buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); if (!ptype || !buffer_ptype) { fprintf(stderr,"insert_buffer: LOFIGCHAIN not found\n"); autexit(1); } for (lofigchain=((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/; lofigchain; lofigchain=lofigchain->NEXT) { locon=(locon_list*) lofigchain->DATA; if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n", locon->NAME); autexit(1); } /*do not move drivers and port of circuit*/ if (locon->TYPE==EXTERNAL || locon->DIRECTION!=IN) { newlofigchain=addchain(newlofigchain,locon); continue; } loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig_buf; buffer_ptype->DATA=addchain(buffer_ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); } /*put back drivers*/ freechain(((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/); ((chain_list*)ptype->DATA)->NEXT=newlofigchain; /*eval all changes*/ propagate_loins_delay(loins_buf); /*relaxation algorithm*/ while (change) { change=0; pred=NULL; buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); ptype=getptype(losig->USER,LOFIGCHAIN); if (!buffer_ptype || !buffer_ptype->DATA) { fprintf(stderr,"insert_buffer: LOFIGCHAIN is empty\n"); autexit(1); } /*put critical path before buffer*/ for (lofigchain=buffer_ptype->DATA; lofigchain->NEXT/*last is buffer output*/; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig; ptype->DATA=addchain(ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); /*put over*/ if (pred) pred->NEXT=lofigchain->NEXT; else buffer_ptype->DATA=lofigchain->NEXT; /*eval all changes*/ propagate_loins_delay(loins); propagate_loins_delay(loins_buf); delay=critical_delay(lofig); if (delay<best_delay) { /*finish change*/ best_delay=delay; change=1; /*flag of change*/ buffer_is_better=1; lofigchain->NEXT=NULL; freechain(lofigchain); break; } else { /*remove change*/ if (pred) pred->NEXT=lofigchain; else buffer_ptype->DATA=lofigchain; /*unchange capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*unchange netlist*/ locon->SIG=losig_buf; temp=ptype->DATA; ptype->DATA=temp->NEXT; temp->NEXT=NULL; freechain(temp); loins_capacitance(loins,1/*add capa*/); /*avoid change*/ propagate_loins_delay(loins_buf); propagate_loins_delay(loins); /*for next loop*/ pred=lofigchain; } } }/*end of while*/ if (buffer_is_better) { /*chose the best buffer*/ change_instance(loins_buf, losig_buf, lofig, optim_level); } else { /*if insert buffer is worst than before, remove it*/ /*remove all references of buffer in lofigchain*/ for (locon=loins_buf->LOCON; locon; locon=locon->NEXT) { losig_aux=locon->SIG; ptype=getptype(losig_aux->USER,LOFIGCHAIN); if (!ptype) break; pred=NULL; for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { if (lofigchain->DATA==locon) { if (pred) pred->NEXT=lofigchain->NEXT; else ptype->DATA=lofigchain->NEXT; lofigchain->NEXT=NULL; freechain(lofigchain); break; } pred=lofigchain; } } buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); ptype=getptype(losig->USER,LOFIGCHAIN); if (buffer_ptype) { for (lofigchain=buffer_ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig; ptype->DATA=addchain(ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); propagate_loins_delay(loins); } freechain(buffer_ptype->DATA); buffer_ptype->DATA=NULL; } loins_capacitance(loins_buf,0/*remove capa*/); dellosig(lofig,index); delloins(lofig,loins_buf->INSNAME); propagate_losig_delay(losig); /*verify no change on timing*/ delay=critical_delay(lofig); capa=getcapacitance(losig->NAMECHAIN->DATA); //01/09/2004 xtof's modification: rounding problem if ((int)(capa + 0.5)!=(int)(init_capa + 0.5) || (int)(delay + 0.5)!=(int)(best_delay + 0.5) || (int)(init_delay + 0.5)!=(int)(getdelay(losig->NAMECHAIN->DATA) + 0.5)) { fprintf(stderr, "insert_buffer: compute error %e!=%e fF %f!=%f ps %f!=%f ps\n", capa,init_capa,delay,best_delay, init_delay, getdelay(losig->NAMECHAIN->DATA)); autexit(1); } } return buffer_is_better; }