Changeset 6c34f587 in mainline for kernel/generic/src
- Timestamp:
- 2012-08-12T18:57:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d7978525
- Parents:
- 49505fe
- Location:
- kernel/generic/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
r49505fe r6c34f587 120 120 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 121 121 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link);123 122 list_initialize(&box->connected_phones); 124 123 list_initialize(&box->calls); … … 161 160 phone->state = IPC_PHONE_FREE; 162 161 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 so180 * 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 the198 * 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 162 } 207 163 … … 606 562 ipc_cleanup_call_list(&TASK->answerbox.calls); 607 563 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);622 564 623 565 /* Wait for all answers to asynchronous calls to arrive */ -
kernel/generic/src/ipc/sysipc.c
r49505fe r6c34f587 612 612 break; 613 613 } 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 than621 * 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 will629 * 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 beyond650 * 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_UDEBUG660 udebug_stoppable_begin();661 #endif662 rc = ipc_call_sync(phone, call);663 #ifdef CONFIG_UDEBUG664 udebug_stoppable_end();665 #endif666 667 if (rc != EOK) {668 /* The call will be freed by ipc_cleanup(). */669 return rc;670 }671 672 process_answer(call);673 } else674 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 the689 * 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_UDEBUG713 udebug_stoppable_begin();714 #endif715 rc = ipc_call_sync(phone, call);716 #ifdef CONFIG_UDEBUG717 udebug_stoppable_end();718 #endif719 720 if (rc != EOK) {721 /* The call will be freed by ipc_cleanup(). */722 return rc;723 }724 725 process_answer(call);726 } else727 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;733 614 734 615 return 0; -
kernel/generic/src/proc/task.c
r49505fe r6c34f587 156 156 157 157 list_initialize(&task->threads); 158 list_initialize(&task->sync_boxes);159 158 160 159 ipc_answerbox_init(&task->answerbox, task); -
kernel/generic/src/syscall/syscall.c
r49505fe r6c34f587 151 151 152 152 /* IPC related syscalls. */ 153 (syshandler_t) sys_ipc_call_sync_fast,154 (syshandler_t) sys_ipc_call_sync_slow,155 153 (syshandler_t) sys_ipc_call_async_fast, 156 154 (syshandler_t) sys_ipc_call_async_slow,
Note:
See TracChangeset
for help on using the changeset viewer.