Annotation of coherent/g/usr/lib/misc/virtual.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Virtual memory system for Coherent.
        !             3:  */
        !             4: #include "local_misc.h"
        !             5: #include <sys/stat.h>
        !             6: 
        !             7: #define FILES 20
        !             8: #define VBLKB 9                /* bytes in virtual block as a power of 2 */
        !             9: #define VBLK (1 << VBLKB) /* bytes in a virtual block */
        !            10: 
        !            11: struct mapper {
        !            12:        unsigned dirty:1;
        !            13:        unsigned what_in:15;
        !            14: };
        !            15: static unsigned long limit[20];
        !            16: static unsigned long initp;
        !            17: static unsigned topf;
        !            18: static struct mapper *map;
        !            19: static char *data;
        !            20: static unsigned blocks;
        !            21: static int tmp, ramsw;
        !            22: static struct stat st;
        !            23: 
        !            24: /*
        !            25:  * init virtual system.
        !            26:  * Called with work file name, may be /dev/ram1, and the
        !            27:  * approximate amount of storage to be used for buffers.
        !            28:  * The more you give it the better it works.
        !            29:  */
        !            30: void
        !            31: vinit(fname, ram)
        !            32: char *fname;   /* file name of virtual device e.g. /dev/rram1 */
        !            33: unsigned ram;  /* amount of storage to devote to ram */
        !            34: {
        !            35:        if (!(blocks = ram / (VBLK + sizeof(*map))))
        !            36:                fatal("Virtual; workspace too small");
        !            37:        data = alloc(blocks << VBLKB);
        !            38:        map  = (struct mapper *)alloc(blocks * sizeof(*map));
        !            39:        ramsw = topf = initp = 0;       /* make code reusable */
        !            40:        
        !            41:        if ((0 == stat(fname, &st)) && (S_IFCHR == (st.st_mode & S_IFCHR))) {
        !            42:                switch (is_fs(fname)) {
        !            43:                case -1:
        !            44:                        fatal("Virtual; cannot seek %s", fname);
        !            45:                case 1:
        !            46:                        fatal("Virtual; %s has a file system", fname);
        !            47:                case 0:
        !            48:                        if (!strcmp(fname, "/dev/ram1"))
        !            49:                                ramsw = 1;
        !            50:                        if (-1 == (tmp = open(fname, 2)))
        !            51:                                fatal("Virtual; cannot open(%s, 2)", fname);
        !            52:                }
        !            53:                return;
        !            54:        }
        !            55: 
        !            56:        if (-1 == (tmp = creat(fname, 0600)))
        !            57:                fatal("Virtual; cannot creat(%s, 0600)", fname);
        !            58:        close(tmp);
        !            59:        if (-1 == (tmp = open(fname, 2)))
        !            60:                fatal("Virtual; cannot open(%s, 2)", fname);
        !            61:        unlink(fname);
        !            62:        fstat(tmp, &st);
        !            63: }
        !            64: 
        !            65: /*
        !            66:  * Close down virtual system and free it's space
        !            67:  */
        !            68: void
        !            69: vshutDown()
        !            70: {
        !            71:        close(tmp);
        !            72:        if (ramsw)
        !            73:                close(open("/dev/ram1close", 0));
        !            74:        free(map);
        !            75:        free(data);
        !            76: }
        !            77: 
        !            78: /*
        !            79:  * Set up a virtual file. Say you want to emulate having a
        !            80:  * 100000 byte array and a 50000 byte array with virtual.
        !            81:  * vid1 = vopen(100000L); vid2 = vopen(50000L);
        !            82:  */
        !            83: unsigned
        !            84: vopen(vamt)
        !            85: unsigned long vamt;
        !            86: {
        !            87:        if (topf == FILES)
        !            88:                fatal("Too many vopen calls");
        !            89:        vamt = limit[topf + 1] = limit[topf] + vamt;
        !            90:        topf++;
        !            91:        vamt >>= VBLKB;
        !            92:        vamt /= blocks;         /* must fit in 15 bits */
        !            93:        if (vamt > 0x7fff)
        !            94:                fatal("Virtual; too much virtual space for buffers");
        !            95: 
        !            96:        if (st.st_mode & S_IFCHR) {     /* character special file */
        !            97:                char work[VBLK];
        !            98: 
        !            99:                memset(work, 0, VBLK);
        !           100:                for (; initp < limit[topf]; initp += VBLK)
        !           101:                        if (VBLK != write(tmp, work, VBLK))
        !           102:                                fatal("Virtual; error writing to tmp file");
        !           103:        }
        !           104:        return (topf - 1);
        !           105: }
        !           106: 
        !           107: /*
        !           108:  * Find a character on the virtual system
        !           109:  * mark the blocks dirty bit if Find is to write.
        !           110:  * Given the example in the vopen() comment. If you want to
        !           111:  * find the 1000 th byte in vid1 
        !           112:  * c = vfind(vid1, 1000L, 0);
        !           113:  * To change the 2000 th byte in vid2
        !           114:  * *(vfind(vid2, 2000L, 1)) = d;
        !           115:  */
        !           116: char *
        !           117: vfind(vid, disp, dirty)
        !           118: unsigned vid;          /* virtual file no */
        !           119: unsigned long disp;    /* where */
        !           120: int dirty;             /* 1 if character gotten to write */
        !           121: {
        !           122:        unsigned  which, what_in, byte_no;
        !           123:        unsigned long diskad;
        !           124:        char *where;
        !           125: 
        !           126:        if (vid >= topf)
        !           127:                fatal("Virtual; invalid vfile");
        !           128:        if ((disp += limit[vid]) >= limit[vid + 1])
        !           129:                fatal("Virtual; request out of limits");
        !           130:                
        !           131:        byte_no = disp & (VBLK - 1);
        !           132:        disp >>= VBLKB;
        !           133:        which = disp % blocks;
        !           134:        what_in = disp / blocks;
        !           135:        where = data + (which << VBLKB);
        !           136: 
        !           137:        if ((diskad = map[which].what_in) != what_in)   {
        !           138:                if (map[which].dirty) {
        !           139:                        diskad *= blocks;
        !           140:                        diskad += which;
        !           141:                        diskad <<= VBLKB;
        !           142:                        if (-1 == lseek(tmp, diskad, 0))
        !           143:                                fatal("Virtual; error in seek");
        !           144:                        if (VBLK != write(tmp, where, VBLK))
        !           145:                                fatal("Virtual; error in write");
        !           146:                }
        !           147:                map[which].dirty = 0;   /* clean */
        !           148:                map[which].what_in = diskad = what_in;
        !           149:                diskad *= blocks;
        !           150:                diskad += which;
        !           151:                diskad <<= VBLKB;
        !           152:                if (-1 == lseek(tmp, diskad, 0))
        !           153:                        fatal("Virtual; error in seek");
        !           154:                if (VBLK != read(tmp, where, VBLK))
        !           155:                        if (st.st_mode & S_IFCHR) /* char special device */
        !           156:                                fatal("Virtual; error in read");
        !           157:                        else
        !           158:                                memset(where, 0, VBLK);
        !           159:        }
        !           160:        map[which].dirty |= dirty; /* maybe dirty */
        !           161:        return (where + byte_no);
        !           162: }
        !           163: 
        !           164: #ifdef TEST
        !           165: static int vid[FILES];
        !           166: static long lim[FILES];
        !           167: static char buf[80];
        !           168: 
        !           169: main()
        !           170: {
        !           171:        char c, d;
        !           172:        int i, f;
        !           173:        long atol();
        !           174:        long l, t, tests;
        !           175: 
        !           176:        vinit("/dev/ram1", atoi(ask(buf, "How much ram to reserve")));
        !           177:        f = atol(ask(buf, "How many virtual files?"));
        !           178:        for (i = 0; i < f; i++)
        !           179:           vid[i] = vopen(lim[i] = atol(ask(buf, "How big is file %d", i)));
        !           180:        tests = atol(ask(buf, "How many tests?"));
        !           181:        srandl(100L, 100L);
        !           182:        for (t = 0; t < tests; t++) {   /* set random locs */
        !           183:                i = randl() % f; /* pick virtual file */
        !           184:                l = randl() % lim[i]; /* pick location */
        !           185:                c = i ^ l;
        !           186:                *(vfind(vid[i], l, 1)) = c;
        !           187:        }
        !           188:        srandl(100L, 100L);
        !           189:        for (t = 0; t < tests; t++) {   /* test same random locs */
        !           190:                i = randl() % f; /* pick virtual file */
        !           191:                l = randl() % lim[i]; /* pick location */
        !           192:                c = i ^ l;
        !           193:                if ((d = *(vfind(vid[i], l, 0))) != c)
        !           194:                        fatal("Expected %c got %c", c, d);
        !           195:        }
        !           196:        vshutDown();
        !           197: }
        !           198: #endif

unix.superglobalmegacorp.com

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