Changeset 7cfe5c0 in mainline for kernel


Ignore:
Timestamp:
2012-08-20T19:16:24Z (13 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6b99156
Parents:
b9cb911 (diff), 01e397ac (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:

Merged with mainline 0.5.0 changes.

Location:
kernel/generic
Files:
7 edited

Legend:

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

    rb9cb911 r7cfe5c0  
    7777        waitq_t wq;
    7878       
    79         /** Linkage for the list of task's synchronous answerboxes. */
    80         link_t sync_box_link;
    81        
    8279        /** Phones connected to this answerbox. */
    8380        list_t connected_phones;
     
    116113        struct task *sender;
    117114       
    118         /*
    119          * The caller box is different from sender->answerbox
    120          * for synchronous calls.
    121          */
    122         answerbox_t *callerbox;
    123        
    124115        /** Private data to internal IPC. */
    125116        sysarg_t priv;
     
    147138
    148139extern int ipc_call(phone_t *, call_t *);
    149 extern int ipc_call_sync(phone_t *, call_t *);
    150140extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
    151141extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
  • kernel/generic/include/ipc/sysipc.h

    rb9cb911 r7cfe5c0  
    4040#include <typedefs.h>
    4141
    42 extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t,
    43     sysarg_t, sysarg_t, ipc_data_t *);
    44 extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *);
    4542extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
    4643    sysarg_t, sysarg_t, sysarg_t);
  • kernel/generic/include/proc/task.h

    rb9cb911 r7cfe5c0  
    9898        phone_t phones[IPC_MAX_PHONES];
    9999        stats_ipc_t ipc_info;   /**< IPC statistics */
    100         list_t sync_boxes;      /**< List of synchronous answerboxes. */
    101100        event_t events[EVENT_TASK_END - EVENT_END];
    102101       
  • kernel/generic/src/ipc/ipc.c

    rb9cb911 r7cfe5c0  
    7171{
    7272        memsetb(call, sizeof(*call), 0);
    73         call->callerbox = &TASK->answerbox;
    7473        call->sender = TASK;
    7574        call->buffer = NULL;
     
    120119        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    121120        waitq_initialize(&box->wq);
    122         link_initialize(&box->sync_box_link);
    123121        list_initialize(&box->connected_phones);
    124122        list_initialize(&box->calls);
     
    163161}
    164162
    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;
    206 }
    207 
    208163/** Answer a message which was not dispatched and is not listed in any queue.
    209164 *
     
    214169static void _ipc_answer_free_call(call_t *call, bool selflocked)
    215170{
    216         answerbox_t *callerbox = call->callerbox;
     171        answerbox_t *callerbox = &call->sender->answerbox;
    217172        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    218173       
     
    606561        ipc_cleanup_call_list(&TASK->answerbox.calls);
    607562        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);
    622563       
    623564        /* Wait for all answers to asynchronous calls to arrive */
  • kernel/generic/src/ipc/sysipc.c

    rb9cb911 r7cfe5c0  
    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;
  • kernel/generic/src/proc/task.c

    rb9cb911 r7cfe5c0  
    156156       
    157157        list_initialize(&task->threads);
    158         list_initialize(&task->sync_boxes);
    159158       
    160159        ipc_answerbox_init(&task->answerbox, task);
  • kernel/generic/src/syscall/syscall.c

    rb9cb911 r7cfe5c0  
    151151       
    152152        /* IPC related syscalls. */
    153         (syshandler_t) sys_ipc_call_sync_fast,
    154         (syshandler_t) sys_ipc_call_sync_slow,
    155153        (syshandler_t) sys_ipc_call_async_fast,
    156154        (syshandler_t) sys_ipc_call_async_slow,
Note: See TracChangeset for help on using the changeset viewer.