Changes in / [de9460e:4e739652] in mainline


Ignore:
Location:
kernel/generic
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    rde9460e r4e739652  
    5151/** This is answer to a call */
    5252#define IPC_CALL_ANSWERED       (1 << 0)
     53/** This call will not be freed on error */
     54#define IPC_CALL_STATIC_ALLOC   (1 << 1)
    5355/** Answer will not be passed to userspace, will be discarded */
    54 #define IPC_CALL_DISCARD_ANSWER (1 << 1)
     56#define IPC_CALL_DISCARD_ANSWER (1 << 2)
    5557/** Call was forwarded */
    56 #define IPC_CALL_FORWARDED      (1 << 2)
     58#define IPC_CALL_FORWARDED      (1 << 3)
    5759/** Identify connect_me_to answer */
    58 #define IPC_CALL_CONN_ME_TO     (1 << 3)
     60#define IPC_CALL_CONN_ME_TO     (1 << 4)
    5961/** Interrupt notification */
    60 #define IPC_CALL_NOTIF          (1 << 4)
     62#define IPC_CALL_NOTIF          (1 << 5)
    6163
    6264/*
     
    265267        waitq_t wq;
    266268
    267         /** Linkage for the list of task's synchronous answerboxes. */
    268         link_t sync_box_link;
    269 
    270269        /** Phones connected to this answerbox. */
    271270        link_t connected_phones;
     
    317316} call_t;
    318317
    319 
    320 extern answerbox_t *ipc_phone_0;
    321 
    322 
    323318extern void ipc_init(void);
    324 
    325 extern call_t * ipc_call_alloc(int);
    326 extern void ipc_call_free(call_t *);
    327 
     319extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
     320extern void ipc_answer(answerbox_t *, call_t *);
    328321extern int ipc_call(phone_t *, call_t *);
    329322extern int ipc_call_sync(phone_t *, call_t *);
    330 extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
    331 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
    332 extern void ipc_answer(answerbox_t *, call_t *);
    333 
    334323extern void ipc_phone_init(phone_t *);
    335324extern void ipc_phone_connect(phone_t *, answerbox_t *);
     325extern void ipc_call_free(call_t *);
     326extern call_t * ipc_call_alloc(int);
     327extern void ipc_answerbox_init(answerbox_t *, struct task *);
     328extern void ipc_call_static_init(call_t *);
     329extern void task_print_list(void);
     330extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
     331extern void ipc_cleanup(void);
    336332extern int ipc_phone_hangup(phone_t *);
    337 
    338 extern void ipc_answerbox_init(answerbox_t *, struct task *);
    339 
    340 extern void ipc_cleanup(void);
    341333extern void ipc_backsend_err(phone_t *, call_t *, unative_t);
     334extern void ipc_print_task(task_id_t);
    342335extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
    343336extern void ipc_cleanup_call_list(link_t *);
    344337
    345 extern void ipc_print_task(task_id_t);
     338extern answerbox_t *ipc_phone_0;
    346339
    347340#endif
  • kernel/generic/include/proc/task.h

    rde9460e r4e739652  
    9898         */
    9999        atomic_t active_calls;
    100         /** List of synchronous answerboxes. */
    101         link_t sync_box_head;
    102100
    103101#ifdef CONFIG_UDEBUG
     
    134132extern int task_kill(task_id_t id);
    135133extern uint64_t task_get_accounting(task_t *t);
    136 extern void task_print_list(void);
    137134
    138135extern void cap_set(task_t *t, cap_t caps);
  • kernel/generic/src/ipc/ipc.c

    rde9460e r4e739652  
    6262
    6363static slab_cache_t *ipc_call_slab;
    64 static slab_cache_t *ipc_answerbox_slab;
    6564
    6665/** Initialize a call structure.
     
    9796}
    9897
     98/** Initialize a statically allocated call structure.
     99 *
     100 * @param call          Statically allocated kernel call structure to be
     101 *                      initialized.
     102 */
     103void ipc_call_static_init(call_t *call)
     104{
     105        _ipc_call_init(call);
     106        call->flags |= IPC_CALL_STATIC_ALLOC;
     107}
     108
    99109/** Deallocate a call structure.
    100110 *
     
    103113void ipc_call_free(call_t *call)
    104114{
     115        ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
    105116        /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
    106117        if (call->buffer)
     
    119130        spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
    120131        waitq_initialize(&box->wq);
    121         link_initialize(&box->sync_box_link);
    122132        list_initialize(&box->connected_phones);
    123133        list_initialize(&box->calls);
     
    169179int ipc_call_sync(phone_t *phone, call_t *request)
    170180{
    171         answerbox_t *sync_box;
    172         ipl_t ipl;
    173 
    174         sync_box = slab_alloc(ipc_answerbox_slab, 0);
    175         ipc_answerbox_init(sync_box, TASK);
    176 
    177         /*
    178          * Put the answerbox on the TASK's list of synchronous answerboxes so
    179          * that it can be cleaned up if the call is interrupted.
    180          */
    181         ipl = interrupts_disable();
    182         spinlock_lock(&TASK->lock);
    183         list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
    184         spinlock_unlock(&TASK->lock);
    185         interrupts_restore(ipl);
     181        answerbox_t sync_box;
     182
     183        ipc_answerbox_init(&sync_box, TASK);
    186184
    187185        /* We will receive data in a special box. */
    188         request->callerbox = sync_box;
     186        request->callerbox = &sync_box;
    189187
    190188        ipc_call(phone, request);
    191         if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    192             SYNCH_FLAGS_INTERRUPTIBLE)) {
    193                 /* The answerbox and the call will be freed by ipc_cleanup(). */
     189        if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
     190            SYNCH_FLAGS_INTERRUPTIBLE))
    194191                return EINTR;
    195         }
    196 
    197         /*
    198          * The answer arrived without interruption so we can remove the
    199          * answerbox from the TASK's list of synchronous answerboxes.
    200          */
    201         (void) interrupts_disable();
    202         spinlock_lock(&TASK->lock);
    203         list_remove(&sync_box->sync_box_link);
    204         spinlock_unlock(&TASK->lock);
    205         interrupts_restore(ipl);
    206 
    207         slab_free(ipc_answerbox_slab, sync_box);
    208192        return EOK;
    209193}
     
    536520        int i;
    537521        call_t *call;
    538         ipl_t ipl;
    539522
    540523        /* Disconnect all our phones ('ipc_phone_hangup') */
     
    562545        spinlock_unlock(&TASK->answerbox.lock);
    563546       
    564         /* Wait for all answers to interrupted synchronous calls to arrive */
    565         ipl = interrupts_disable();
    566         while (!list_empty(&TASK->sync_box_head)) {
    567                 answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
    568                     answerbox_t, sync_box_link);
    569 
    570                 list_remove(&box->sync_box_link);
    571                 call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    572                     SYNCH_FLAGS_NONE);
    573                 ipc_call_free(call);
    574                 slab_free(ipc_answerbox_slab, box);
    575         }
    576         interrupts_restore(ipl);
    577 
    578         /* Wait for all answers to asynchronous calls to arrive */
     547        /* Wait for all async answers to arrive */
    579548        while (1) {
    580549                /* Go through all phones, until all are FREE... */
     
    605574                ASSERT((call->flags & IPC_CALL_ANSWERED) ||
    606575                    (call->flags & IPC_CALL_NOTIF));
     576                ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
    607577               
    608578                /*
     
    623593        ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
    624594            NULL, 0);
    625         ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
    626             sizeof(answerbox_t), 0, NULL, NULL, 0);
    627595}
    628596
  • kernel/generic/src/ipc/sysipc.c

    rde9460e r4e739652  
    531531    unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data)
    532532{
    533         call_t *call;
     533        call_t call;
    534534        phone_t *phone;
    535535        int res;
     
    538538        GET_CHECK_PHONE(phone, phoneid, return ENOENT);
    539539
    540         call = ipc_call_alloc(0);
    541         IPC_SET_METHOD(call->data, method);
    542         IPC_SET_ARG1(call->data, arg1);
    543         IPC_SET_ARG2(call->data, arg2);
    544         IPC_SET_ARG3(call->data, arg3);
     540        ipc_call_static_init(&call);
     541        IPC_SET_METHOD(call.data, method);
     542        IPC_SET_ARG1(call.data, arg1);
     543        IPC_SET_ARG2(call.data, arg2);
     544        IPC_SET_ARG3(call.data, arg3);
    545545        /*
    546546         * To achieve deterministic behavior, zero out arguments that are beyond
    547547         * the limits of the fast version.
    548548         */
    549         IPC_SET_ARG4(call->data, 0);
    550         IPC_SET_ARG5(call->data, 0);
    551 
    552         if (!(res = request_preprocess(call, phone))) {
     549        IPC_SET_ARG4(call.data, 0);
     550        IPC_SET_ARG5(call.data, 0);
     551
     552        if (!(res = request_preprocess(&call, phone))) {
    553553#ifdef CONFIG_UDEBUG
    554554                udebug_stoppable_begin();
    555555#endif
    556                 rc = ipc_call_sync(phone, call);
     556                rc = ipc_call_sync(phone, &call);
    557557#ifdef CONFIG_UDEBUG
    558558                udebug_stoppable_end();
    559559#endif
    560                 if (rc != EOK) {
    561                         /* The call will be freed by ipc_cleanup(). */
     560                if (rc != EOK)
    562561                        return rc;
    563                 }
    564                 process_answer(call);
     562                process_answer(&call);
    565563
    566564        } else {
    567                 IPC_SET_RETVAL(call->data, res);
    568         }
    569         rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
    570         ipc_call_free(call);
     565                IPC_SET_RETVAL(call.data, res);
     566        }
     567        rc = STRUCT_TO_USPACE(&data->args, &call.data.args);
    571568        if (rc != 0)
    572569                return rc;
     
    587584    ipc_data_t *reply)
    588585{
    589         call_t *call;
     586        call_t call;
    590587        phone_t *phone;
    591588        int res;
    592589        int rc;
    593590
     591        ipc_call_static_init(&call);
     592        rc = copy_from_uspace(&call.data.args, &question->args,
     593            sizeof(call.data.args));
     594        if (rc != 0)
     595                return (unative_t) rc;
     596
    594597        GET_CHECK_PHONE(phone, phoneid, return ENOENT);
    595598
    596         call = ipc_call_alloc(0);
    597         rc = copy_from_uspace(&call->data.args, &question->args,
    598             sizeof(call->data.args));
    599         if (rc != 0) {
    600                 ipc_call_free(call);
    601                 return (unative_t) rc;
    602         }
    603 
    604 
    605         if (!(res = request_preprocess(call, phone))) {
     599        if (!(res = request_preprocess(&call, phone))) {
    606600#ifdef CONFIG_UDEBUG
    607601                udebug_stoppable_begin();
    608602#endif
    609                 rc = ipc_call_sync(phone, call);
     603                rc = ipc_call_sync(phone, &call);
    610604#ifdef CONFIG_UDEBUG
    611605                udebug_stoppable_end();
    612606#endif
    613                 if (rc != EOK) {
    614                         /* The call will be freed by ipc_cleanup(). */
     607                if (rc != EOK)
    615608                        return rc;
    616                 }
    617                 process_answer(call);
     609                process_answer(&call);
    618610        } else
    619                 IPC_SET_RETVAL(call->data, res);
    620 
    621         rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
    622         ipc_call_free(call);
     611                IPC_SET_RETVAL(call.data, res);
     612
     613        rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
    623614        if (rc != 0)
    624615                return rc;
     
    1000991
    1001992        if (call->flags & IPC_CALL_NOTIF) {
     993                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
     994
    1002995                /* Set in_phone_hash to the interrupt counter */
    1003996                call->data.phone = (void *) call->priv;
     
    10121005        if (call->flags & IPC_CALL_ANSWERED) {
    10131006                process_answer(call);
     1007
     1008                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
    10141009
    10151010                if (call->flags & IPC_CALL_DISCARD_ANSWER) {
  • kernel/generic/src/proc/task.c

    rde9460e r4e739652  
    178178                ipc_phone_connect(&ta->phones[0], ipc_phone_0);
    179179        atomic_set(&ta->active_calls, 0);
    180         list_initialize(&ta->sync_box_head);
    181180
    182181        mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
Note: See TracChangeset for help on using the changeset viewer.