Changeset 9db9b10 in mainline


Ignore:
Timestamp:
2009-06-03T19:16:07Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
937aeee
Parents:
e77994dd
Message:

async framework: add generic support for processing pending operations (in a separate fibril)
coding style

Location:
uspace/lib/libc
Files:
2 edited

Legend:

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

    re77994dd r9db9b10  
    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);
     181static void default_pending(void);
    181182
    182183/**
     
    191192static async_client_conn_t interrupt_received = default_interrupt_received;
    192193
     194/**
     195 * Pointer to a fibril function that will be used to handle pending
     196 * operations.
     197 */
     198static async_pending_t pending = default_pending;
    193199
    194200static hash_table_t conn_hash_table;
    195201static LIST_INITIALIZE(timeout_list);
    196 
    197202
    198203#define CONN_HASH_TABLE_CHAINS  32
     
    371376       
    372377        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 */
     394static 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 */
     409static bool process_pending(void)
     410{
     411        futex_down(&async_futex);
     412       
     413        fid_t fid = fibril_create(pending_fibril, NULL);
    373414        fibril_add_ready(fid);
    374415       
     
    473514}
    474515
     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 */
     521static void default_pending(void)
     522{
     523}
     524
    475525/** Wrapper for client connection fibril.
    476526 *
     
    564614       
    565615        /* Add connection to the connection hash table */
    566         ipcarg_t key = conn->in_phone_hash;
     616        unsigned long key = conn->in_phone_hash;
    567617       
    568618        futex_down(&async_futex);
     
    589639        if ((callid & IPC_CALLID_NOTIFICATION)) {
    590640                process_notification(callid, call);
    591                 return;
     641                goto out;
    592642        }
    593643       
     
    598648                async_new_connection(IPC_GET_ARG5(*call), callid, call,
    599649                    client_connection);
    600                 return;
     650                goto out;
    601651        }
    602652       
    603653        /* Try to route the call through the connection hash table */
    604654        if (route_call(callid, call))
    605                 return;
     655                goto out;
    606656       
    607657        /* Unknown call from unknown phone - hang it up */
    608658        ipc_answer_0(callid, EHANGUP);
     659        return;
     660       
     661out:
     662        process_pending();
    609663}
    610664
     
    760814static void reply_received(void *arg, int retval, ipc_call_t *data)
    761815{
     816        futex_down(&async_futex);
     817       
    762818        amsg_t *msg = (amsg_t *) arg;
    763819        msg->retval = retval;
    764820       
    765         futex_down(&async_futex);
    766        
    767821        /* Copy data after futex_down, just in case the call was detached */
    768         if (msg->dataptr)
     822        if ((msg->dataptr) && (data))
    769823                *msg->dataptr = *data;
    770824       
     
    9931047{
    9941048        interrupt_received = intr;
     1049}
     1050
     1051/** Setter for pending function pointer.
     1052 *
     1053 * @param pend Function that will implement a new pending
     1054 *             operations fibril.
     1055 */
     1056void async_set_pending(async_pending_t pend)
     1057{
     1058        pending = pend;
    9951059}
    9961060
  • uspace/lib/libc/include/async.h

    re77994dd r9db9b10  
    4444typedef ipc_callid_t aid_t;
    4545typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
     46typedef void (*async_pending_t)(void);
     47
     48extern atomic_t async_futex;
    4649
    4750static inline void async_manager(void)
     
    5053}
    5154
    52 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
     55extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
     56
    5357static inline ipc_callid_t async_get_call(ipc_call_t *data)
    5458{
     
    6468
    6569#define async_send_0(phoneid, method, dataptr) \
    66     async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
     70        async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
    6771#define async_send_1(phoneid, method, arg1, dataptr) \
    68     async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
     72        async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
    6973#define async_send_2(phoneid, method, arg1, arg2, dataptr) \
    70     async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
     74        async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
    7175#define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
    72     async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
     76        async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
    7377#define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
    74     async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    75         (dataptr))
     78        async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
     79            (dataptr))
    7680#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
    77     async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    78         (arg5), (dataptr))
     81        async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
     82            (arg5), (dataptr))
    7983
    8084extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     
    8791    suseconds_t timeout);
    8892
    89 fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
     93extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
    9094    ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
    91 void async_usleep(suseconds_t timeout);
    92 void async_create_manager(void);
    93 void async_destroy_manager(void);
    94 int _async_init(void);
     95extern void async_usleep(suseconds_t timeout);
     96extern void async_create_manager(void);
     97extern void async_destroy_manager(void);
     98extern int _async_init(void);
    9599
    96100extern void async_set_client_connection(async_client_conn_t conn);
    97101extern void async_set_interrupt_received(async_client_conn_t conn);
     102extern void async_set_pending(async_pending_t pend);
    98103
    99104/* Wrappers for simple communication */
    100105#define async_msg_0(phone, method) \
    101     ipc_call_async_0((phone), (method), NULL, NULL, true)
     106        ipc_call_async_0((phone), (method), NULL, NULL, true)
    102107#define async_msg_1(phone, method, arg1) \
    103     ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
    104         true)
     108        ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
     109            true)
    105110#define async_msg_2(phone, method, arg1, arg2) \
    106     ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
    107         true)
     111        ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
     112            true)
    108113#define async_msg_3(phone, method, arg1, arg2, arg3) \
    109     ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
    110         true)
     114        ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
     115            true)
    111116#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
    112     ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
    113         NULL, true)
     117        ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
     118            NULL, true)
    114119#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
    115     ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
    116         (arg5), NULL, NULL, true)
     120        ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
     121            (arg5), NULL, NULL, true)
    117122
    118123/*
     
    123128 */
    124129#define async_req_0_0(phoneid, method) \
    125     async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
    126         NULL)
     130        async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
     131            NULL)
    127132#define async_req_0_1(phoneid, method, r1) \
    128     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
    129         NULL)
     133        async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
     134            NULL)
    130135#define async_req_0_2(phoneid, method, r1, r2) \
    131     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
    132         NULL)
     136        async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
     137            NULL)
    133138#define async_req_0_3(phoneid, method, r1, r2, r3) \
    134     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
    135         NULL)
     139        async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
     140            NULL)
    136141#define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
    137     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
    138         NULL)
     142        async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
     143            NULL)
    139144#define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
    140     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
    141         (r5))
     145        async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
     146            (r5))
    142147#define async_req_1_0(phoneid, method, arg1) \
    143     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
    144         NULL, NULL)
     148        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
     149            NULL, NULL)
    145150#define async_req_1_1(phoneid, method, arg1, rc1) \
    146     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
    147         NULL, NULL)
     151        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
     152            NULL, NULL)
    148153#define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
    149     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
    150         NULL, NULL)
     154        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
     155            NULL, NULL)
    151156#define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
    152     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    153         NULL, NULL)
     157        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
     158            NULL, NULL)
    154159#define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
    155     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    156         (rc4), NULL)
     160        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
     161            (rc4), NULL)
    157162#define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
    158     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    159         (rc4), (rc5))
     163        async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
     164            (rc4), (rc5))
    160165#define async_req_2_0(phoneid, method, arg1, arg2) \
    161     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
    162         NULL, NULL, NULL)
     166        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
     167            NULL, NULL, NULL)
    163168#define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
    164     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
    165         NULL, NULL, NULL)
     169        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
     170            NULL, NULL, NULL)
    166171#define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
    167     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    168         NULL, NULL, NULL)
     172        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
     173            NULL, NULL, NULL)
    169174#define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
    170     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    171         (rc3), NULL, NULL)
     175        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
     176            (rc3), NULL, NULL)
    172177#define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
    173     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    174         (rc3), (rc4), NULL)
     178        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
     179            (rc3), (rc4), NULL)
    175180#define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
    176     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    177         (rc3), (rc4), (rc5))
     181        async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
     182            (rc3), (rc4), (rc5))
    178183#define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
    179     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
    180         NULL, NULL, NULL)
     184        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
     185            NULL, NULL, NULL)
    181186#define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
    182     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    183         NULL, NULL, NULL, NULL)
     187        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
     188            NULL, NULL, NULL, NULL)
    184189#define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
    185     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    186         (rc2), NULL, NULL, NULL)
     190        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
     191            (rc2), NULL, NULL, NULL)
    187192#define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
    188     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    189         (rc2), (rc3), NULL, NULL)
     193        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
     194            (rc2), (rc3), NULL, NULL)
    190195#define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
    191     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    192         (rc2), (rc3), (rc4), NULL)
     196        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
     197            (rc2), (rc3), (rc4), NULL)
    193198#define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
    194199    rc5) \
     
    196201            (rc2), (rc3), (rc4), (rc5))
    197202#define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
    198     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
    199         NULL, NULL, NULL, NULL)
     203        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
     204            NULL, NULL, NULL, NULL)
    200205#define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
    201     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    202         NULL, NULL, NULL, NULL)
     206        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
     207            NULL, NULL, NULL, NULL)
    203208#define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
    204     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    205         (rc2), NULL, NULL, NULL)
     209        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
     210            (rc2), NULL, NULL, NULL)
    206211#define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
    207     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    208         (rc2), (rc3), NULL, NULL)
     212        async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
     213            (rc2), (rc3), NULL, NULL)
    209214#define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
    210215    rc4) \
     
    216221            (rc1), (rc2), (rc3), (rc4), (rc5))
    217222#define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
    218     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    219         (arg5), NULL, NULL, NULL, NULL, NULL)
     223        async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
     224            (arg5), NULL, NULL, NULL, NULL, NULL)
    220225#define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
    221     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    222         (arg5), (rc1), NULL, NULL, NULL, NULL)
     226        async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
     227            (arg5), (rc1), NULL, NULL, NULL, NULL)
    223228#define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
    224     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    225         (arg5), (rc1), (rc2), NULL, NULL, NULL)
     229        async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
     230            (arg5), (rc1), (rc2), NULL, NULL, NULL)
    226231#define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
    227232    rc3) \
     
    254259}
    255260
    256 extern atomic_t async_futex;
    257 
    258261#endif
    259262
Note: See TracChangeset for help on using the changeset viewer.