Annotation of 41BSD/4.0.upgrade/sys/dev/dsort.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.