Changeset 953769f in mainline


Ignore:
Timestamp:
2009-06-15T21:51:50Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
103e7d7
Parents:
ef8bcc6
Message:

Handle pending input using only one fibril.
Relax serialization in console, keep your fingers crossed.
Do not create a new "pending" fibril after each received call.

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/async.c

    ref8bcc6 r953769f  
    179179static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    180180static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
    181 static void default_pending(void);
    182181
    183182/**
     
    191190 */
    192191static async_client_conn_t interrupt_received = default_interrupt_received;
    193 
    194 /**
    195  * Pointer to a fibril function that will be used to handle pending
    196  * operations.
    197  */
    198 static async_pending_t pending = default_pending;
    199192
    200193static hash_table_t conn_hash_table;
     
    376369       
    377370        fid_t fid = fibril_create(notification_fibril, msg);
    378         fibril_add_ready(fid);
    379        
    380         futex_up(&async_futex);
    381         return true;
    382 }
    383 
    384 /** Pending fibril.
    385  *
    386  * After each call the pending operations are executed in a separate
    387  * fibril. The function pending() is c.
    388  *
    389  * @param arg Unused.
    390  *
    391  * @return Always zero.
    392  *
    393  */
    394 static int pending_fibril(void *arg)
    395 {
    396         pending();
    397        
    398         return 0;
    399 }
    400 
    401 /** Process pending actions.
    402  *
    403  * A new fibril is created which would process the pending operations.
    404  *
    405  * @return False if an error occured.
    406  *         True if the execution was passed to the pending fibril.
    407  *
    408  */
    409 static bool process_pending(void)
    410 {
    411         futex_down(&async_futex);
    412        
    413         fid_t fid = fibril_create(pending_fibril, NULL);
    414371        fibril_add_ready(fid);
    415372       
     
    514471}
    515472
    516 /** Default fibril function that gets called to handle pending operations.
    517  *
    518  * This function is defined as a weak symbol - to be redefined in user code.
    519  *
    520  */
    521 static void default_pending(void)
    522 {
    523 }
    524 
    525473/** Wrapper for client connection fibril.
    526474 *
     
    661609       
    662610out:
    663         process_pending();
     611        ;
    664612}
    665613
     
    1050998}
    1051999
    1052 /** Setter for pending function pointer.
    1053  *
    1054  * @param pend Function that will implement a new pending
    1055  *             operations fibril.
    1056  */
    1057 void async_set_pending(async_pending_t pend)
    1058 {
    1059         pending = pend;
    1060 }
    1061 
    10621000/** Pseudo-synchronous message sending - fast version.
    10631001 *
  • uspace/lib/libc/include/async.h

    ref8bcc6 r953769f  
    4444typedef ipc_callid_t aid_t;
    4545typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
    46 typedef void (*async_pending_t)(void);
    4746
    4847extern atomic_t async_futex;
     
    10099extern void async_set_client_connection(async_client_conn_t conn);
    101100extern void async_set_interrupt_received(async_client_conn_t conn);
    102 extern void async_set_pending(async_pending_t pend);
    103101
    104102/* Wrappers for simple communication */
  • uspace/srv/console/console.c

    ref8bcc6 r953769f  
    5252#include <event.h>
    5353#include <devmap.h>
     54#include <assert.h>
     55#include <fibril_sync.h>
    5456
    5557#include "console.h"
     
    112114LIST_INITIALIZE(pending_input);
    113115
     116static FIBRIL_MUTEX_INITIALIZE(input_mutex);
     117static FIBRIL_CONDVAR_INITIALIZE(input_cv);
     118static input_flag = false;
     119
    114120/** Process pending input requests */
    115121static void process_pending_input(void)
    116122{
    117         async_serialize_start();
    118        
    119123        link_t *cur;
    120124       
    121125loop:
     126        fibril_mutex_lock(&input_mutex);
     127        while (!input_flag)
     128                fibril_condvar_wait(&input_cv, &input_mutex);
     129rescan:
    122130        for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
    123131                pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
     
    133141                        } else {
    134142                                ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
    135                                
    136143                                list_remove(cur);
    137144                                free(pr);
    138                                
    139                                 goto loop;
     145                                goto rescan;
    140146                        }
    141147                }
     
    144150                        (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
    145151                        ipc_answer_1(pr->rid, EOK, pr->size);
    146                        
     152
    147153                        free(pr->data);
    148154                        list_remove(cur);
    149155                        free(pr);
    150                        
    151                         goto loop;
    152                 }
    153         }
    154        
    155         async_serialize_end();
     156                        goto rescan;
     157                }
     158        }
     159        input_flag = false;
     160        fibril_mutex_unlock(&input_mutex);
     161        goto loop;
    156162}
    157163
     
    454460                        }
    455461                       
     462                        fibril_mutex_lock(&input_mutex);
    456463                        keybuffer_push(&active_console->keybuffer, &ev);
     464                        input_flag = true;
     465                        fibril_condvar_signal(&input_cv);
     466                        fibril_mutex_unlock(&input_mutex);
    457467                        break;
    458468                default:
     
    515525        }
    516526       
    517         async_serialize_start();
    518        
    519527        size_t pos = 0;
    520528        console_event_t ev;
     529        fibril_mutex_lock(&input_mutex);
    521530        while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
    522531                if (ev.type == KEY_PRESS) {
     
    533542                pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
    534543                if (!pr) {
     544                        fibril_mutex_unlock(&input_mutex);
    535545                        ipc_answer_0(callid, ENOMEM);
    536546                        ipc_answer_0(rid, ENOMEM);
    537547                        free(buf);
    538                         async_serialize_end();
    539548                        return;
    540549                }
     
    548557                list_append(&pr->link, &pending_input);
    549558        }
    550        
    551         async_serialize_end();
     559        fibril_mutex_unlock(&input_mutex);
    552560}
    553561
    554562static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    555563{
    556         async_serialize_start();
    557        
    558564        console_event_t ev;
     565
     566        fibril_mutex_lock(&input_mutex);
    559567        if (keybuffer_pop(&cons->keybuffer, &ev)) {
    560568                ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
     
    562570                pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
    563571                if (!pr) {
     572                        fibril_mutex_unlock(&input_mutex);
    564573                        ipc_answer_0(rid, ENOMEM);
    565                         async_serialize_end();
    566574                        return;
    567575                }
     
    573581                list_append(&pr->link, &pending_input);
    574582        }
    575        
    576         async_serialize_end();
     583        fibril_mutex_unlock(&input_mutex);
    577584}
    578585
     
    716723static bool console_init(void)
    717724{
    718         async_serialize_start();
    719        
    720725        /* Connect to keyboard driver */
    721726        kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
    722727        if (kbd_phone < 0) {
    723728                printf(NAME ": Failed to connect to keyboard service\n");
    724                 async_serialize_end();
    725729                return false;
    726730        }
     
    729733        if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
    730734                printf(NAME ": Failed to create callback from keyboard service\n");
    731                 async_serialize_end();
    732735                return false;
    733736        }
    734737       
    735         async_set_pending(process_pending_input);
    736738        async_new_connection(phonehash, 0, NULL, keyboard_events);
     739
     740        fid_t fid = fibril_create(process_pending_input, NULL);
     741        if (!fid) {
     742                printf(NAME ": Failed to create fibril for handling pending "
     743                    "input\n");
     744                return -1;
     745        }
     746        fibril_add_ready(fid);
    737747       
    738748        /* Connect to framebuffer driver */
     
    740750        if (fb_info.phone < 0) {
    741751                printf(NAME ": Failed to connect to video service\n");
    742                 async_serialize_end();
    743752                return -1;
    744753        }
     
    748757        if (rc < 0) {
    749758                printf(NAME ": Unable to register driver (%d)\n", rc);
    750                 async_serialize_end();
    751759                return false;
    752760        }
     
    784792                            fb_info.cols, fb_info.rows) == NULL) {
    785793                                printf(NAME ": Unable to allocate screen buffer %u\n", i);
    786                                 async_serialize_end();
    787794                                return false;
    788795                        }
     
    798805                                devmap_hangup_phone(DEVMAP_DRIVER);
    799806                                printf(NAME ": Unable to register device %s\n", vc);
    800                                 async_serialize_end();
    801807                                return false;
    802808                        }
     
    808814       
    809815        /* Initialize the screen */
     816        async_serialize_start();
    810817        gcons_redraw_console();
    811818        set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     
    813820        curs_goto(0, 0);
    814821        curs_visibility(active_console->scr.is_cursor_visible);
     822        async_serialize_end();
    815823       
    816824        /* Receive kernel notifications */
     
    820828        async_set_interrupt_received(interrupt_received);
    821829       
    822         async_serialize_end();
    823830        return true;
    824831}
Note: See TracChangeset for help on using the changeset viewer.