|
|
1.1 ! root 1: /* dsort.c 4.3 81/03/08 */ ! 2: ! 3: /* ! 4: * Seek sort for disks. We depend on the driver ! 5: * which calls us using b_resid as the current cylinder number. ! 6: * ! 7: * The argument dp structure holds a b_actf activity chain pointer ! 8: * on which we keep two queues, sorted in ascending cylinder order. ! 9: * The first queue holds those requests which are positioned after ! 10: * the current cylinder (in the first request); the second holds ! 11: * requests which came in after their cylinder number was passed. ! 12: * Thus we implement a one way scan, retracting after reaching the ! 13: * end of the drive to the first request on the second queue, ! 14: * at which time it becomes the first queue. ! 15: * ! 16: * A one-way scan is natural because of the way UNIX read-ahead ! 17: * blocks are allocated. ! 18: */ ! 19: ! 20: #include "../h/param.h" ! 21: #include "../h/systm.h" ! 22: #include "../h/buf.h" ! 23: ! 24: #define b_cylin b_resid ! 25: ! 26: disksort(dp, bp) ! 27: register struct buf *dp, *bp; ! 28: { ! 29: register struct buf *ap; ! 30: ! 31: /* ! 32: * If nothing on the activity queue, then ! 33: * we become the only thing. ! 34: */ ! 35: ap = dp->b_actf; ! 36: if(ap == NULL) { ! 37: dp->b_actf = bp; ! 38: dp->b_actl = bp; ! 39: bp->av_forw = NULL; ! 40: return; ! 41: } ! 42: /* ! 43: * If we lie after the first (currently active) ! 44: * request, then we must locate the second request list ! 45: * and add ourselves to it. ! 46: */ ! 47: if (bp->b_cylin < ap->b_cylin) { ! 48: while (ap->av_forw) { ! 49: /* ! 50: * Check for an ``inversion'' in the ! 51: * normally ascending cylinder numbers, ! 52: * indicating the start of the second request list. ! 53: */ ! 54: if (ap->av_forw->b_cylin < ap->b_cylin) { ! 55: /* ! 56: * Search the second request list ! 57: * for the first request at a larger ! 58: * cylinder number. We go before that; ! 59: * if there is no such request, we go at end. ! 60: */ ! 61: do { ! 62: if (bp->b_cylin < ap->av_forw->b_cylin) ! 63: goto insert; ! 64: ap = ap->av_forw; ! 65: } while (ap->av_forw); ! 66: goto insert; /* after last */ ! 67: } ! 68: ap = ap->av_forw; ! 69: } ! 70: /* ! 71: * No inversions... we will go after the last, and ! 72: * be the first request in the second request list. ! 73: */ ! 74: goto insert; ! 75: } ! 76: /* ! 77: * Request is at/after the current request... ! 78: * sort in the first request list. ! 79: */ ! 80: while (ap->av_forw) { ! 81: /* ! 82: * We want to go after the current request ! 83: * if there is an inversion after it (i.e. it is ! 84: * the end of the first request list), or if ! 85: * the next request is a larger cylinder than our request. ! 86: */ ! 87: if (ap->av_forw->b_cylin < ap->b_cylin || ! 88: bp->b_cylin < ap->av_forw->b_cylin) ! 89: goto insert; ! 90: ap = ap->av_forw; ! 91: } ! 92: /* ! 93: * Neither a second list nor a larger ! 94: * request... we go at the end of the first list, ! 95: * which is the same as the end of the whole schebang. ! 96: */ ! 97: insert: ! 98: bp->av_forw = ap->av_forw; ! 99: ap->av_forw = bp; ! 100: if (ap == dp->b_actl) ! 101: dp->b_actl = bp; ! 102: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.