Annotation of coherent/g/usr/lib/misc/virtual.c, revision 1.1.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.