Assignment 5, due Feb. 20

Part of the homework for 22C:112, Spring 2009
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

  1. Background: The Unix read(d,b,c) routine reads from device d into buffer b reading no more than c characters, and returning the count of characters actually read. For interactive devices, it returns if c characters are read, or if the user types a newline character, whichever happens first.

    The C standard library routine fgetc(f) returns one character read from file f. The variable f points to an open file object, where open file objects contain a device descriptor (used to specify a device when calling read(), a buffer, and a buffer pointer. The size of the buffer (call it BUFSIZE is bigger than one because calls to read() are relatively slow due to the overhead of system calls and due to the overhead of working down through the hierarchy of the file system and device interfaces.

    a) Assume you are inside the operating system and have concluded that the user's call to read() involved a character sequential device such as an asynchronous communications line. Propose code for read() in this context, in terms of a low-level operating system internal routine called get(d), where d is some internal device descriptor (an object handle on an operating system device that has already been determined to be character sequential). (0.5 points)

    int char_seq_read( d, buf, len ) {
            int i = 0;
            while (i < len) {
                    char ch;
                    ch = get(d);
                    /* optional */ if (ch == BACKSPACE) i--;
                    buf[i] = ch;
                    i ++;
                    /* optional */ if (ch == NEWLINE) break;
            }
            return i;
    }
    

    b) Suggest code for fgetc(). (0.5 points)

    char fgetc( FILE *f ) {
            if (f->pos >= f->lim) {
                    int i = read (f->fd, f->buf, f->bufsize);
                    f->pos = f->buf;
                    f->lim = f->buf + i;
            }
            return *f->pos++;
    }
    

  2. Background: Consider the problem of writing a serial I/O driver. Under Unix, the keyboard devices are documented in man 4 tty and man 4 ttyS, and the calls used to control the operating mode of the keyboard device are given in man termios. These calls allow you to control everything from echo mode to baud rate as one flat service. Flat, as in, there is no hierarchy here, either implementation hierarchy or behavioral hierarchy.

    If compatibility with Unix were not an issue, it would make sense to introduce an implementation hierarchy, with a low level serial port device interface that knows nothing about the data in the input or output streams and a suite of higher level device interfaces, each implemented entirely in terms of the lower level, that understands keyboards, the structure text, and various other communications protocols that can be embedded in a serial byte stream.

    a) Go through the things that the termios interfaces allow you to set and identify those that relate to the high level category described above. (0.5 points)

    This list captures the gist of a decent answer, but it may have missed a few: IGNCR ICRNL IUCLC IXON IXANY IXOFF IMAXBEL OLCUC ONLCR OCRNL ONOCR ONLRET NLDLY CRDLY TABDLY BSDLY VTDLY FFDLY ISIG ICANON XCASE EXHO EXHOE EXHOK ECHONL ECHOCTL ECHOPRT ECHOKE DEFECHO VINTR VQUIT VERASE VKILL VEOF VMIN VEOL VTIME VEOL2 VSWTCH VSTART VSTOP VSUSP VDSUSP VLNEXT VWERASE VREPRINT VDISCARD VSTATUS TCOOFF TCOON TCIOFF TCION

    b) In an ideal object-oriented implementation of the operating-system device interface, the idea of implementing one device class in terms of another is straightforward. Can you propose a way to attach high level devices to low-level devices in a Unix-like system interface? (0.5 points)

    Unix does not provide an easy way to do this.

  3. Background: Within an interrupt handler, it is essential to disable at least some interrupts until the handler has completed some minimal computation.

    a) At the bare minimum, what interrupt must be disabled by each interrupt handler? (0.5 points)

    The interrupt request from that handler's device. If it were not disabled, the entry to the handler would be followed, immediately, with another interrupt, leading to an infinite interrupt loop.

    b) At what point, at the earliest, is it possible to safely enable the interrupt identified in part a? (0.5 points)

    As soon as the global interrupt enable bit is on, or alternatively, as soon as the ready bit for the device has been reset.