Changes in / [de9460e:4e739652] in mainline
- Location:
- kernel/generic
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
rde9460e r4e739652 51 51 /** This is answer to a call */ 52 52 #define IPC_CALL_ANSWERED (1 << 0) 53 /** This call will not be freed on error */ 54 #define IPC_CALL_STATIC_ALLOC (1 << 1) 53 55 /** 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) 55 57 /** Call was forwarded */ 56 #define IPC_CALL_FORWARDED (1 << 2)58 #define IPC_CALL_FORWARDED (1 << 3) 57 59 /** Identify connect_me_to answer */ 58 #define IPC_CALL_CONN_ME_TO (1 << 3)60 #define IPC_CALL_CONN_ME_TO (1 << 4) 59 61 /** Interrupt notification */ 60 #define IPC_CALL_NOTIF (1 << 4)62 #define IPC_CALL_NOTIF (1 << 5) 61 63 62 64 /* … … 265 267 waitq_t wq; 266 268 267 /** Linkage for the list of task's synchronous answerboxes. */268 link_t sync_box_link;269 270 269 /** Phones connected to this answerbox. */ 271 270 link_t connected_phones; … … 317 316 } call_t; 318 317 319 320 extern answerbox_t *ipc_phone_0;321 322 323 318 extern void ipc_init(void); 324 325 extern call_t * ipc_call_alloc(int); 326 extern void ipc_call_free(call_t *); 327 319 extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int); 320 extern void ipc_answer(answerbox_t *, call_t *); 328 321 extern int ipc_call(phone_t *, call_t *); 329 322 extern 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 334 323 extern void ipc_phone_init(phone_t *); 335 324 extern void ipc_phone_connect(phone_t *, answerbox_t *); 325 extern void ipc_call_free(call_t *); 326 extern call_t * ipc_call_alloc(int); 327 extern void ipc_answerbox_init(answerbox_t *, struct task *); 328 extern void ipc_call_static_init(call_t *); 329 extern void task_print_list(void); 330 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int); 331 extern void ipc_cleanup(void); 336 332 extern int ipc_phone_hangup(phone_t *); 337 338 extern void ipc_answerbox_init(answerbox_t *, struct task *);339 340 extern void ipc_cleanup(void);341 333 extern void ipc_backsend_err(phone_t *, call_t *, unative_t); 334 extern void ipc_print_task(task_id_t); 342 335 extern void ipc_answerbox_slam_phones(answerbox_t *, bool); 343 336 extern void ipc_cleanup_call_list(link_t *); 344 337 345 extern void ipc_print_task(task_id_t);338 extern answerbox_t *ipc_phone_0; 346 339 347 340 #endif -
kernel/generic/include/proc/task.h
rde9460e r4e739652 98 98 */ 99 99 atomic_t active_calls; 100 /** List of synchronous answerboxes. */101 link_t sync_box_head;102 100 103 101 #ifdef CONFIG_UDEBUG … … 134 132 extern int task_kill(task_id_t id); 135 133 extern uint64_t task_get_accounting(task_t *t); 136 extern void task_print_list(void);137 134 138 135 extern void cap_set(task_t *t, cap_t caps); -
kernel/generic/src/ipc/ipc.c
rde9460e r4e739652 62 62 63 63 static slab_cache_t *ipc_call_slab; 64 static slab_cache_t *ipc_answerbox_slab;65 64 66 65 /** Initialize a call structure. … … 97 96 } 98 97 98 /** Initialize a statically allocated call structure. 99 * 100 * @param call Statically allocated kernel call structure to be 101 * initialized. 102 */ 103 void ipc_call_static_init(call_t *call) 104 { 105 _ipc_call_init(call); 106 call->flags |= IPC_CALL_STATIC_ALLOC; 107 } 108 99 109 /** Deallocate a call structure. 100 110 * … … 103 113 void ipc_call_free(call_t *call) 104 114 { 115 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); 105 116 /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */ 106 117 if (call->buffer) … … 119 130 spinlock_initialize(&box->irq_lock, "ipc_box_irqlock"); 120 131 waitq_initialize(&box->wq); 121 link_initialize(&box->sync_box_link);122 132 list_initialize(&box->connected_phones); 123 133 list_initialize(&box->calls); … … 169 179 int ipc_call_sync(phone_t *phone, call_t *request) 170 180 { 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); 186 184 187 185 /* We will receive data in a special box. */ 188 request->callerbox = sync_box;186 request->callerbox = &sync_box; 189 187 190 188 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)) 194 191 return EINTR; 195 }196 197 /*198 * The answer arrived without interruption so we can remove the199 * 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);208 192 return EOK; 209 193 } … … 536 520 int i; 537 521 call_t *call; 538 ipl_t ipl;539 522 540 523 /* Disconnect all our phones ('ipc_phone_hangup') */ … … 562 545 spinlock_unlock(&TASK->answerbox.lock); 563 546 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 */ 579 548 while (1) { 580 549 /* Go through all phones, until all are FREE... */ … … 605 574 ASSERT((call->flags & IPC_CALL_ANSWERED) || 606 575 (call->flags & IPC_CALL_NOTIF)); 576 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); 607 577 608 578 /* … … 623 593 ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL, 624 594 NULL, 0); 625 ipc_answerbox_slab = slab_cache_create("ipc_answerbox",626 sizeof(answerbox_t), 0, NULL, NULL, 0);627 595 } 628 596 -
kernel/generic/src/ipc/sysipc.c
rde9460e r4e739652 531 531 unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data) 532 532 { 533 call_t *call;533 call_t call; 534 534 phone_t *phone; 535 535 int res; … … 538 538 GET_CHECK_PHONE(phone, phoneid, return ENOENT); 539 539 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); 545 545 /* 546 546 * To achieve deterministic behavior, zero out arguments that are beyond 547 547 * the limits of the fast version. 548 548 */ 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))) { 553 553 #ifdef CONFIG_UDEBUG 554 554 udebug_stoppable_begin(); 555 555 #endif 556 rc = ipc_call_sync(phone, call);556 rc = ipc_call_sync(phone, &call); 557 557 #ifdef CONFIG_UDEBUG 558 558 udebug_stoppable_end(); 559 559 #endif 560 if (rc != EOK) { 561 /* The call will be freed by ipc_cleanup(). */ 560 if (rc != EOK) 562 561 return rc; 563 } 564 process_answer(call); 562 process_answer(&call); 565 563 566 564 } 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); 571 568 if (rc != 0) 572 569 return rc; … … 587 584 ipc_data_t *reply) 588 585 { 589 call_t *call;586 call_t call; 590 587 phone_t *phone; 591 588 int res; 592 589 int rc; 593 590 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 594 597 GET_CHECK_PHONE(phone, phoneid, return ENOENT); 595 598 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))) { 606 600 #ifdef CONFIG_UDEBUG 607 601 udebug_stoppable_begin(); 608 602 #endif 609 rc = ipc_call_sync(phone, call);603 rc = ipc_call_sync(phone, &call); 610 604 #ifdef CONFIG_UDEBUG 611 605 udebug_stoppable_end(); 612 606 #endif 613 if (rc != EOK) { 614 /* The call will be freed by ipc_cleanup(). */ 607 if (rc != EOK) 615 608 return rc; 616 } 617 process_answer(call); 609 process_answer(&call); 618 610 } 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); 623 614 if (rc != 0) 624 615 return rc; … … 1000 991 1001 992 if (call->flags & IPC_CALL_NOTIF) { 993 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); 994 1002 995 /* Set in_phone_hash to the interrupt counter */ 1003 996 call->data.phone = (void *) call->priv; … … 1012 1005 if (call->flags & IPC_CALL_ANSWERED) { 1013 1006 process_answer(call); 1007 1008 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); 1014 1009 1015 1010 if (call->flags & IPC_CALL_DISCARD_ANSWER) { -
kernel/generic/src/proc/task.c
rde9460e r4e739652 178 178 ipc_phone_connect(&ta->phones[0], ipc_phone_0); 179 179 atomic_set(&ta->active_calls, 0); 180 list_initialize(&ta->sync_box_head);181 180 182 181 mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
Note:
See TracChangeset
for help on using the changeset viewer.