void paranoia_resetcache(cdrom_paranoia *p){ c_block *c=c_first(p); v_fragment *v; while(c){ free_c_block(c); c=c_first(p); } v=v_first(p); while(v){ free_v_fragment(v); v=v_first(p); } }
//SUMMARY // Return the first request in the cache after removing it from the cache, or NULL if the cache is empty struct cache_entry* c_shift() { fprintf(stderr, "c_shift: Called\n"); struct cache_entry* first = c_first(); if (first != NULL) c_remove(first); return first; }
void i_paranoia_trim(cdrom_paranoia_t *p, long int beginword, long int endword) { root_block *root=&(p->root); if(root->vector!=NULL){ long target=beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS; long rbegin=cb(root->vector); long rend=ce(root->vector); if(rbegin>beginword) goto rootfree; if(rbegin+MAX_SECTOR_OVERLAP*CD_FRAMEWORDS<beginword){ if(target+MIN_WORDS_OVERLAP>rend) goto rootfree; { long int offset=target-rbegin; c_removef(root->vector,offset); } } { c_block_t *c=c_first(p); while(c){ c_block_t *next=c_next(c); if(ce(c)<beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS) free_c_block(c); c=next; } } } return; rootfree: i_cblock_destructor(root->vector); root->vector=NULL; root->returnedlimit=-1; root->lastsector=0; }
void offset_adjust_settings(cdrom_paranoia *p, void(*callback)(long,int)){ if(p->stage2.offpoints>=10){ /* drift: look at the average offset value. If it's over one sector, frob it. We just want a little hysteresis [sp?]*/ long av=(p->stage2.offpoints?p->stage2.offaccum/p->stage2.offpoints:0); if(abs(av)>p->dynoverlap/4){ av=(av/MIN_SECTOR_EPSILON)*MIN_SECTOR_EPSILON; if(callback)(*callback)(ce(p->root.vector),PARANOIA_CB_DRIFT); p->dyndrift+=av; /* Adjust all the values in the cache otherwise we get a (potentially unstable) feedback loop */ { c_block *c=c_first(p); v_fragment *v=v_first(p); while(v && v->one){ /* safeguard beginning bounds case with a hammer */ if(fb(v)<av || cb(v->one)<av){ v->one=NULL; }else{ fb(v)-=av; } v=v_next(v); } while(c){ long adj=min(av,cb(c)); c_set(c,cb(c)-adj); c=c_next(c); } } p->stage2.offaccum=0; p->stage2.offmin=0; p->stage2.offmax=0; p->stage2.offpoints=0; p->stage2.newpoints=0; p->stage2.offdiff=0; } } if(p->stage1.offpoints>=10){ /* dynoverlap: we arbitrarily set it to 4x the running difference value, unless min/max are more */ p->dynoverlap=(p->stage1.offpoints?p->stage1.offdiff/ p->stage1.offpoints*3:CD_FRAMEWORDS); if(p->dynoverlap<-p->stage1.offmin*1.5) p->dynoverlap= - (long)( (double)p->stage1.offmin * 1.5 ); if(p->dynoverlap<p->stage1.offmax*1.5) p->dynoverlap = (long)( (double)p->stage1.offmax * 1.5 ); if(p->dynoverlap<MIN_SECTOR_EPSILON)p->dynoverlap=MIN_SECTOR_EPSILON; if(p->dynoverlap>MAX_SECTOR_OVERLAP*CD_FRAMEWORDS) p->dynoverlap=MAX_SECTOR_OVERLAP*CD_FRAMEWORDS; if(callback)(*callback)(p->dynoverlap,PARANOIA_CB_OVERLAP); if(p->stage1.offpoints>600){ /* bit of a bug; this routine is called too often due to the overlap mesh alg we use in stage 1 */ p->stage1.offpoints = (long)( (double)p->stage1.offpoints / 1.2 ); p->stage1.offaccum = (long)( (double)p->stage1.offaccum / 1.2); p->stage1.offdiff = (long)( (double) p->stage1.offdiff / 1.2 ); } p->stage1.offmin=0; p->stage1.offmax=0; p->stage1.newpoints=0; } }