Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ef8bcc6 in mainline


Ignore:
Timestamp:
2009-06-15T21:46:21Z (13 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master
Children:
953769f
Parents:
c07af37
Message:

Stdio stream buffering (only for writing a.t.m.) Issue: Do we need two moving delimiters (head, tail) to recover from error or is one moving data delimiter enough, like in the current implementation? (Where the buffer must be drained as a whole, cannot do it part at a time.

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    rc07af37 ref8bcc6  
    148148        char line[INPUT_MAX];
    149149
     150        fflush(stdout);
    150151        console_set_style(fphone(stdout), STYLE_EMPHASIS);
    151152        printf("%s", usr->prompt);
     153        fflush(stdout);
    152154        console_set_style(fphone(stdout), STYLE_NORMAL);
    153155
  • uspace/app/tester/console/console1.c

    rc07af37 ref8bcc6  
    5252
    5353        printf("Style test: ");
     54        fflush(stdout);
    5455        console_set_style(fphone(stdout), STYLE_NORMAL);
    5556        printf("normal ");
     57        fflush(stdout);
    5658        console_set_style(fphone(stdout), STYLE_EMPHASIS);
    5759        printf("emphasized");
     60        fflush(stdout);
    5861        console_set_style(fphone(stdout), STYLE_NORMAL);
    5962        printf(".\n");
     
    6265        for (j = 0; j < 2; j++) {
    6366                for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
     67                        fflush(stdout);
    6468                        console_set_color(fphone(stdout), i, COLOR_WHITE,
    6569                            j ? CATTR_BRIGHT : 0);
    6670                        printf(" %s ", color_name[i]);
    6771                }
     72                fflush(stdout);
    6873                console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    6974                putchar('\n');
     
    7378        for (j = 0; j < 2; j++) {
    7479                for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
     80                        fflush(stdout);
    7581                        console_set_color(fphone(stdout), COLOR_WHITE, i,
    7682                            j ? CATTR_BRIGHT : 0);
    7783                        printf(" %s ", color_name[i]);
    7884                }
     85                fflush(stdout);
    7986                console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    8087                putchar('\n');
     
    8491
    8592        for (i = 0; i < 255; i += 16) {
     93                fflush(stdout);
    8694                console_set_rgb_color(fphone(stdout), 0xffffff, i << 16);
    8795                putchar('X');
    8896        }
     97        fflush(stdout);
    8998        console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    9099        putchar('\n');
    91100
    92101        for (i = 0; i < 255; i += 16) {
     102                fflush(stdout);
    93103                console_set_rgb_color(fphone(stdout), 0xffffff, i << 8);
    94104                putchar('X');
    95105        }
     106        fflush(stdout);
    96107        console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    97108        putchar('\n');
    98109
    99110        for (i = 0; i < 255; i += 16) {
     111                fflush(stdout);
    100112                console_set_rgb_color(fphone(stdout), 0xffffff, i);
    101113                putchar('X');
    102114        }
     115        fflush(stdout);
    103116        console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    104117        putchar('\n');
  • uspace/app/tetris/screen.c

    rc07af37 ref8bcc6  
    7878static void start_standout(uint32_t color)
    7979{
     80        fflush(stdout);
    8081        console_set_rgb_color(fphone(stdout), 0xf0f0f0, color);
    8182}
     
    8384static void resume_normal(void)
    8485{
     86        fflush(stdout);
    8587        console_set_rgb_color(fphone(stdout), 0, 0xf0f0f0);
    8688}
     
    115117void moveto(int r, int c)
    116118{
     119        fflush(stdout);
    117120        console_goto(fphone(stdout), c, r);
    118121}
  • uspace/lib/libc/generic/io/io.c

    rc07af37 ref8bcc6  
    3636#include <unistd.h>
    3737#include <fcntl.h>
     38#include <assert.h>
    3839#include <string.h>
    3940#include <errno.h>
     
    4546#include <adt/list.h>
    4647
     48static void _fflushbuf(FILE *stream);
     49
    4750static FILE stdin_null = {
    4851        .fd = -1,
     
    5053        .eof = true,
    5154        .klog = false,
    52         .phone = -1
     55        .phone = -1,
     56        .btype = _IONBF,
     57        .buf = NULL,
     58        .buf_size = 0,
     59        .buf_head = NULL
    5360};
    5461
     
    5865        .eof = false,
    5966        .klog = true,
    60         .phone = -1
     67        .phone = -1,
     68        .btype = _IOLBF,
     69        .buf = NULL,
     70        .buf_size = BUFSIZ,
     71        .buf_head = NULL
    6172};
    6273
     
    6677        .eof = false,
    6778        .klog = true,
    68         .phone = -1
     79        .phone = -1,
     80        .btype = _IONBF,
     81        .buf = NULL,
     82        .buf_size = 0,
     83        .buf_head = NULL
    6984};
    7085
     
    157172}
    158173
     174/** Set stream buffer. */
     175void setvbuf(FILE *stream, void *buf, int mode, size_t size)
     176{
     177        stream->btype = mode;
     178        stream->buf = buf;
     179        stream->buf_size = size;
     180        stream->buf_head = stream->buf;
     181}
     182
     183/** Allocate stream buffer. */
     184static int _fallocbuf(FILE *stream)
     185{
     186        assert(stream->buf == NULL);
     187
     188        stream->buf = malloc(stream->buf_size);
     189        if (stream->buf == NULL) {
     190                errno = ENOMEM;
     191                return -1;
     192        }
     193
     194        stream->buf_head = stream->buf;
     195        return 0;
     196}
     197
    159198/** Open a stream.
    160199 *
     
    187226        stream->klog = false;
    188227        stream->phone = -1;
     228
     229        /* FIXME: Should select buffering type based on what was opened. */
     230        setvbuf(stream, NULL, _IOFBF, BUFSIZ);
    189231       
    190232        list_append(&stream->link, &files);
     
    207249        stream->klog = false;
    208250        stream->phone = -1;
     251
     252        /* FIXME: Should select buffering type based on what was opened. */
     253        setvbuf(stream, NULL, _IOLBF, BUFSIZ);
    209254       
    210255        list_append(&stream->link, &files);
     
    237282        stream->klog = false;
    238283        stream->phone = -1;
     284
     285        /* FIXME: Should select buffering type based on what was opened. */
     286        setvbuf(stream, NULL, _IOLBF, BUFSIZ);
    239287       
    240288        list_append(&stream->link, &files);
     
    284332        size_t left = size * nmemb;
    285333        size_t done = 0;
    286        
     334
     335        /* Make sure no data is pending write. */
     336        _fflushbuf(stream);
     337
    287338        while ((left > 0) && (!stream->error) && (!stream->eof)) {
    288339                ssize_t rd = read(stream->fd, buf + done, left);
     
    301352}
    302353
    303 /** Write to a stream.
    304  *
    305  * @param buf    Source buffer.
    306  * @param size   Size of each record.
    307  * @param nmemb  Number of records to write.
    308  * @param stream Pointer to the stream.
    309  *
    310  */
    311 size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
     354static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
    312355{
    313356        size_t left = size * nmemb;
     
    333376}
    334377
     378/** Drain stream buffer, do not sync stream. */
     379static void _fflushbuf(FILE *stream)
     380{
     381        size_t bytes_used;
     382
     383        if (!stream->buf || stream->btype == _IONBF || stream->error)
     384                return;
     385
     386        bytes_used = stream->buf_head - stream->buf;
     387        if (bytes_used == 0)
     388                return;
     389
     390        (void) _fwrite(stream->buf, 1, bytes_used, stream);
     391        stream->buf_head = stream->buf;
     392}
     393
     394/** Write to a stream.
     395 *
     396 * @param buf    Source buffer.
     397 * @param size   Size of each record.
     398 * @param nmemb  Number of records to write.
     399 * @param stream Pointer to the stream.
     400 *
     401 */
     402size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
     403{
     404        uint8_t *data;
     405        size_t bytes_left;
     406        size_t now;
     407        size_t buf_free;
     408        size_t total_written;
     409        size_t i;
     410        uint8_t b;
     411        bool need_flush;
     412
     413        /* If not buffered stream, write out directly. */
     414        if (stream->btype == _IONBF)
     415                return _fwrite(buf, size, nmemb, stream);
     416
     417        /* Perform lazy allocation of stream buffer. */
     418        if (stream->buf == NULL) {
     419                if (_fallocbuf(stream) != 0)
     420                        return 0; /* Errno set by _fallocbuf(). */
     421        }
     422
     423        data = (uint8_t *) buf;
     424        bytes_left = size * nmemb;
     425        total_written = 0;
     426        need_flush = false;
     427
     428        while (!stream->error && bytes_left > 0) {
     429
     430                buf_free = stream->buf_size - (stream->buf_head - stream->buf);
     431                if (bytes_left > buf_free)
     432                        now = buf_free;
     433                else
     434                        now = bytes_left;
     435
     436                for (i = 0; i < now; i++) {
     437                        b = data[i];
     438                        stream->buf_head[i] = b;
     439
     440                        if (b == '\n' && stream->btype == _IOLBF)
     441                                need_flush = true;
     442                }
     443
     444                buf += now;
     445                stream->buf_head += now;
     446                buf_free -= now;
     447                bytes_left -= now;
     448                total_written += now;
     449
     450                if (buf_free == 0) {
     451                        /* Only need to drain buffer. */
     452                        _fflushbuf(stream);
     453                        need_flush = false;
     454                }
     455        }
     456
     457        if (need_flush)
     458                fflush(stream);
     459
     460        return (total_written / size);
     461}
     462
    335463int fputc(wchar_t c, FILE *stream)
    336464{
     
    406534int fflush(FILE *stream)
    407535{
     536        _fflushbuf(stream);
     537
    408538        if (stream->klog) {
    409539                klog_update();
  • uspace/lib/libc/include/stdio.h

    rc07af37 ref8bcc6  
    4242#define EOF  (-1)
    4343
     44/** Default size for stream I/O buffers */
     45#define BUFSIZ 4096
     46
    4447#define DEBUG(fmt, ...) \
    4548{ \
     
    5558        #define SEEK_END  2
    5659#endif
     60
     61enum _buffer_type {
     62        /** No buffering */
     63        _IONBF,
     64        /** Line buffering */
     65        _IOLBF,
     66        /** Full buffering */
     67        _IOFBF
     68};
    5769
    5870typedef struct {
     
    7486        /** Phone to the file provider */
    7587        int phone;
     88
     89        /** Buffering type */
     90        enum _buffer_type btype;
     91        /** Buffer */
     92        uint8_t *buf;
     93        /** Buffer size */
     94        size_t buf_size;
     95        /** Buffer I/O pointer */
     96        uint8_t *buf_head;
    7697} FILE;
    7798
     
    122143extern void clearerr(FILE *);
    123144
     145extern void setvbuf(FILE *, void *, int, size_t);
     146
    124147/* Misc file functions */
    125148extern int rename(const char *, const char *);
Note: See TracChangeset for help on using the changeset viewer.