Changeset d2cc7e1 in mainline for uspace/srv


Ignore:
Timestamp:
2009-03-21T11:26:31Z (17 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0a5116db
Parents:
5b8c75a
Message:

Buffer console output with line granularity. Makes esp. msim/ski console faster. EGA-fb needs fixing.

Location:
uspace/srv
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/console/console.c

    r5b8c75a rd2cc7e1  
    9090                                                 * faster virtual console
    9191                                                 * switching */
     92/** Size of fb_buf. */
     93#define FB_BUF_SIZE 256
     94
     95/** Buffer for sending characters to FB driver. */
     96static char fb_buf[FB_BUF_SIZE];
     97
     98/* Properties of fb_buf data. */
     99static int fb_buf_row;          /**< Row where fb_buf data belong. */
     100static int fb_buf_col;          /**< Column where fb_buf data start. */
     101static int fb_console;          /**< VC to which fb_buf data belong. */
     102int fb_bi = 0;                  /**< Number of valid chars in fb_buf. */
     103
     104/** Size of cwrite_buf. */
     105#define CWRITE_BUF_SIZE 256
     106
     107/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
     108static char cwrite_buf[CWRITE_BUF_SIZE];
    92109
    93110
     
    159176}
    160177
     178/** Write a character vector to FB driver via IPC. */
     179static ssize_t fb_write(const char *buf, size_t nbyte, int row, int col)
     180{
     181        ipcarg_t rc;
     182        ipc_call_t answer;
     183        aid_t req;
     184
     185        async_serialize_start();
     186       
     187        req = async_send_2(fb_info.phone, FB_WRITE, row, col, &answer);
     188        rc = ipc_data_write_start(fb_info.phone, (void *) buf, nbyte);
     189
     190        if (rc != EOK) {
     191                async_wait_for(req, NULL);
     192                async_serialize_end();
     193                return (ssize_t) rc;
     194        }
     195
     196        async_wait_for(req, &rc);
     197        async_serialize_end();
     198
     199        if (rc == EOK)
     200                return (ssize_t) IPC_GET_ARG1(answer);
     201        else
     202                return -1;
     203}
     204
     205/** Flush buffered characters to FB. */
     206static void fb_buf_flush(void)
     207{
     208        screenbuffer_t *scr;
     209        int i;
     210
     211        scr = &(connections[fb_console].screenbuffer);
     212
     213        if (fb_bi > 0) {
     214                if (fb_write(fb_buf, fb_bi, fb_buf_row, fb_buf_col) < 0) {
     215                        /* Try falling back to char-by-char. */
     216                        for (i = 0; i < fb_bi; i++) {
     217                                async_msg_3(fb_info.phone, FB_PUTCHAR, fb_buf[i],
     218                                    fb_buf_row, fb_buf_col + i);
     219                        }
     220                }
     221                fb_bi = 0;
     222        }
     223}
     224
     225/** Print a character to the active VC with buffering. */
    161226static void prtchr(char c, int row, int col)
    162227{
    163         async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
     228        if (fb_bi >= FB_BUF_SIZE)
     229                fb_buf_flush();
     230
     231        if (fb_bi == 0) {
     232                fb_buf_row = row;
     233                fb_buf_col = col;
     234                fb_console = active_console;
     235        }
     236
     237        fb_buf[fb_bi++] = c;
    164238}
    165239
     
    170244static void write_char(int console, char key)
    171245{
     246        bool flush_cursor = false;
    172247        screenbuffer_t *scr = &(connections[console].screenbuffer);
    173        
     248
    174249        switch (key) {
    175250        case '\n':
     251                fb_buf_flush();
     252                flush_cursor = true;
    176253                scr->position_y++;
    177254                scr->position_x = 0;
    178255                break;
    179256        case '\r':
     257                fb_buf_flush();
    180258                break;
    181259        case '\t':
     260                fb_buf_flush();
    182261                scr->position_x += 8;
    183262                scr->position_x -= scr->position_x % 8;
    184263                break;
    185264        case '\b':
     265                fb_buf_flush();
    186266                if (scr->position_x == 0)
    187267                        break;
     
    198278                scr->position_x++;
    199279        }
    200        
    201         scr->position_y += (scr->position_x >= scr->size_x);
     280
     281        if (scr->position_x >= scr->size_x) {
     282                fb_buf_flush();
     283                flush_cursor = true;
     284                scr->position_y++;
     285        }
    202286       
    203287        if (scr->position_y >= scr->size_y) {
     
    208292                        async_msg_1(fb_info.phone, FB_SCROLL, 1);
    209293        }
    210        
     294
    211295        scr->position_x = scr->position_x % scr->size_x;
    212        
    213         if (console == active_console)
     296
     297        if (console == active_console && flush_cursor)
    214298                curs_goto(scr->position_y, scr->position_x);
    215        
    216299}
    217300
     
    226309        if (newcons == active_console)
    227310                return;
    228        
     311
     312        fb_buf_flush();
     313
    229314        if (newcons == KERNEL_CONSOLE) {
    230315                async_serialize_start();
     
    361446}
    362447
     448/** Handle CONSOLE_WRITE call. */
     449static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
     450{
     451        ipc_callid_t callid;
     452        size_t len;
     453        size_t i;
     454
     455        if (!ipc_data_write_receive(&callid, &len)) {
     456                ipc_answer_0(callid, EINVAL);
     457                ipc_answer_0(rid, EINVAL);
     458        }
     459
     460        if (len > CWRITE_BUF_SIZE)
     461                len = CWRITE_BUF_SIZE;
     462
     463        (void) ipc_data_write_finalize(callid, cwrite_buf, len);
     464
     465        for (i = 0; i < len; i++) {
     466                write_char(consnum, cwrite_buf[i]);
     467        }
     468
     469        gcons_notify_char(consnum);
     470        ipc_answer_1(rid, EOK, len);
     471}
     472
    363473/** Default thread for new connections */
    364474static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    412522                        gcons_notify_char(consnum);
    413523                        break;
     524                case CONSOLE_WRITE:
     525                        cons_write(consnum, callid, &call);
     526                        continue;
    414527                case CONSOLE_CLEAR:
    415528                        /* Send message to fb */
     
    422535                        break;
    423536                case CONSOLE_GOTO:
     537                        fb_buf_flush();
    424538                        screenbuffer_goto(&conn->screenbuffer,
    425539                            IPC_GET_ARG2(call), IPC_GET_ARG1(call));
     
    433547                        break;
    434548                case CONSOLE_FLUSH:
     549                        fb_buf_flush();
    435550                        if (consnum == active_console)
    436551                                async_req_0_0(fb_info.phone, FB_FLUSH);
    437552                        break;
    438553                case CONSOLE_SET_STYLE:
     554                        fb_buf_flush();
    439555                        arg1 = IPC_GET_ARG1(call);
    440556                        screenbuffer_set_style(&conn->screenbuffer, arg1);
     
    443559                        break;
    444560                case CONSOLE_SET_COLOR:
     561                        fb_buf_flush();
    445562                        arg1 = IPC_GET_ARG1(call);
    446563                        arg2 = IPC_GET_ARG2(call);
     
    452569                        break;
    453570                case CONSOLE_SET_RGB_COLOR:
     571                        fb_buf_flush();
    454572                        arg1 = IPC_GET_ARG1(call);
    455573                        arg2 = IPC_GET_ARG2(call);
     
    460578                        break;
    461579                case CONSOLE_CURSOR_VISIBILITY:
     580                        fb_buf_flush();
    462581                        arg1 = IPC_GET_ARG1(call);
    463582                        conn->screenbuffer.is_cursor_visible = arg1;
  • uspace/srv/fb/ega.c

    r5b8c75a rd2cc7e1  
    360360
    361361                default:
    362                         retval = ENOENT;
     362                        retval = EINVAL;
    363363                }
    364364                ipc_answer_0(callid, retval);
  • uspace/srv/fb/fb.c

    r5b8c75a rd2cc7e1  
    14721472        return rgb_from_idx(&vport->attr, fg_color, bg_color, flags);
    14731473}
     1474
     1475#define FB_WRITE_BUF_SIZE 256
     1476static char fb_write_buf[FB_WRITE_BUF_SIZE];
     1477
     1478static void fb_write(viewport_t *vport, ipc_callid_t rid, ipc_call_t *request)
     1479{
     1480        int row, col;
     1481        ipc_callid_t callid;
     1482        size_t len;
     1483        size_t i;
     1484
     1485        row = IPC_GET_ARG1(*request);
     1486        col = IPC_GET_ARG2(*request);
     1487
     1488        if ((col >= vport->cols) || (row >= vport->rows)) {
     1489                ipc_answer_0(callid, EINVAL);
     1490                ipc_answer_0(rid, EINVAL);
     1491                return;
     1492        }
     1493
     1494        if (!ipc_data_write_receive(&callid, &len)) {
     1495                ipc_answer_0(callid, EINVAL);
     1496                ipc_answer_0(rid, EINVAL);
     1497                return;
     1498        }
     1499
     1500        if (len > FB_WRITE_BUF_SIZE)
     1501                len = FB_WRITE_BUF_SIZE;
     1502        if (len >= vport->cols - col)
     1503                len = vport->cols - col;
     1504
     1505        (void) ipc_data_write_finalize(callid, fb_write_buf, len);
     1506
     1507        for (i = 0; i < len; i++) {
     1508                draw_char(vport, fb_write_buf[i], col++, row);
     1509        }
     1510
     1511        ipc_answer_1(rid, EOK, len);
     1512}
     1513
    14741514
    14751515/** Function for handling connections to FB
     
    15471587                        /* Message already answered */
    15481588                        continue;
     1589                case FB_WRITE:
     1590                        fb_write(vport, callid, &call);
     1591                       
     1592                        /* Message already answered */
     1593                        continue;
    15491594                case FB_CLEAR:
    15501595                        vport_clear(vport);
  • uspace/srv/fb/serial_console.c

    r5b8c75a rd2cc7e1  
    244244}
    245245
     246int lastcol = 0;
     247int lastrow = 0;
     248
     249#define FB_WRITE_BUF_SIZE 256
     250static char fb_write_buf[FB_WRITE_BUF_SIZE];
     251
     252static void fb_write(ipc_callid_t rid, ipc_call_t *request)
     253{
     254        int row, col;
     255        ipc_callid_t callid;
     256        size_t len;
     257        size_t i;
     258
     259        row = IPC_GET_ARG1(*request);
     260        col = IPC_GET_ARG2(*request);
     261
     262        if ((col >= scr_width) || (row >= scr_height)) {
     263                ipc_answer_0(callid, EINVAL);
     264                ipc_answer_0(rid, EINVAL);
     265                return;
     266        }
     267
     268        if (!ipc_data_write_receive(&callid, &len)) {
     269                ipc_answer_0(callid, EINVAL);
     270                ipc_answer_0(rid, EINVAL);
     271                return;
     272        }
     273
     274        if (len > FB_WRITE_BUF_SIZE)
     275                len = FB_WRITE_BUF_SIZE;
     276        if (len >= scr_width - col)
     277                len = scr_width - col;
     278
     279        (void) ipc_data_write_finalize(callid, fb_write_buf, len);
     280
     281        if ((lastcol != col) || (lastrow != row))
     282                serial_goto(row, col);
     283
     284        for (i = 0; i < len; i++) {
     285                (*putc_function)(fb_write_buf[i]);
     286        }
     287
     288        lastcol = col + len;
     289        lastrow = row;
     290
     291        ipc_answer_1(rid, EOK, len);
     292}
     293
    246294/**
    247295 * Main function of the thread serving client connections.
     
    256304
    257305        char c;
    258         int lastcol = 0;
    259         int lastrow = 0;
    260306        int newcol;
    261307        int newrow;
     
    318364                        retval = 0;
    319365                        break;
     366                case FB_WRITE:
     367                        fb_write(callid, &call);
     368                       
     369                        /* Message already answered */
     370                        continue;
    320371                case FB_CURSOR_GOTO:
    321372                        newrow = IPC_GET_ARG1(call);
Note: See TracChangeset for help on using the changeset viewer.