struct sptf_queue { TAILQ_HEAD(sptfq, buf) queue; daddr_t lastpos; int t_lastpos; }; #define sptf_init(q) do { \ TAILQ_INIT(&(q)->queue); \ (q)->lastpos = 0; \ (q)->t_lastpos = 0; \ } while(0) #define sptf_enqueue(q,bp) TAILQ_INSERT_TAIL(&(q)->queue, (bp), b_act) #define sptf_dequeue(q,bp) do { \ TAILQ_REMOVE(&(q)->queue, (bp), b_act); \ (q)->lastpos = (bp)->b_pblkno; \ } while(0) #define sptf_iodone(q,bp) do { \ (q)->lastpos = (bp)->b_pblkno; \ (q)->t_lastpos = NOW; \ } while(0) #define sptf_dist(q,bp) (postime((bp)->b_pblkno - (q)->lastpos)) struct buf *sptf_select(struct sptf_queue *q) { struct buf *bp, *bq = 0; int t0 = INT_MAX, t; quad_t now __attribute__ ((unused)) = ll_microtime(); asptf_switch = 1; TAILQ_FOREACH(bp, &q->queue, b_act) { #ifdef ASPTF_BOUND if (now - bp->b_t_enqueue > ASPTF_BOUND * 1000LL) return bp; #endif t = sptf_dist(q,bp); if (!bq || t < t0) t0 = t, bq = bp; } asptf_switch = 0; return bq; } #define sptf_foreach(q,bp) TAILQ_FOREACH(bp, &(q)->queue, b_act)