Changeset 2a7ba5e in mainline


Ignore:
Timestamp:
2016-05-24T21:03:32Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
609f8d9c
Parents:
0a981e3 (diff), c170438 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge async framework changes

Location:
uspace
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/i8042/main.c

    r0a981e3 r2a7ba5e  
    4343#include <ddf/log.h>
    4444#include <stdio.h>
    45 #include <async.h>
    4645#include "i8042.h"
    4746
     
    152151        ddf_log_init(NAME);
    153152       
    154         /*
    155          * Alleviate the virtual memory / page table pressure caused by
    156          * interrupt storms when the default large stacks are used.
    157          */
    158         async_set_notification_handler_stack_size(PAGE_SIZE);
    159 
    160153        return ddf_driver_main(&i8042_driver);
    161154}
  • uspace/lib/c/generic/async.c

    r0a981e3 r2a7ba5e  
    493493}
    494494
    495 static size_t notification_handler_stksz = FIBRIL_DFLT_STK_SIZE;
    496 
    497 /** Set the stack size for the notification handler notification fibrils.
    498  *
    499  * @param size Stack size in bytes.
    500  */
    501 void async_set_notification_handler_stack_size(size_t size)
    502 {
    503         notification_handler_stksz = size;
    504 }
    505 
    506495/** Mutex protecting inactive_exch_list and avail_phone_cv.
    507496 *
     
    998987}
    999988
    1000 /** Notification fibril.
    1001  *
    1002  * When a notification arrives, a fibril with this implementing function is
    1003  * created. It calls the corresponding notification handler and does the final
    1004  * cleanup.
    1005  *
    1006  * @param arg Message structure pointer.
    1007  *
    1008  * @return Always zero.
    1009  *
    1010  */
    1011 static int notification_fibril(void *arg)
    1012 {
    1013         assert(arg);
    1014        
    1015         msg_t *msg = (msg_t *) arg;
     989/** Process notification.
     990 *
     991 * @param callid Hash of the incoming call.
     992 * @param call   Data of the incoming call.
     993 */
     994static void process_notification(ipc_callid_t callid, ipc_call_t *call)
     995{
    1016996        async_notification_handler_t handler = NULL;
    1017997        void *data = NULL;
     998
     999        assert(call);
    10181000       
    10191001        futex_down(&async_futex);
    10201002       
    10211003        ht_link_t *link = hash_table_find(&notification_hash_table,
    1022             &IPC_GET_IMETHOD(msg->call));
     1004            &IPC_GET_IMETHOD(*call));
    10231005        if (link) {
    10241006                notification_t *notification =
     
    10311013       
    10321014        if (handler)
    1033                 handler(msg->callid, &msg->call, data);
    1034        
    1035         free(msg);
    1036         return 0;
    1037 }
    1038 
    1039 /** Process notification.
    1040  *
    1041  * A new fibril is created which would process the notification.
    1042  *
    1043  * @param callid Hash of the incoming call.
    1044  * @param call   Data of the incoming call.
    1045  *
    1046  * @return False if an error occured.
    1047  *         True if the call was passed to the notification fibril.
    1048  *
    1049  */
    1050 static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
    1051 {
    1052         assert(call);
    1053        
    1054         futex_down(&async_futex);
    1055        
    1056         msg_t *msg = malloc(sizeof(*msg));
    1057         if (!msg) {
    1058                 futex_up(&async_futex);
    1059                 return false;
    1060         }
    1061        
    1062         msg->callid = callid;
    1063         msg->call = *call;
    1064        
    1065         fid_t fid = fibril_create_generic(notification_fibril, msg,
    1066             notification_handler_stksz);
    1067         if (fid == 0) {
    1068                 free(msg);
    1069                 futex_up(&async_futex);
    1070                 return false;
    1071         }
    1072        
    1073         fibril_add_ready(fid);
    1074        
    1075         futex_up(&async_futex);
    1076         return true;
     1015                handler(callid, call, data);
    10771016}
    10781017
     
    13751314        /* Kernel notification */
    13761315        if ((callid & IPC_CALLID_NOTIFICATION)) {
     1316                fibril_t *fibril = (fibril_t *) __tcb_get()->fibril_data;
     1317                unsigned oldsw = fibril->switches;
     1318
    13771319                process_notification(callid, call);
     1320
     1321                if (oldsw != fibril->switches) {
     1322                        /*
     1323                         * The notification handler did not execute atomically
     1324                         * and so the current manager fibril assumed the role of
     1325                         * a notification fibril. While waiting for its
     1326                         * resources, it switched to another manager fibril that
     1327                         * had already existed or it created a new one. We
     1328                         * therefore know there is at least yet another
     1329                         * manager fibril that can take over. We now kill the
     1330                         * current 'notification' fibril to prevent fibril
     1331                         * population explosion.
     1332                         */
     1333                        futex_down(&async_futex);
     1334                        fibril_switch(FIBRIL_FROM_DEAD);
     1335                }
    13781336                return;
    13791337        }
     
    15501508void async_create_manager(void)
    15511509{
    1552         fid_t fid = fibril_create(async_manager_fibril, NULL);
     1510        fid_t fid = fibril_create_generic(async_manager_fibril, NULL, PAGE_SIZE);
    15531511        if (fid != 0)
    15541512                fibril_add_manager(fid);
     
    16741632       
    16751633        ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
    1676             reply_received, true);
     1634            reply_received);
    16771635       
    16781636        return (aid_t) msg;
     
    17121670       
    17131671        ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
    1714             msg, reply_received, true);
     1672            msg, reply_received);
    17151673       
    17161674        return (aid_t) msg;
     
    20011959{
    20021960        if (exch != NULL)
    2003                 ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
     1961                ipc_call_async_0(exch->phone, imethod, NULL, NULL);
    20041962}
    20051963
     
    20071965{
    20081966        if (exch != NULL)
    2009                 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
     1967                ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL);
    20101968}
    20111969
     
    20141972{
    20151973        if (exch != NULL)
    2016                 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
    2017                     true);
     1974                ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL);
    20181975}
    20191976
     
    20231980        if (exch != NULL)
    20241981                ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
    2025                     NULL, true);
     1982                    NULL);
    20261983}
    20271984
     
    20311988        if (exch != NULL)
    20321989                ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
    2033                     NULL, NULL, true);
     1990                    NULL, NULL);
    20341991}
    20351992
     
    20391996        if (exch != NULL)
    20401997                ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
    2041                     arg5, NULL, NULL, true);
     1998                    arg5, NULL, NULL);
    20421999}
    20432000
     
    21622119       
    21632120        ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
    2164             reply_received, true);
     2121            reply_received);
    21652122       
    21662123        sysarg_t rc;
     
    22112168       
    22122169        ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
    2213             msg, reply_received, true);
     2170            msg, reply_received);
    22142171       
    22152172        sysarg_t rc;
  • uspace/lib/c/generic/fibril.c

    r0a981e3 r2a7ba5e  
    113113       
    114114        fibril->waits_for = NULL;
     115
     116        fibril->switches = 0;
    115117
    116118        /*
     
    216218                        assert(stype == FIBRIL_TO_MANAGER);
    217219
     220                        srcf->switches++;
     221
    218222                        /*
    219223                         * Don't put the current fibril into any list, it should
  • uspace/lib/c/generic/ipc.c

    r0a981e3 r2a7ba5e  
    9696}
    9797
    98 /** Prolog for ipc_call_async_*() functions.
     98/** Prologue for ipc_call_async_*() functions.
    9999 *
    100100 * @param private  Argument for the answer/error callback.
     
    122122}
    123123
    124 /** Epilog for ipc_call_async_*() functions.
     124/** Epilogue for ipc_call_async_*() functions.
    125125 *
    126126 * @param callid      Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
    127127 * @param phoneid     Phone handle through which the call was made.
    128128 * @param call        Structure returned by ipc_prepare_async().
    129  * @param can_preempt If true, the current fibril can be preempted
    130  *                    in this call.
    131  *
    132129 */
    133130static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    134     async_call_t *call, bool can_preempt)
     131    async_call_t *call)
    135132{
    136133        if (!call) {
     
    159156                list_append(&call->list, &queued_calls);
    160157               
    161                 if (can_preempt) {
    162                         call->fid = fibril_get_id();
    163                         fibril_switch(FIBRIL_TO_MANAGER);
    164                         /* Async futex unlocked by previous call */
    165                 } else {
    166                         call->fid = 0;
    167                         futex_up(&async_futex);
    168                 }
     158                call->fid = fibril_get_id();
     159                fibril_switch(FIBRIL_TO_MANAGER);
     160                /* Async futex unlocked by previous call */
    169161               
    170162                return;
     
    197189 * @param private     Argument to be passed to the answer/error callback.
    198190 * @param callback    Answer or error callback.
    199  * @param can_preempt If true, the current fibril will be preempted in
    200  *                    case the kernel temporarily refuses to accept more
    201  *                    asynchronous calls.
    202  *
    203191 */
    204192void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
    205193    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
    206     ipc_async_callback_t callback, bool can_preempt)
     194    ipc_async_callback_t callback)
    207195{
    208196        async_call_t *call = NULL;
     
    246234        }
    247235       
    248         ipc_finish_async(callid, phoneid, call, can_preempt);
     236        ipc_finish_async(callid, phoneid, call);
    249237}
    250238
     
    266254 * @param private     Argument to be passed to the answer/error callback.
    267255 * @param callback    Answer or error callback.
    268  * @param can_preempt If true, the current fibril will be preempted in
    269  *                    case the kernel temporarily refuses to accept more
    270  *                    asynchronous calls.
    271  *
    272256 */
    273257void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    274258    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
    275     ipc_async_callback_t callback, bool can_preempt)
     259    ipc_async_callback_t callback)
    276260{
    277261        async_call_t *call = ipc_prepare_async(private, callback);
     
    295279            ipc_call_async_internal(phoneid, &call->u.msg.data);
    296280       
    297         ipc_finish_async(callid, phoneid, call, can_preempt);
     281        ipc_finish_async(callid, phoneid, call);
    298282}
    299283
     
    375359                futex_up(&async_futex);
    376360               
    377                 if (call->fid)
    378                         fibril_add_ready(call->fid);
     361                assert(call->fid);
     362                fibril_add_ready(call->fid);
    379363               
    380364                if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
  • uspace/lib/c/include/async.h

    r0a981e3 r2a7ba5e  
    165165extern int async_create_callback_port(async_exch_t *, iface_t, sysarg_t,
    166166    sysarg_t, async_port_handler_t, void *, port_id_t *);
    167 
    168 extern void async_set_notification_handler_stack_size(size_t);
    169167
    170168extern int async_irq_subscribe(int, int, async_notification_handler_t, void *,
  • uspace/lib/c/include/fibril.h

    r0a981e3 r2a7ba5e  
    7878       
    7979        fibril_owner_info_t *waits_for;
     80
     81        unsigned switches;
    8082} fibril_t;
    8183
  • uspace/lib/c/include/ipc/ipc.h

    r0a981e3 r2a7ba5e  
    8989 */
    9090
    91 #define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \
     91#define ipc_call_async_0(phoneid, method, private, callback) \
    9292        ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \
    93             (callback), (can_preempt))
    94 #define ipc_call_async_1(phoneid, method, arg1, private, callback, \
    95     can_preempt) \
     93            (callback))
     94#define ipc_call_async_1(phoneid, method, arg1, private, callback) \
    9695        ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, 0, (private), \
    97             (callback), (can_preempt))
    98 #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback, \
    99     can_preempt) \
     96            (callback))
     97#define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback) \
    10098        ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
    101             (private), (callback), (can_preempt))
    102 #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback, \
    103     can_preempt) \
     99            (private), (callback))
     100#define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback) \
    104101        ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
    105             (private), (callback), (can_preempt))
     102            (private), (callback))
    106103#define ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, private, \
    107     callback, can_preempt) \
     104    callback) \
    108105        ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    109             (arg4), (private), (callback), (can_preempt))
     106            (arg4), (private), (callback))
    110107#define ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, \
    111     private, callback, can_preempt) \
     108    private, callback) \
    112109        ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    113             (arg4), (arg5), (private), (callback), (can_preempt))
     110            (arg4), (arg5), (private), (callback))
    114111
    115112extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    116     sysarg_t, void *, ipc_async_callback_t, bool);
     113    sysarg_t, void *, ipc_async_callback_t);
    117114extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    118     sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
     115    sysarg_t, sysarg_t, void *, ipc_async_callback_t);
    119116
    120117extern int ipc_hangup(int);
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    r0a981e3 r2a7ba5e  
    4747#include <errno.h>
    4848#include <ipc/adb.h>
    49 #include <async.h>
    5049#include <assert.h>
    5150#include "cuda_adb.h"
     
    158157        printf(NAME ": VIA-CUDA Apple Desktop Bus driver\n");
    159158       
    160         /*
    161          * Alleviate the virtual memory / page table pressure caused by
    162          * interrupt storms when the default large stacks are used.
    163          */
    164         async_set_notification_handler_stack_size(PAGE_SIZE);
    165 
    166159        for (i = 0; i < ADB_MAX_ADDR; ++i) {
    167160                adb_dev[i].client_sess = NULL;
Note: See TracChangeset for help on using the changeset viewer.