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

Changeset 566f4cfb in mainline


Ignore:
Timestamp:
2009-04-24T08:01:05Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
402de0c
Parents:
ab1861a
Message:

use buffering for klog output (this can be used to avoid the ugly usleeps while starting tasks)
unify and cleanup console.c and related files

Files:
11 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/main/kinit.c

    rab1861a r566f4cfb  
    219219       
    220220        /*
    221          * Run user tasks with small delays
    222          * to avoid intermixed klog output.
    223          *
    224          * TODO: This certainly does not guarantee
    225          *       anything, it just works in most of the
    226          *       cases. Some better way how to achieve
    227          *       nice klog output should be found.
     221         * Run user tasks.
    228222         */
    229223        for (i = 0; i < init.cnt; i++) {
    230                 if (programs[i].task != NULL) {
     224                if (programs[i].task != NULL)
    231225                        program_ready(&programs[i]);
    232                         thread_usleep(10000);
    233                 }
    234226        }
    235227       
  • uspace/app/init/init.c

    rab1861a r566f4cfb  
    8989        argv[1] = NULL;
    9090       
    91         if (task_spawn(fname, argv)) {
    92                 /* Add reasonable delay to avoid intermixed klog output. */
    93                 usleep(10000);
    94         } else {
     91        if (!task_spawn(fname, argv))
    9592                printf(NAME ": Error spawning %s\n", fname);
    96         }
    9793}
    9894
  • uspace/app/tetris/input.c

    rab1861a r566f4cfb  
    116116again:
    117117                if (!getchar_inprog) {
    118                         cons_phone = console_phone_get(true);
     118                        cons_phone = console_open(true);
    119119                        getchar_inprog = async_send_2(cons_phone,
    120120                            CONSOLE_GETKEY, 0, 0, &charcall);
  • uspace/lib/libc/generic/console.c

    rab1861a r566f4cfb  
    3333 */
    3434/** @file
    35  */
    36 
     35 */
     36
     37#include <libc.h>
    3738#include <async.h>
    3839#include <io/stream.h>
     
    4647
    4748/** Size of cbuffer. */
    48 #define CBUFFER_SIZE 256
     49#define CBUFFER_SIZE  256
    4950
    5051/** Buffer for writing characters to the console. */
     
    5758static char *cbp = cbuffer;
    5859
    59 static ssize_t cons_write(const char *buf, size_t nbyte);
    60 static void cons_putchar(wchar_t c);
    61 
    62 static void cbuffer_flush(void);
    63 static void cbuffer_drain(void);
    64 static inline void cbuffer_putc(int c);
    65 
    66 
    67 void console_open(bool blocking)
     60
     61/** Write one character to the console via IPC. */
     62static void cons_putchar(wchar_t c)
     63{
     64        console_wait();
     65        async_msg_1(console_phone, CONSOLE_PUTCHAR, c);
     66}
     67
     68/** Write characters to the console via IPC or to klog */
     69static ssize_t cons_write(const char *buf, size_t size)
     70{
     71        console_open(false);
     72       
     73        if (console_phone >= 0) {
     74                async_serialize_start();
     75               
     76                ipc_call_t answer;
     77                aid_t req = async_send_0(console_phone, CONSOLE_WRITE, &answer);
     78                ipcarg_t rc = ipc_data_write_start(console_phone, (void *) buf, size);
     79               
     80                if (rc != EOK) {
     81                        async_wait_for(req, NULL);
     82                        async_serialize_end();
     83                        return (ssize_t) rc;
     84                }
     85               
     86                async_wait_for(req, &rc);
     87                async_serialize_end();
     88               
     89                if (rc == EOK)
     90                        return (ssize_t) IPC_GET_ARG1(answer);
     91                else
     92                        return -1;
     93        } else
     94                return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
     95}
     96
     97/** Write all data from output buffer to the console. */
     98static void cbuffer_flush(void)
     99{
     100        size_t len = cbp - cbuffer;
     101       
     102        while (len > 0) {
     103                ssize_t rc = cons_write(cbuffer, cbp - cbuffer);
     104                if (rc < 0)
     105                        return;
     106               
     107                len -= rc;
     108        }
     109       
     110        cbp = cbuffer;
     111}
     112
     113/** Drop all data in console output buffer. */
     114static void cbuffer_drain(void)
     115{
     116        cbp = cbuffer;
     117}
     118
     119/** Write one character to the output buffer. */
     120static inline void cbuffer_putc(char c)
     121{
     122        if (cbp == cbuffer_end)
     123                cbuffer_flush();
     124       
     125        *cbp++ = c;
     126       
     127        if (c == '\n')
     128                cbuffer_flush();
     129}
     130
     131int console_open(bool blocking)
    68132{
    69133        if (console_phone < 0) {
    70134                int phone;
    71                 if (blocking) {
     135               
     136                if (blocking)
    72137                        phone = ipc_connect_me_to_blocking(PHONE_NS,
    73138                            SERVICE_CONSOLE, 0, 0);
    74                 } else {
    75                         phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0,
    76                             0);
    77                 }
     139                else
     140                        phone = ipc_connect_me_to(PHONE_NS,
     141                            SERVICE_CONSOLE, 0, 0);
     142               
    78143                if (phone >= 0)
    79144                        console_phone = phone;
    80145        }
     146       
     147        return console_phone;
    81148}
    82149
     
    84151{
    85152        if (console_phone >= 0) {
    86                 if (ipc_hangup(console_phone) == 0) {
     153                if (ipc_hangup(console_phone) == 0)
    87154                        console_phone = -1;
    88                 }
    89         }
    90 }
    91 
    92 int console_phone_get(bool blocking)
    93 {
    94         if (console_phone < 0)
    95                 console_open(blocking);
    96        
    97         return console_phone;
     155        }
    98156}
    99157
     
    106164void console_clear(void)
    107165{
    108         int cons_phone = console_phone_get(true);
    109 
     166        console_wait();
    110167        cbuffer_drain();
    111         async_msg_0(cons_phone, CONSOLE_CLEAR);
     168        async_msg_0(console_phone, CONSOLE_CLEAR);
     169}
     170
     171int console_get_size(int *rows, int *cols)
     172{
     173        console_wait();
     174       
     175        ipcarg_t r;
     176        ipcarg_t c;
     177        int rc = async_req_0_2(console_phone, CONSOLE_GETSIZE, &r, &c);
     178       
     179        *rows = (int) r;
     180        *cols = (int) c;
     181       
     182        return rc;
     183}
     184
     185void console_set_style(int style)
     186{
     187        console_wait();
     188        cbuffer_flush();
     189        async_msg_1(console_phone, CONSOLE_SET_STYLE, style);
     190}
     191
     192void console_set_color(int fg_color, int bg_color, int flags)
     193{
     194        console_wait();
     195        cbuffer_flush();
     196        async_msg_3(console_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
     197}
     198
     199void console_set_rgb_color(int fg_color, int bg_color)
     200{
     201        console_wait();
     202        cbuffer_flush();
     203        async_msg_2(console_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
     204}
     205
     206void console_cursor_visibility(int show)
     207{
     208        console_wait();
     209        cbuffer_flush();
     210        async_msg_1(console_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
     211}
     212
     213void console_kcon_enable(void)
     214{
     215        console_wait();
     216        cbuffer_flush();
     217        async_msg_0(console_phone, CONSOLE_KCON_ENABLE);
    112218}
    113219
    114220void console_goto(int row, int col)
    115221{
    116         int cons_phone = console_phone_get(true);
    117 
    118         cbuffer_flush();
    119         async_msg_2(cons_phone, CONSOLE_GOTO, row, col);
     222        console_wait();
     223        cbuffer_flush();
     224        async_msg_2(console_phone, CONSOLE_GOTO, row, col);
    120225}
    121226
    122227void console_putchar(wchar_t c)
    123228{
    124 //      cbuffer_putc(c);
     229        console_wait();
    125230        cbuffer_flush();
    126231        cons_putchar(c);
    127232}
    128233
    129 /** Write all data from output buffer to the console. */
    130 static void cbuffer_flush(void)
    131 {
    132         int rc;
    133         int len;
    134 
    135         len = cbp - cbuffer;
    136 
    137         while (len > 0) {
    138                 rc = cons_write(cbuffer, cbp - cbuffer);
    139                 if (rc < 0)
    140                         return;
    141 
    142                 len -= rc;
    143         }
    144 
    145         cbp = cbuffer;
    146 }
    147 
    148 /** Drop all data in console output buffer. */
    149 static void cbuffer_drain(void)
    150 {
    151         cbp = cbuffer;
    152 }
    153 
    154 /** Write one character to the output buffer. */
    155 static inline void cbuffer_putc(int c)
    156 {
    157         if (cbp == cbuffer_end)
    158                 cbuffer_flush();
    159 
    160         *cbp++ = c;
    161 
    162         if (c == '\n')
    163                 cbuffer_flush();
    164 }
    165 
    166 /** Write one character to the console via IPC. */
    167 static void cons_putchar(wchar_t c)
    168 {
    169         int cons_phone = console_phone_get(true);
    170         async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
    171 }
    172 
    173 /** Write characters to the console via IPC. */
    174 static ssize_t cons_write(const char *buf, size_t nbyte)
    175 {
    176         int cons_phone = console_phone_get(true);
    177         ipcarg_t rc;
    178         ipc_call_t answer;
    179         aid_t req;
    180 
    181         async_serialize_start();
    182        
    183         req = async_send_0(cons_phone, CONSOLE_WRITE, &answer);
    184         rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte);
    185 
    186         if (rc != EOK) {
    187                 async_wait_for(req, NULL);
    188                 async_serialize_end();
    189                 return (ssize_t) rc;
    190         }
    191 
    192         async_wait_for(req, &rc);
    193         async_serialize_end();
    194 
    195         if (rc == EOK)
    196                 return (ssize_t) IPC_GET_ARG1(answer);
    197         else
    198                 return -1;
    199 }
    200 
    201234/** Write characters to the console. */
    202 ssize_t console_write(const char *buf, size_t nbyte)
    203 {
    204         size_t left;
    205 
    206         left = nbyte;
    207 
     235ssize_t console_write(const char *buf, size_t size)
     236{
     237        size_t left = size;
     238       
    208239        while (left > 0) {
    209240                cbuffer_putc(*buf++);
    210                 --left;
    211         }
    212 
    213         return nbyte;
     241                left--;
     242        }
     243       
     244        return size;
    214245}
    215246
    216247/** Write a NULL-terminated string to the console. */
    217 void console_putstr(const char *s)
    218 {
    219         size_t len;
    220         ssize_t rc;
    221 
    222         len = str_size(s);
    223         while (len > 0) {
    224                 rc = console_write(s, len);
    225                 if (rc < 0)
    226                         return; /* Error */
    227                 s += rc;
    228                 len -= rc;
    229         }
    230 }
    231 
    232 /** Flush all output to the console. */
     248void console_putstr(const char *str)
     249{
     250        size_t left = str_size(str);
     251       
     252        while (left > 0) {
     253                ssize_t rc = console_write(str, left);
     254               
     255                if (rc < 0) {
     256                        /* Error */
     257                        return;
     258                }
     259               
     260                str += rc;
     261                left -= rc;
     262        }
     263}
     264
     265/** Flush all output to the console or klog. */
    233266void console_flush(void)
    234267{
    235         int cons_phone = console_phone_get(false);
    236 
    237         cbuffer_flush();
    238         async_msg_0(cons_phone, CONSOLE_FLUSH);
    239 }
    240 
    241 void console_flush_optional(void)
    242 {
     268        cbuffer_flush();
    243269        if (console_phone >= 0)
    244                 console_flush();
    245 }
    246 
    247 int console_get_size(int *rows, int *cols)
    248 {
    249         int cons_phone = console_phone_get(true);
    250         ipcarg_t r, c;
    251         int rc;
    252 
    253         rc = async_req_0_2(cons_phone, CONSOLE_GETSIZE, &r, &c);
    254 
    255         *rows = (int) r;
    256         *cols = (int) c;
    257 
    258         return rc;
    259 }
    260 
    261 void console_set_style(int style)
    262 {
    263         int cons_phone = console_phone_get(true);
    264 
    265         cbuffer_flush();
    266         async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
    267 }
    268 
    269 void console_set_color(int fg_color, int bg_color, int flags)
    270 {
    271         int cons_phone = console_phone_get(true);
    272 
    273         cbuffer_flush();
    274         async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
    275 }
    276 
    277 void console_set_rgb_color(int fg_color, int bg_color)
    278 {
    279         int cons_phone = console_phone_get(true);
    280 
    281         cbuffer_flush();
    282         async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
    283 }
    284 
    285 void console_cursor_visibility(int show)
    286 {
    287         int cons_phone = console_phone_get(true);
    288 
    289         cbuffer_flush();
    290         async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
    291 }
    292 
    293 void console_kcon_enable(void)
    294 {
    295         int cons_phone = console_phone_get(true);
    296 
    297         cbuffer_flush();
    298         async_msg_0(cons_phone, CONSOLE_KCON_ENABLE);
     270                async_msg_0(console_phone, CONSOLE_FLUSH);
    299271}
    300272
  • uspace/lib/libc/generic/io/io.c

    rab1861a r566f4cfb  
    3939#include <string.h>
    4040#include <errno.h>
     41#include <console.h>
    4142
    4243const static char nl = '\n';
     
    5051       
    5152        for (count = 0; str[count] != 0; count++);
    52         if (write_stdout((void *) str, count) == count) {
    53                 if (write_stdout(&nl, 1) == 1)
     53       
     54        if (console_write((void *) str, count) == count) {
     55                if (console_write(&nl, 1) == 1)
    5456                        return 0;
    5557        }
     
    6567int putnchars(const char *buf, size_t count)
    6668{
    67         if (write_stdout((void *) buf, count) == count)
     69        if (console_write((void *) buf, count) == count)
    6870                return 0;
    6971       
     
    8284
    8385        for (count = 0; str[count] != 0; count++);
    84         if (write_stdout((void *) str, count) == count)
     86        if (console_write((void *) str, count) == count)
    8587                return 0;
    8688       
     
    9799                return EOF;
    98100
    99         if (write_stdout((void *) buf, offs) == offs)
     101        if (console_write((void *) buf, offs) == offs)
    100102                return c;
    101103
     
    106108{
    107109        unsigned char c;
    108 
    109         flush_stdout();
     110       
     111        console_flush();
    110112        if (read_stdin((void *) &c, 1) == 1)
    111113                return c;
     
    116118int fflush(FILE *f)
    117119{
     120        /* Dummy implementation */
    118121        (void) f;
    119         return flush_stdout();
     122        console_flush();
     123        return 0;
    120124}
    121125
  • uspace/lib/libc/generic/io/stream.c

    rab1861a r566f4cfb  
    5050#include <sys/types.h>
    5151
    52 ssize_t write_stderr(const void *buf, size_t count)
    53 {
    54         return count;
    55 }
    56 
    5752ssize_t read_stdin(void *buf, size_t count)
    5853{
    59         int cons_phone = console_phone_get(false);
    60 
     54        int cons_phone = console_open(false);
     55       
    6156        if (cons_phone >= 0) {
    6257                kbd_event_t ev;
    6358                int rc;
    6459                size_t i = 0;
    65        
     60               
    6661                while (i < count) {
    6762                        do {
     
    6964                                if (rc < 0) return -1;
    7065                        } while (ev.c == 0 || ev.type == KE_RELEASE);
    71 
     66                       
    7267                        ((char *) buf)[i++] = ev.c;
    7368                }
    7469                return i;
    75         } else {
     70        } else
    7671                return -1;
    77         }
    78 }
    79 
    80 ssize_t write_stdout(const void *buf, size_t count)
    81 {
    82         int cons_phone = console_phone_get(false);
    83         int left, rc;
    84 
    85         if (cons_phone >= 0) {
    86                 int i;
    87 
    88                 left = count;
    89                 while (left > 0) {
    90                         rc = console_write(buf, left);
    91                         if (rc < 0)
    92                                 break;
    93                         buf += rc;
    94                         left -= rc;
    95                 }
    96 
    97                 return count;
    98         } else
    99                 return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count);
    100 }
    101 
    102 int flush_stdout(void)
    103 {
    104         console_flush();
    105         return 0;
    10672}
    10773
  • uspace/lib/libc/generic/io/vprintf.c

    rab1861a r566f4cfb  
    3939#include <futex.h>
    4040#include <async.h>
     41#include <console.h>
    4142
    4243static atomic_t printf_futex = FUTEX_INITIALIZER;
     
    5152                prev = offset;
    5253                str_decode(str, &offset, size);
    53                 write_stdout(str + prev, offset - prev);
     54                console_write(str + prev, offset - prev);
    5455                chars++;
    5556        }
     
    6869                boff = 0;
    6970                chr_encode(str[chars], buf, &boff, 4);
    70                 write_stdout(buf, boff);
     71                console_write(buf, boff);
    7172                chars++;
    7273                offset += sizeof(wchar_t);
  • uspace/lib/libc/generic/kbd.c

    rab1861a r566f4cfb  
    4343int kbd_get_event(kbd_event_t *ev)
    4444{
    45         int cons_phone = console_phone_get(true);
     45        int cons_phone = console_open(true);
    4646        ipcarg_t r0, r1, r2, r3;
    4747        int rc;
  • uspace/lib/libc/generic/libc.c

    rab1861a r566f4cfb  
    8585
    8686        main(argc, argv);
    87         console_flush_optional();
     87        console_flush();
    8888}
    8989
  • uspace/lib/libc/include/console.h

    rab1861a r566f4cfb  
    2828
    2929/** @addtogroup libc
    30  * @{ 
     30 * @{
    3131 */
    3232/** @file
     
    4141#include <bool.h>
    4242
    43 extern void console_open(bool);
     43extern int console_open(bool);
    4444extern void console_close(void);
    45 
    46 extern int console_phone_get(bool);
    4745extern void console_wait(void);
    4846
     
    5048extern void console_goto(int, int);
    5149extern void console_putchar(wchar_t);
    52 extern ssize_t console_write(const char *buf, size_t nbyte);
    53 extern void console_putstr(const char *s);
     50extern ssize_t console_write(const char *, size_t);
     51extern void console_putstr(const char *);
    5452extern void console_flush(void);
    55 extern void console_flush_optional(void);
    5653
    5754extern int console_get_size(int *, int *);
     
    6461
    6562#endif
    66  
     63
    6764/** @}
    6865 */
  • uspace/lib/libc/include/io/stream.h

    rab1861a r566f4cfb  
    3838#include <libarch/types.h>
    3939
    40 #define EMFILE -17
    41 
    42 extern void klog_update(void);
     40#define EMFILE  -17
    4341
    4442extern ssize_t read_stdin(void *, size_t);
    45 extern ssize_t write_stdout(const void *, size_t);
    46 extern ssize_t write_stderr(const void *, size_t);
    47 extern int flush_stdout(void);
     43extern void klog_update(void);
    4844
    4945#endif
Note: See TracChangeset for help on using the changeset viewer.