Changeset 01ff41c in mainline


Ignore:
Timestamp:
2006-05-27T22:28:25Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7f5b37a
Parents:
7f9cd77
Message:

Added functions to async framework for reasonable sending asynchronous
messages.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • init/init.c

    r7f9cd77 r01ff41c  
    4444#include <kbd.h>
    4545#include <ipc/fb.h>
     46#include <async.h>
    4647
    4748int a;
     
    319320}
    320321
     322static void test_async_kbd()
     323{
     324        int res;
     325        ipcarg_t result;
     326        ipc_call_t kbddata;
     327        int phoneid;
     328        aid_t aid;
     329
     330        printf("Test: Starting connect...\n");
     331        while ((phoneid = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0)) < 0) {
     332        };
     333       
     334        printf("Test: Connected: %d\n", res);
     335        printf("Test: pinging.\n");
     336        while (1) {
     337                aid = async_send_2(phoneid, KBD_GETCHAR, 0, 0, &kbddata);
     338                async_wait_for(aid, NULL);
     339                printf("%c", IPC_GET_ARG1(kbddata));
     340        }
     341       
     342        printf("Test: Hangin up\n");
     343        ipc_hangup(phoneid);
     344}
     345
    321346static void test_pci()
    322347{
     
    393418//      test_hangup();
    394419//      test_slam();
    395         test_as_area_send();
     420//      test_as_area_send();
    396421//      test_pci();
    397         test_kbd();
     422//      test_kbd();
     423        test_async_kbd();
    398424//      test_fb();
    399425
  • libc/generic/async.c

    r7f9cd77 r01ff41c  
    9292#include <errno.h>
    9393
    94 static atomic_t conn_futex = FUTEX_INITIALIZER;
     94static atomic_t async_futex = FUTEX_INITIALIZER;
    9595static hash_table_t conn_hash_table;
     96
     97typedef struct {
     98        pstid_t ptid;                /**< Thread waiting for this message */
     99        int active;                  /**< If this thread is currently active */
     100        int done;                    /**< If reply was received */
     101        ipc_call_t *dataptr;         /**< Pointer where the answer data
     102                                      *   should be stored */
     103        ipcarg_t retval;
     104} amsg_t;
    96105
    97106typedef struct {
     
    116125
    117126/* Hash table functions */
    118 
    119127#define CONN_HASH_TABLE_CHAINS  32
    120128
     
    147155};
    148156
     157/*************************************************/
     158
    149159/** Try to route a call to an appropriate connection thread
    150160 *
     
    157167        unsigned long key;
    158168
    159         futex_down(&conn_futex);
     169        futex_down(&async_futex);
    160170
    161171        key = call->in_phone_hash;
    162172        hlp = hash_table_find(&conn_hash_table, &key);
    163173        if (!hlp) {
    164                 futex_up(&conn_futex);
     174                futex_up(&async_futex);
    165175                return 0;
    166176        }
     
    177187        }
    178188
    179         futex_up(&conn_futex);
     189        futex_up(&async_futex);
    180190
    181191        return 1;
     
    189199        connection_t *conn;
    190200       
    191         futex_down(&conn_futex);
     201        futex_down(&async_futex);
    192202
    193203        conn = PS_connection;
     
    204214        free(msg);
    205215       
    206         futex_up(&conn_futex);
     216        futex_up(&async_futex);
    207217        return callid;
    208218}
     
    237247
    238248        /* Remove myself from connection hash table */
    239         futex_down(&conn_futex);
     249        futex_down(&async_futex);
    240250        key = conn->in_phone_hash;
    241251        hash_table_remove(&conn_hash_table, &key, 1);
    242         futex_up(&conn_futex);
     252        futex_up(&async_futex);
    243253        /* Answer all remaining messages with ehangup */
    244254        while (!list_empty(&conn->msg_queue)) {
     
    289299        }
    290300        key = conn->in_phone_hash;
    291         futex_down(&conn_futex);
     301        futex_down(&async_futex);
    292302        /* Add connection to hash table */
    293303        hash_table_insert(&conn_hash_table, &key, &conn->link);
    294         futex_up(&conn_futex);
     304        futex_up(&async_futex);
    295305
    296306        psthread_add_ready(conn->ptid);
     
    299309}
    300310
    301 /** Handle call to a task */
     311/** Handle call that was received */
    302312static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    303313{
     
    325335        while (1) {
    326336                if (psthread_schedule_next_adv(PS_FROM_MANAGER)) {
    327                         futex_up(&conn_futex); /* conn_futex is always held
     337                        futex_up(&async_futex); /* async_futex is always held
    328338                                                * when entering manager thread
    329339                                                */
     
    334344                if (callid & IPC_CALLID_ANSWERED)
    335345                        continue;
     346
    336347                handle_call(callid, &call);
    337348        }
     
    347358static int async_manager_thread(void *arg)
    348359{
    349         futex_up(&conn_futex); /* conn_futex is always locked when entering
     360        futex_up(&async_futex); /* async_futex is always locked when entering
    350361                                * manager */
    351362        async_manager();
     
    376387       
    377388}
     389
     390/** IPC handler for messages in async framework
     391 *
     392 * Notify thread that is waiting for this message, that it arrived
     393 */
     394static void reply_received(void *private, int retval,
     395                           ipc_call_t *data)
     396{
     397        amsg_t *msg = (amsg_t *) private;
     398
     399        msg->retval = retval;
     400
     401        futex_down(&async_futex);
     402        /* Copy data after futex_down, just in case the
     403         * call was detached
     404         */
     405        if (msg->dataptr)
     406                *msg->dataptr = *data;
     407       
     408        msg->done = 1;
     409        if (! msg->active) {
     410                msg->active = 1;
     411                psthread_add_ready(msg->ptid);
     412        }
     413        futex_up(&async_futex);
     414}
     415
     416/** Send message and return id of the sent message
     417 *
     418 * The return value can be used as input for async_wait() to wait
     419 * for completion.
     420 */
     421aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     422                   ipc_call_t *dataptr)
     423{
     424        amsg_t *msg;
     425
     426        msg = malloc(sizeof(*msg));
     427        msg->active = 1;
     428        msg->done = 0;
     429        msg->dataptr = dataptr;
     430        ipc_call_async_2(phoneid,method,arg1,arg2,msg,reply_received);
     431
     432        return (aid_t) msg;
     433}
     434
     435/** Wait for a message sent by async framework
     436 *
     437 * @param amsgid Message ID to wait for
     438 * @param retval Pointer to variable where will be stored retval
     439 *               of the answered message. If NULL, it is ignored.
     440 *
     441 */
     442void async_wait_for(aid_t amsgid, ipcarg_t *retval)
     443{
     444        amsg_t *msg = (amsg_t *) amsgid;
     445        connection_t *conn;
     446
     447        futex_down(&async_futex);
     448        if (msg->done) {
     449                futex_up(&async_futex);
     450                goto done;
     451        }
     452
     453        msg->ptid = psthread_get_id();
     454        msg->active = 0;
     455        /* Leave locked async_futex when entering this function */
     456        psthread_schedule_next_adv(PS_TO_MANAGER);
     457        /* futex is up automatically after psthread_schedule_next...*/
     458done:
     459        if (retval)
     460                *retval = msg->retval;
     461        free(msg);
     462}
  • libc/generic/psthread.c

    r7f9cd77 r01ff41c  
    118118/** Schedule next userspace pseudo thread.
    119119 *
     120 * If calling with PS_TO_MANAGER parameter, the async_futex should be
     121 * held.
     122 *
    120123 * @param tomanager If true, we are switching to next ready manager thread
    121124 *                  (if none is found, thread is exited)
     
    137140        }
    138141        /* If we are going to manager and none exists, create it */
    139         if (ctype == PS_TO_MANAGER && list_empty(&manager_list))
     142        while (ctype == PS_TO_MANAGER && list_empty(&manager_list)) {
     143                futex_up(&psthread_futex);
    140144                async_create_manager();
     145                futex_down(&psthread_futex);
     146        }
    141147
    142148        pt = __tcb_get()->pst_data;
     
    260266        futex_up(&psthread_futex);
    261267}
     268
     269/** Return thread id of current running thread */
     270pstid_t psthread_get_id(void)
     271{
     272        return (pstid_t)__tcb_get()->pst_data;
     273}
  • libc/generic/thread.c

    r7f9cd77 r01ff41c  
    4343#endif
    4444
     45static LIST_INITIALIZE(thread_garbage);
    4546
    4647extern char _tdata_start;
     
    146147        __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
    147148}
     149
  • libc/include/async.h

    r7f9cd77 r01ff41c  
    44#include <ipc/ipc.h>
    55#include <psthread.h>
     6
     7typedef ipc_callid_t aid_t;
    68
    79int async_manager(void);
     
    1113ipc_callid_t async_get_call(ipc_call_t *data);
    1214
    13 /* Should be defined by application */
    1415pstid_t async_new_connection(ipc_callid_t callid, ipc_call_t *call,
    1516                             void (*cthread)(ipc_callid_t,ipc_call_t *));
     17aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     18                   ipc_call_t *dataptr);
     19void async_wait_for(aid_t amsgid, ipcarg_t *result);
     20
     21
     22/* Should be defined by application */
    1623void client_connection(ipc_callid_t callid, ipc_call_t *call) __attribute__((weak));
    1724
  • libc/include/psthread.h

    r7f9cd77 r01ff41c  
    7575void psthread_add_manager(pstid_t psthrid);
    7676void psthread_remove_manager(void);
     77pstid_t psthread_get_id(void);
    7778
    7879static inline int psthread_schedule_next() {
  • libc/include/thread.h

    r7f9cd77 r01ff41c  
    3939extern int thread_create(void (* function)(void *arg), void *arg, char *name);
    4040extern void thread_exit(int status);
    41 tcb_t * __make_tls(void);
    42 tcb_t * __alloc_tls(void **data, size_t size);
    43 void __free_tls(tcb_t *);
    44 void __free_tls_arch(tcb_t *, size_t size);
     41extern tcb_t * __make_tls(void);
     42extern tcb_t * __alloc_tls(void **data, size_t size);
     43extern void __free_tls(tcb_t *);
     44extern void __free_tls_arch(tcb_t *, size_t size);
    4545
    4646#endif
Note: See TracChangeset for help on using the changeset viewer.