Changeset 6c34f587 in mainline for kernel/generic/src/ipc


Ignore:
Timestamp:
2012-08-12T18:57:22Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d7978525
Parents:
49505fe
Message:

Remove synchronous IPC primitives.

Location:
kernel/generic/src/ipc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/ipc.c

    r49505fe r6c34f587  
    120120        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    121121        waitq_initialize(&box->wq);
    122         link_initialize(&box->sync_box_link);
    123122        list_initialize(&box->connected_phones);
    124123        list_initialize(&box->calls);
     
    161160        phone->state = IPC_PHONE_FREE;
    162161        atomic_set(&phone->active_calls, 0);
    163 }
    164 
    165 /** Helper function to facilitate synchronous calls.
    166  *
    167  * @param phone   Destination kernel phone structure.
    168  * @param request Call structure with request.
    169  *
    170  * @return EOK on success or EINTR if the sleep was interrupted.
    171  *
    172  */
    173 int ipc_call_sync(phone_t *phone, call_t *request)
    174 {
    175         answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
    176         ipc_answerbox_init(sync_box, TASK);
    177        
    178         /*
    179          * Put the answerbox on the TASK's list of synchronous answerboxes so
    180          * that it can be cleaned up if the call is interrupted.
    181          */
    182         irq_spinlock_lock(&TASK->lock, true);
    183         list_append(&sync_box->sync_box_link, &TASK->sync_boxes);
    184         irq_spinlock_unlock(&TASK->lock, true);
    185        
    186         /* We will receive data in a special box. */
    187         request->callerbox = sync_box;
    188        
    189         ipc_call(phone, request);
    190         if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    191             SYNCH_FLAGS_INTERRUPTIBLE)) {
    192                 /* The answerbox and the call will be freed by ipc_cleanup(). */
    193                 return EINTR;
    194         }
    195        
    196         /*
    197          * The answer arrived without interruption so we can remove the
    198          * answerbox from the TASK's list of synchronous answerboxes.
    199          */
    200         irq_spinlock_lock(&TASK->lock, true);
    201         list_remove(&sync_box->sync_box_link);
    202         irq_spinlock_unlock(&TASK->lock, true);
    203        
    204         slab_free(ipc_answerbox_slab, sync_box);
    205         return EOK;
    206162}
    207163
     
    606562        ipc_cleanup_call_list(&TASK->answerbox.calls);
    607563        irq_spinlock_unlock(&TASK->answerbox.lock, true);
    608        
    609         /* Wait for all answers to interrupted synchronous calls to arrive */
    610         ipl_t ipl = interrupts_disable();
    611         while (!list_empty(&TASK->sync_boxes)) {
    612                 answerbox_t *box = list_get_instance(
    613                     list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);
    614                
    615                 list_remove(&box->sync_box_link);
    616                 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    617                     SYNCH_FLAGS_NONE);
    618                 ipc_call_free(call);
    619                 slab_free(ipc_answerbox_slab, box);
    620         }
    621         interrupts_restore(ipl);
    622564       
    623565        /* Wait for all answers to asynchronous calls to arrive */
  • kernel/generic/src/ipc/sysipc.c

    r49505fe r6c34f587  
    612612                break;
    613613        }
    614        
    615         return 0;
    616 }
    617 
    618 /** Make a fast call over IPC, wait for reply and return to user.
    619  *
    620  * This function can handle only three arguments of payload, but is faster than
    621  * the generic function (i.e. sys_ipc_call_sync_slow()).
    622  *
    623  * @param phoneid Phone handle for the call.
    624  * @param imethod Interface and method of the call.
    625  * @param arg1    Service-defined payload argument.
    626  * @param arg2    Service-defined payload argument.
    627  * @param arg3    Service-defined payload argument.
    628  * @param data    Address of user-space structure where the reply call will
    629  *                be stored.
    630  *
    631  * @return 0 on success.
    632  * @return ENOENT if there is no such phone handle.
    633  *
    634  */
    635 sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod,
    636     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data)
    637 {
    638         phone_t *phone;
    639         if (phone_get(phoneid, &phone) != EOK)
    640                 return ENOENT;
    641        
    642         call_t *call = ipc_call_alloc(0);
    643         IPC_SET_IMETHOD(call->data, imethod);
    644         IPC_SET_ARG1(call->data, arg1);
    645         IPC_SET_ARG2(call->data, arg2);
    646         IPC_SET_ARG3(call->data, arg3);
    647        
    648         /*
    649          * To achieve deterministic behavior, zero out arguments that are beyond
    650          * the limits of the fast version.
    651          */
    652         IPC_SET_ARG4(call->data, 0);
    653         IPC_SET_ARG5(call->data, 0);
    654        
    655         int res = request_preprocess(call, phone);
    656         int rc;
    657        
    658         if (!res) {
    659 #ifdef CONFIG_UDEBUG
    660                 udebug_stoppable_begin();
    661 #endif
    662                 rc = ipc_call_sync(phone, call);
    663 #ifdef CONFIG_UDEBUG
    664                 udebug_stoppable_end();
    665 #endif
    666                
    667                 if (rc != EOK) {
    668                         /* The call will be freed by ipc_cleanup(). */
    669                         return rc;
    670                 }
    671                
    672                 process_answer(call);
    673         } else
    674                 IPC_SET_RETVAL(call->data, res);
    675        
    676         rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
    677         ipc_call_free(call);
    678         if (rc != 0)
    679                 return rc;
    680        
    681         return 0;
    682 }
    683 
    684 /** Make a synchronous IPC call allowing to transmit the entire payload.
    685  *
    686  * @param phoneid Phone handle for the call.
    687  * @param request User-space address of call data with the request.
    688  * @param reply   User-space address of call data where to store the
    689  *                answer.
    690  *
    691  * @return Zero on success or an error code.
    692  *
    693  */
    694 sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request,
    695     ipc_data_t *reply)
    696 {
    697         phone_t *phone;
    698         if (phone_get(phoneid, &phone) != EOK)
    699                 return ENOENT;
    700        
    701         call_t *call = ipc_call_alloc(0);
    702         int rc = copy_from_uspace(&call->data.args, &request->args,
    703             sizeof(call->data.args));
    704         if (rc != 0) {
    705                 ipc_call_free(call);
    706                 return (sysarg_t) rc;
    707         }
    708        
    709         int res = request_preprocess(call, phone);
    710        
    711         if (!res) {
    712 #ifdef CONFIG_UDEBUG
    713                 udebug_stoppable_begin();
    714 #endif
    715                 rc = ipc_call_sync(phone, call);
    716 #ifdef CONFIG_UDEBUG
    717                 udebug_stoppable_end();
    718 #endif
    719                
    720                 if (rc != EOK) {
    721                         /* The call will be freed by ipc_cleanup(). */
    722                         return rc;
    723                 }
    724                
    725                 process_answer(call);
    726         } else
    727                 IPC_SET_RETVAL(call->data, res);
    728        
    729         rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
    730         ipc_call_free(call);
    731         if (rc != 0)
    732                 return rc;
    733614       
    734615        return 0;
Note: See TracChangeset for help on using the changeset viewer.