Changeset 3f35634c in mainline for kernel/generic/src
- Timestamp:
- 2009-11-28T20:28:13Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- eb79d60
- Parents:
- 3da11f37 (diff), 2e07d27e (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. - Location:
- kernel/generic/src
- Files:
-
- 5 edited
-
ipc/ipc.c (modified) (10 diffs)
-
ipc/irq.c (modified) (1 diff)
-
ipc/sysipc.c (modified) (11 diffs)
-
lib/elf.c (modified) (2 diffs)
-
proc/task.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
r3da11f37 r3f35634c 62 62 63 63 static slab_cache_t *ipc_call_slab; 64 static slab_cache_t *ipc_answerbox_slab; 64 65 65 66 /** Initialize a call structure. … … 96 97 } 97 98 98 /** Initialize a statically allocated call structure.99 *100 * @param call Statically allocated kernel call structure to be101 * 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 109 99 /** Deallocate a call structure. 110 100 * … … 113 103 void ipc_call_free(call_t *call) 114 104 { 115 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));116 105 /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */ 117 106 if (call->buffer) … … 130 119 spinlock_initialize(&box->irq_lock, "ipc_box_irqlock"); 131 120 waitq_initialize(&box->wq); 121 link_initialize(&box->sync_box_link); 132 122 list_initialize(&box->connected_phones); 133 123 list_initialize(&box->calls); … … 179 169 int ipc_call_sync(phone_t *phone, call_t *request) 180 170 { 181 answerbox_t sync_box; 182 183 ipc_answerbox_init(&sync_box, TASK); 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); 184 186 185 187 /* We will receive data in a special box. */ 186 request->callerbox = &sync_box;188 request->callerbox = sync_box; 187 189 188 190 ipc_call(phone, request); 189 if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, 190 SYNCH_FLAGS_INTERRUPTIBLE)) 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(). */ 191 194 return EINTR; 195 } 196 197 /* 198 * The answer arrived without interruption so we can remove the 199 * 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); 192 208 return EOK; 193 209 } … … 520 536 int i; 521 537 call_t *call; 538 ipl_t ipl; 522 539 523 540 /* Disconnect all our phones ('ipc_phone_hangup') */ … … 545 562 spinlock_unlock(&TASK->answerbox.lock); 546 563 547 /* Wait for all async answers to arrive */ 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 */ 548 579 while (1) { 549 580 /* Go through all phones, until all are FREE... */ … … 552 583 for (i = 0; i < IPC_MAX_PHONES; i++) { 553 584 if (TASK->phones[i].state == IPC_PHONE_HUNGUP && 554 atomic_get(&TASK->phones[i].active_calls) == 0) 585 atomic_get(&TASK->phones[i].active_calls) == 0) { 555 586 TASK->phones[i].state = IPC_PHONE_FREE; 587 TASK->phones[i].callee = NULL; 588 } 556 589 557 590 /* Just for sure, we might have had some … … 574 607 ASSERT((call->flags & IPC_CALL_ANSWERED) || 575 608 (call->flags & IPC_CALL_NOTIF)); 576 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));577 609 578 610 /* … … 593 625 ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL, 594 626 NULL, 0); 627 ipc_answerbox_slab = slab_cache_create("ipc_answerbox", 628 sizeof(answerbox_t), 0, NULL, NULL, 0); 595 629 } 596 630 -
kernel/generic/src/ipc/irq.c
r3da11f37 r3f35634c 418 418 case CMD_ACCEPT: 419 419 return IRQ_ACCEPT; 420 break;421 420 case CMD_DECLINE: 422 421 default: -
kernel/generic/src/ipc/sysipc.c
r3da11f37 r3f35634c 61 61 { \ 62 62 if (phoneid > IPC_MAX_PHONES) { \ 63 err ;\63 err \ 64 64 } \ 65 65 phone = &TASK->phones[phoneid]; \ … … 122 122 case IPC_M_DATA_READ: 123 123 return 1; 124 break;125 124 default: 126 125 return 0; … … 376 375 phone_t *cloned_phone; 377 376 GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data), 378 return ENOENT );377 return ENOENT;); 379 378 phones_lock(cloned_phone, phone); 380 379 if ((cloned_phone->state != IPC_PHONE_CONNECTED) || … … 531 530 unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data) 532 531 { 533 call_t call;532 call_t *call; 534 533 phone_t *phone; 535 534 int res; 536 535 int rc; 537 536 538 GET_CHECK_PHONE(phone, phoneid, return ENOENT );539 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);537 GET_CHECK_PHONE(phone, phoneid, return ENOENT;); 538 539 call = ipc_call_alloc(0); 540 IPC_SET_METHOD(call->data, method); 541 IPC_SET_ARG1(call->data, arg1); 542 IPC_SET_ARG2(call->data, arg2); 543 IPC_SET_ARG3(call->data, arg3); 545 544 /* 546 545 * To achieve deterministic behavior, zero out arguments that are beyond 547 546 * the limits of the fast version. 548 547 */ 549 IPC_SET_ARG4(call .data, 0);550 IPC_SET_ARG5(call .data, 0);551 552 if (!(res = request_preprocess( &call, phone))) {548 IPC_SET_ARG4(call->data, 0); 549 IPC_SET_ARG5(call->data, 0); 550 551 if (!(res = request_preprocess(call, phone))) { 553 552 #ifdef CONFIG_UDEBUG 554 553 udebug_stoppable_begin(); 555 554 #endif 556 rc = ipc_call_sync(phone, &call);555 rc = ipc_call_sync(phone, call); 557 556 #ifdef CONFIG_UDEBUG 558 557 udebug_stoppable_end(); 559 558 #endif 560 if (rc != EOK) 559 if (rc != EOK) { 560 /* The call will be freed by ipc_cleanup(). */ 561 561 return rc; 562 process_answer(&call); 562 } 563 process_answer(call); 563 564 564 565 } else { 565 IPC_SET_RETVAL(call.data, res); 566 } 567 rc = STRUCT_TO_USPACE(&data->args, &call.data.args); 566 IPC_SET_RETVAL(call->data, res); 567 } 568 rc = STRUCT_TO_USPACE(&data->args, &call->data.args); 569 ipc_call_free(call); 568 570 if (rc != 0) 569 571 return rc; … … 584 586 ipc_data_t *reply) 585 587 { 586 call_t call;588 call_t *call; 587 589 phone_t *phone; 588 590 int res; 589 591 int rc; 590 592 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) 593 GET_CHECK_PHONE(phone, phoneid, return ENOENT;); 594 595 call = ipc_call_alloc(0); 596 rc = copy_from_uspace(&call->data.args, &question->args, 597 sizeof(call->data.args)); 598 if (rc != 0) { 599 ipc_call_free(call); 595 600 return (unative_t) rc; 596 597 GET_CHECK_PHONE(phone, phoneid, return ENOENT); 598 599 if (!(res = request_preprocess( &call, phone))) {601 } 602 603 604 if (!(res = request_preprocess(call, phone))) { 600 605 #ifdef CONFIG_UDEBUG 601 606 udebug_stoppable_begin(); 602 607 #endif 603 rc = ipc_call_sync(phone, &call);608 rc = ipc_call_sync(phone, call); 604 609 #ifdef CONFIG_UDEBUG 605 610 udebug_stoppable_end(); 606 611 #endif 607 if (rc != EOK) 612 if (rc != EOK) { 613 /* The call will be freed by ipc_cleanup(). */ 608 614 return rc; 609 process_answer(&call); 615 } 616 process_answer(call); 610 617 } else 611 IPC_SET_RETVAL(call.data, res); 612 613 rc = STRUCT_TO_USPACE(&reply->args, &call.data.args); 618 IPC_SET_RETVAL(call->data, res); 619 620 rc = STRUCT_TO_USPACE(&reply->args, &call->data.args); 621 ipc_call_free(call); 614 622 if (rc != 0) 615 623 return rc; … … 658 666 return IPC_CALLRET_TEMPORARY; 659 667 660 GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL );668 GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;); 661 669 662 670 call = ipc_call_alloc(0); … … 697 705 return IPC_CALLRET_TEMPORARY; 698 706 699 GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL );707 GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;); 700 708 701 709 call = ipc_call_alloc(0); … … 747 755 call->flags |= IPC_CALL_FORWARDED; 748 756 749 GET_CHECK_PHONE(phone, phoneid, { 757 GET_CHECK_PHONE(phone, phoneid, { 750 758 IPC_SET_RETVAL(call->data, EFORWARD); 751 759 ipc_answer(&TASK->answerbox, call); … … 952 960 phone_t *phone; 953 961 954 GET_CHECK_PHONE(phone, phoneid, return ENOENT );962 GET_CHECK_PHONE(phone, phoneid, return ENOENT;); 955 963 956 964 if (ipc_phone_hangup(phone)) … … 991 999 992 1000 if (call->flags & IPC_CALL_NOTIF) { 993 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));994 995 1001 /* Set in_phone_hash to the interrupt counter */ 996 1002 call->data.phone = (void *) call->priv; … … 1005 1011 if (call->flags & IPC_CALL_ANSWERED) { 1006 1012 process_answer(call); 1007 1008 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));1009 1013 1010 1014 if (call->flags & IPC_CALL_DISCARD_ANSWER) { -
kernel/generic/src/lib/elf.c
r3da11f37 r3f35634c 163 163 case PT_LOAD: 164 164 return load_segment(entry, elf, as); 165 break;166 165 case PT_DYNAMIC: 167 166 case PT_INTERP: … … 182 181 default: 183 182 return EE_UNSUPPORTED; 184 break;185 183 } 186 184 return EE_OK; -
kernel/generic/src/proc/task.c
r3da11f37 r3f35634c 75 75 static task_id_t task_counter = 0; 76 76 77 static slab_cache_t *task_slab; 78 77 79 /* Forward declarations. */ 78 80 static void task_kill_internal(task_t *); 81 static int tsk_constructor(void *, int); 79 82 80 83 /** Initialize kernel tasks support. */ … … 83 86 TASK = NULL; 84 87 avltree_create(&tasks_tree); 88 task_slab = slab_cache_create("task_slab", sizeof(task_t), 0, 89 tsk_constructor, NULL, 0); 85 90 } 86 91 … … 128 133 } 129 134 135 int tsk_constructor(void *obj, int kmflags) 136 { 137 task_t *ta = obj; 138 int i; 139 140 atomic_set(&ta->refcount, 0); 141 atomic_set(&ta->lifecount, 0); 142 atomic_set(&ta->active_calls, 0); 143 144 spinlock_initialize(&ta->lock, "task_ta_lock"); 145 mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE); 146 147 list_initialize(&ta->th_head); 148 list_initialize(&ta->sync_box_head); 149 150 ipc_answerbox_init(&ta->answerbox, ta); 151 for (i = 0; i < IPC_MAX_PHONES; i++) 152 ipc_phone_init(&ta->phones[i]); 153 154 #ifdef CONFIG_UDEBUG 155 /* Init kbox stuff */ 156 ta->kb.thread = NULL; 157 ipc_answerbox_init(&ta->kb.box, ta); 158 mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE); 159 #endif 160 161 return 0; 162 } 163 130 164 /** Create new task with no threads. 131 165 * … … 140 174 ipl_t ipl; 141 175 task_t *ta; 142 int i; 143 144 ta = (task_t *) malloc(sizeof(task_t), 0); 145 176 177 ta = (task_t *) slab_alloc(task_slab, 0); 146 178 task_create_arch(ta); 147 148 spinlock_initialize(&ta->lock, "task_ta_lock");149 list_initialize(&ta->th_head);150 179 ta->as = as; 151 152 180 memcpy(ta->name, name, TASK_NAME_BUFLEN); 153 181 ta->name[TASK_NAME_BUFLEN - 1] = 0; 154 182 155 atomic_set(&ta->refcount, 0);156 atomic_set(&ta->lifecount, 0);157 183 ta->context = CONTEXT; 158 159 184 ta->capabilities = 0; 160 185 ta->cycles = 0; … … 165 190 166 191 /* Init kbox stuff */ 167 ipc_answerbox_init(&ta->kb.box, ta);168 ta->kb.thread = NULL;169 mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);170 192 ta->kb.finished = false; 171 193 #endif 172 194 173 ipc_answerbox_init(&ta->answerbox, ta); 174 for (i = 0; i < IPC_MAX_PHONES; i++) 175 ipc_phone_init(&ta->phones[i]); 176 if ((ipc_phone_0) && (context_check(ipc_phone_0->task->context, 177 ta->context))) 195 if ((ipc_phone_0) && 196 (context_check(ipc_phone_0->task->context, ta->context))) 178 197 ipc_phone_connect(&ta->phones[0], ipc_phone_0); 179 atomic_set(&ta->active_calls, 0); 180 181 mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE); 198 182 199 btree_create(&ta->futexes); 183 200 184 201 ipl = interrupts_disable(); 185 186 /*187 * Increment address space reference count.188 */189 202 atomic_inc(&as->refcount); 190 191 203 spinlock_lock(&tasks_lock); 192 204 ta->taskid = ++task_counter; … … 229 241 as_destroy(t->as); 230 242 231 free(t);243 slab_free(task_slab, t); 232 244 TASK = NULL; 233 245 }
Note:
See TracChangeset
for help on using the changeset viewer.
