Changeset bc1f1c2 in mainline for uspace/lib/libc/generic/async.c


Ignore:
Timestamp:
2007-06-28T00:54:12Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
12f91130
Parents:
b9641ee
Message:

Goodbye pseudo threads, welcome fibrils.
The renaming might still be incomplete.

File:
1 edited

Legend:

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

    rb9641ee rbc1f1c2  
    8686 * }
    8787 *
    88  * TODO: Detaching/joining dead psthreads?
    8988 */
    9089#include <futex.h>
    9190#include <async.h>
    92 #include <psthread.h>
     91#include <fibril.h>
    9392#include <stdio.h>
    9493#include <libadt/hash_table.h>
     
    105104
    106105typedef struct {
    107         struct timeval expires;         /**< Expiration time for waiting thread */
    108         int inlist;                     /**< If true, this struct is in timeout list */
     106        /** Expiration time for waiting fibril. */
     107        struct timeval expires;         
     108        /** If true, this struct is in the timeout list. */
     109        int inlist;
    109110        link_t link;
    110111
    111         pstid_t ptid;                   /**< Thread waiting for this message */
    112         int active;                     /**< If this thread is currently active */
    113         int timedout;                   /**< If true, we timed out */
     112        /** Fibril waiting for this message. */
     113        fid_t fid;
     114        /** If this fibril is currently active. */
     115        int active;
     116        /** If true, we timed out. */
     117        int timedout;
    114118} awaiter_t;
    115119
     
    119123        int done;                       /**< If reply was received */
    120124        ipc_call_t *dataptr;            /**< Pointer where the answer data
    121                                           *   is stored */
     125                                         *   is stored */
    122126        ipcarg_t retval;
    123127} amsg_t;
     
    132136        awaiter_t wdata;
    133137
    134         link_t link;                    /**< Hash table link */
     138        link_t link;                    /**< Hash table link. */
    135139        ipcarg_t in_phone_hash;         /**< Incoming phone hash. */
    136         link_t msg_queue;               /**< Messages that should be delivered to this thread */
     140        link_t msg_queue;               /**< Messages that should be delivered
     141                                         *   to this fibril. */
    137142        /* Structures for connection opening packet */
    138143        ipc_callid_t callid;
    139144        ipc_call_t call;
    140         ipc_callid_t close_callid;      /* Identification of closing packet */
    141         void (*cthread)(ipc_callid_t,ipc_call_t *);
     145        ipc_callid_t close_callid;      /* Identification of closing packet. */
     146        void (*cfibril)(ipc_callid_t, ipc_call_t *);
    142147} connection_t;
    143148
    144 /** Identifier of incoming connection handled by current thread */
    145 __thread connection_t *PS_connection;
     149/** Identifier of the incoming connection handled by the current fibril. */
     150__thread connection_t *FIBRIL_connection;
    146151/** If true, it is forbidden to use async_req functions and
    147152 *  all preemption is disabled */
     
    286291                }
    287292                conn->wdata.active = 1;
    288                 psthread_add_ready(conn->wdata.ptid);
     293                fibril_add_ready(conn->wdata.fid);
    289294        }
    290295
     
    301306        connection_t *conn;
    302307       
    303         assert(PS_connection);
    304         /* GCC 4.1.0 coughs on PS_connection-> dereference,
     308        assert(FIBRIL_connection);
     309        /* GCC 4.1.0 coughs on FIBRIL_connection-> dereference,
    305310         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    306311         *           I would never expect to find so many errors in
    307312         *           compiler *($&$(*&$
    308313         */
    309         conn = PS_connection;
     314        conn = FIBRIL_connection;
    310315
    311316        futex_down(&async_futex);
     
    323328
    324329                conn->wdata.active = 0;
    325                 psthread_schedule_next_adv(PS_TO_MANAGER);
     330                fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
    326331                /* Futex is up after getting back from async_manager
    327332                 * get it again */
    328333                futex_down(&async_futex);
    329                 if (usecs && conn->wdata.timedout && \
     334                if (usecs && conn->wdata.timedout &&
    330335                    list_empty(&conn->msg_queue)) {
    331336                        /* If we timed out-> exit */
     
    365370 * @param arg Connection structure pointer
    366371 */
    367 static int connection_thread(void  *arg)
     372static int connection_fibril(void  *arg)
    368373{
    369374        unsigned long key;
     
    372377
    373378        /* Setup thread local connection pointer */
    374         PS_connection = (connection_t *)arg;
    375         PS_connection->cthread(PS_connection->callid, &PS_connection->call);
     379        FIBRIL_connection = (connection_t *) arg;
     380        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
     381            &FIBRIL_connection->call);
    376382       
    377383        /* Remove myself from connection hash table */
    378384        futex_down(&async_futex);
    379         key = PS_connection->in_phone_hash;
     385        key = FIBRIL_connection->in_phone_hash;
    380386        hash_table_remove(&conn_hash_table, &key, 1);
    381387        futex_up(&async_futex);
    382388       
    383389        /* Answer all remaining messages with ehangup */
    384         while (!list_empty(&PS_connection->msg_queue)) {
    385                 msg = list_get_instance(PS_connection->msg_queue.next, msg_t, link);
     390        while (!list_empty(&FIBRIL_connection->msg_queue)) {
     391                msg = list_get_instance(FIBRIL_connection->msg_queue.next,
     392                    msg_t, link);
    386393                list_remove(&msg->link);
    387                 if (msg->callid == PS_connection->close_callid)
     394                if (msg->callid == FIBRIL_connection->close_callid)
    388395                        close_answered = 1;
    389396                ipc_answer_fast(msg->callid, EHANGUP, 0, 0);
    390397                free(msg);
    391398        }
    392         if (PS_connection->close_callid)
    393                 ipc_answer_fast(PS_connection->close_callid, 0, 0, 0);
     399        if (FIBRIL_connection->close_callid)
     400                ipc_answer_fast(FIBRIL_connection->close_callid, 0, 0, 0);
    394401       
    395402        return 0;
     
    406413 * @param callid Callid of the IPC_M_CONNECT_ME_TO packet
    407414 * @param call Call data of the opening packet
    408  * @param cthread Thread function that should be called upon
     415 * @param cfibril Fibril function that should be called upon
    409416 *                opening the connection
    410  * @return New thread id
    411  */
    412 pstid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid, ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *))
     417 * @return New fibril id.
     418 */
     419fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
     420    ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
    413421{
    414422        connection_t *conn;
     
    427435                conn->call = *call;
    428436        conn->wdata.active = 1; /* We will activate it asap */
    429         conn->cthread = cthread;
    430 
    431         conn->wdata.ptid = psthread_create(connection_thread, conn);
    432         if (!conn->wdata.ptid) {
     437        conn->cfibril = cfibril;
     438
     439        conn->wdata.fid = fibril_create(connection_fibril, conn);
     440        if (!conn->wdata.fid) {
    433441                free(conn);
    434442                ipc_answer_fast(callid, ENOMEM, 0, 0);
     
    441449        futex_up(&async_futex);
    442450
    443         psthread_add_ready(conn->wdata.ptid);
    444 
    445         return conn->wdata.ptid;
     451        fibril_add_ready(conn->wdata.fid);
     452
     453        return conn->wdata.fid;
    446454}
    447455
     
    460468        case IPC_M_CONNECT_ME_TO:
    461469                /* Open new connection with thread etc. */
    462                 async_new_connection(IPC_GET_ARG3(*call), callid, call, client_connection);
     470                async_new_connection(IPC_GET_ARG3(*call), callid, call,
     471                    client_connection);
    463472                return;
    464473        }
     
    486495        cur = timeout_list.next;
    487496        while (cur != &timeout_list) {
    488                 waiter = list_get_instance(cur,awaiter_t,link);
     497                waiter = list_get_instance(cur, awaiter_t, link);
    489498                if (tv_gt(&waiter->expires, &tv))
    490499                        break;
     
    498507                if (!waiter->active) {
    499508                        waiter->active = 1;
    500                         psthread_add_ready(waiter->ptid);
     509                        fibril_add_ready(waiter->fid);
    501510                }
    502511        }
     
    515524
    516525        while (1) {
    517                 if (psthread_schedule_next_adv(PS_FROM_MANAGER)) {
     526                if (fibril_schedule_next_adv(FIBRIL_FROM_MANAGER)) {
    518527                        futex_up(&async_futex);
    519528                        /* async_futex is always held
     
    524533                futex_down(&async_futex);
    525534                if (!list_empty(&timeout_list)) {
    526                         waiter = list_get_instance(timeout_list.next,awaiter_t,link);
    527                         gettimeofday(&tv,NULL);
     535                        waiter = list_get_instance(timeout_list.next, awaiter_t,
     536                            link);
     537                        gettimeofday(&tv, NULL);
    528538                        if (tv_gteq(&tv, &waiter->expires)) {
    529539                                futex_up(&async_futex);
     
    573583void async_create_manager(void)
    574584{
    575         pstid_t ptid;
    576 
    577         ptid = psthread_create(async_manager_thread, NULL);
    578         psthread_add_manager(ptid);
     585        fid_t fid;
     586
     587        fid = fibril_create(async_manager_thread, NULL);
     588        fibril_add_manager(fid);
    579589}
    580590
     
    582592void async_destroy_manager(void)
    583593{
    584         psthread_remove_manager();
     594        fibril_remove_manager();
    585595}
    586596
     
    588598int _async_init(void)
    589599{
    590         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1, &conn_hash_table_ops)) {
     600        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
     601            &conn_hash_table_ops)) {
    591602                printf("%s: cannot create hash table\n", "async");
    592603                return ENOMEM;
     
    598609/** IPC handler for messages in async framework
    599610 *
    600  * Notify thread that is waiting for this message, that it arrived
     611 * Notify the fibril which is waiting for this message, that it arrived
    601612 */
    602613static void reply_received(void *private, int retval,
     
    621632        if (! msg->wdata.active) {
    622633                msg->wdata.active = 1;
    623                 psthread_add_ready(msg->wdata.ptid);
     634                fibril_add_ready(msg->wdata.fid);
    624635        }
    625636        futex_up(&async_futex);
     
    633644aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
    634645                   ipc_call_t *dataptr)
     646{
     647        amsg_t *msg;
     648
     649        if (in_interrupt_handler) {
     650                printf("Cannot send asynchronous request in interrupt "
     651                    "handler.\n");
     652                _exit(1);
     653        }
     654
     655        msg = malloc(sizeof(*msg));
     656        msg->done = 0;
     657        msg->dataptr = dataptr;
     658
     659        msg->wdata.active = 1; /* We may sleep in next method, but it
     660                                * will use it's own mechanism */
     661        ipc_call_async_2(phoneid, method, arg1, arg2, msg, reply_received, 1);
     662
     663        return (aid_t) msg;
     664}
     665
     666/** Send message and return id of the sent message
     667 *
     668 * The return value can be used as input for async_wait() to wait
     669 * for completion.
     670 */
     671aid_t async_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     672                   ipcarg_t arg3, ipc_call_t *dataptr)
    635673{
    636674        amsg_t *msg;
     
    647685        msg->wdata.active = 1; /* We may sleep in next method, but it
    648686                                * will use it's own mechanism */
    649         ipc_call_async_2(phoneid,method,arg1,arg2,msg,reply_received,1);
    650 
    651         return (aid_t) msg;
    652 }
    653 
    654 /** Send message and return id of the sent message
    655  *
    656  * The return value can be used as input for async_wait() to wait
    657  * for completion.
    658  */
    659 aid_t async_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
    660                    ipcarg_t arg3, ipc_call_t *dataptr)
    661 {
    662         amsg_t *msg;
    663 
    664         if (in_interrupt_handler) {
    665                 printf("Cannot send asynchronous request in interrupt handler.\n");
    666                 _exit(1);
    667         }
    668 
    669         msg = malloc(sizeof(*msg));
    670         msg->done = 0;
    671         msg->dataptr = dataptr;
    672 
    673         msg->wdata.active = 1; /* We may sleep in next method, but it
    674                                 * will use it's own mechanism */
    675         ipc_call_async_3(phoneid,method,arg1,arg2,arg3, msg,reply_received,1);
     687        ipc_call_async_3(phoneid, method, arg1, arg2, arg3, msg, reply_received,
     688            1);
    676689
    677690        return (aid_t) msg;
     
    695708        }
    696709
    697         msg->wdata.ptid = psthread_get_id();
     710        msg->wdata.fid = fibril_get_id();
    698711        msg->wdata.active = 0;
    699712        msg->wdata.inlist = 0;
    700713        /* Leave locked async_futex when entering this function */
    701         psthread_schedule_next_adv(PS_TO_MANAGER);
    702         /* futex is up automatically after psthread_schedule_next...*/
     714        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
     715        /* futex is up automatically after fibril_schedule_next...*/
    703716done:
    704717        if (retval)
     
    733746        tv_add(&msg->wdata.expires, timeout);
    734747
    735         msg->wdata.ptid = psthread_get_id();
     748        msg->wdata.fid = fibril_get_id();
    736749        msg->wdata.active = 0;
    737750        insert_timeout(&msg->wdata);
    738751
    739752        /* Leave locked async_futex when entering this function */
    740         psthread_schedule_next_adv(PS_TO_MANAGER);
    741         /* futex is up automatically after psthread_schedule_next...*/
     753        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
     754        /* futex is up automatically after fibril_schedule_next...*/
    742755
    743756        if (!msg->done)
     
    769782                return;
    770783
    771         msg->wdata.ptid = psthread_get_id();
     784        msg->wdata.fid = fibril_get_id();
    772785        msg->wdata.active = 0;
    773786
     
    778791        insert_timeout(&msg->wdata);
    779792        /* Leave locked async_futex when entering this function */
    780         psthread_schedule_next_adv(PS_TO_MANAGER);
    781         /* futex is up automatically after psthread_schedule_next...*/
     793        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
     794        /* futex is up automatically after fibril_schedule_next...*/
    782795        free(msg);
    783796}
     
    800813                 ipcarg_t arg2, ipcarg_t arg3)
    801814{
    802         ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, !in_interrupt_handler);
     815        ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL,
     816            !in_interrupt_handler);
    803817}
    804818
    805819void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)
    806820{
    807         ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, !in_interrupt_handler);
     821        ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL,
     822            !in_interrupt_handler);
    808823}
    809824
Note: See TracChangeset for help on using the changeset viewer.