Changes in kernel/generic/src/ipc/ipc.c [e701eb1:287e83f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
re701eb1 r287e83f 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... */ … … 583 552 for (i = 0; i < IPC_MAX_PHONES; i++) { 584 553 if (TASK->phones[i].state == IPC_PHONE_HUNGUP && 585 atomic_get(&TASK->phones[i].active_calls) == 0) {554 atomic_get(&TASK->phones[i].active_calls) == 0) 586 555 TASK->phones[i].state = IPC_PHONE_FREE; 587 TASK->phones[i].callee = NULL;588 }589 556 590 557 /* Just for sure, we might have had some … … 607 574 ASSERT((call->flags & IPC_CALL_ANSWERED) || 608 575 (call->flags & IPC_CALL_NOTIF)); 576 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); 609 577 610 578 /* … … 625 593 ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL, 626 594 NULL, 0); 627 ipc_answerbox_slab = slab_cache_create("ipc_answerbox",628 sizeof(answerbox_t), 0, NULL, NULL, 0);629 595 } 630 596
Note:
See TracChangeset
for help on using the changeset viewer.