Changes in kernel/generic/src/proc/task.c [d3808d3:41df2827] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/proc/task.c
rd3808d3 r41df2827 1 1 /* 2 * Copyright (c) 20 10Jakub Jermar2 * Copyright (c) 2001-2004 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Task management. 36 36 */ 37 37 … … 53 53 #include <errno.h> 54 54 #include <func.h> 55 #include <str .h>55 #include <string.h> 56 56 #include <memstr.h> 57 57 #include <syscall/copy.h> … … 66 66 * The task is guaranteed to exist after it was found in the tasks_tree as 67 67 * long as: 68 *69 68 * @li the tasks_lock is held, 70 69 * @li the task's lock is held when task's lock is acquired before releasing … … 100 99 task_t *t = avltree_get_instance(node, task_t, tasks_tree_node); 101 100 unsigned *cnt = (unsigned *) arg; 102 101 103 102 if (t != TASK) { 104 103 (*cnt)++; … … 108 107 task_kill_internal(t); 109 108 } 110 111 /* Continue the walk */ 112 return true; 109 110 return true; /* continue the walk */ 113 111 } 114 112 … … 117 115 { 118 116 unsigned tasks_left; 119 117 120 118 do { /* Repeat until there are any tasks except TASK */ 121 119 /* Messing with task structures, avoid deadlock */ … … 140 138 task_t *ta = obj; 141 139 int i; 142 140 143 141 atomic_set(&ta->refcount, 0); 144 142 atomic_set(&ta->lifecount, 0); 145 143 atomic_set(&ta->active_calls, 0); 146 144 147 145 spinlock_initialize(&ta->lock, "task_ta_lock"); 148 146 mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE); 149 147 150 148 list_initialize(&ta->th_head); 151 149 list_initialize(&ta->sync_box_head); 152 150 153 151 ipc_answerbox_init(&ta->answerbox, ta); 154 152 for (i = 0; i < IPC_MAX_PHONES; i++) 155 153 ipc_phone_init(&ta->phones[i]); 156 154 157 155 #ifdef CONFIG_UDEBUG 158 156 /* Init kbox stuff */ … … 161 159 mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE); 162 160 #endif 163 161 164 162 return 0; 165 163 } … … 167 165 /** Create new task with no threads. 168 166 * 169 * @param as 170 * @param name 171 * 172 * @return 173 * 174 */ 175 task_t *task_create(as_t *as, c onst char *name)167 * @param as Task's address space. 168 * @param name Symbolic name (a copy is made). 169 * 170 * @return New task's structure. 171 * 172 */ 173 task_t *task_create(as_t *as, char *name) 176 174 { 177 175 ipl_t ipl; … … 183 181 memcpy(ta->name, name, TASK_NAME_BUFLEN); 184 182 ta->name[TASK_NAME_BUFLEN - 1] = 0; 185 183 186 184 ta->context = CONTEXT; 187 185 ta->capabilities = 0; 188 ta->ucycles = 0; 189 ta->kcycles = 0; 190 191 ta->ipc_info.call_sent = 0; 192 ta->ipc_info.call_recieved = 0; 193 ta->ipc_info.answer_sent = 0; 194 ta->ipc_info.answer_recieved = 0; 195 ta->ipc_info.irq_notif_recieved = 0; 196 ta->ipc_info.forwarded = 0; 186 ta->cycles = 0; 197 187 198 188 #ifdef CONFIG_UDEBUG 199 189 /* Init debugging stuff */ 200 190 udebug_task_init(&ta->udebug); 201 191 202 192 /* Init kbox stuff */ 203 193 ta->kb.finished = false; 204 194 #endif 205 195 206 196 if ((ipc_phone_0) && 207 197 (context_check(ipc_phone_0->task->context, ta->context))) 208 198 ipc_phone_connect(&ta->phones[0], ipc_phone_0); 209 199 210 200 btree_create(&ta->futexes); 211 201 212 /*213 * Get a reference to the address space.214 */215 as_hold(ta->as);216 217 202 ipl = interrupts_disable(); 203 atomic_inc(&as->refcount); 218 204 spinlock_lock(&tasks_lock); 219 205 ta->taskid = ++task_counter; … … 229 215 /** Destroy task. 230 216 * 231 * @param t Task to be destroyed. 232 * 217 * @param t Task to be destroyed. 233 218 */ 234 219 void task_destroy(task_t *t) … … 240 225 avltree_delete(&tasks_tree, &t->tasks_tree_node); 241 226 spinlock_unlock(&tasks_lock); 242 227 243 228 /* 244 229 * Perform architecture specific task destruction. 245 230 */ 246 231 task_destroy_arch(t); 247 232 248 233 /* 249 234 * Free up dynamically allocated state. 250 235 */ 251 236 btree_destroy(&t->futexes); 252 237 253 238 /* 254 239 * Drop our reference to the address space. 255 240 */ 256 as_release(t->as); 241 if (atomic_predec(&t->as->refcount) == 0) 242 as_destroy(t->as); 257 243 258 244 slab_free(task_slab, t); 259 } 260 261 /** Hold a reference to a task. 262 * 263 * Holding a reference to a task prevents destruction of that task. 264 * 265 * @param t Task to be held. 266 */ 267 void task_hold(task_t *t) 268 { 269 atomic_inc(&t->refcount); 270 } 271 272 /** Release a reference to a task. 273 * 274 * The last one to release a reference to a task destroys the task. 275 * 276 * @param t Task to be released. 277 */ 278 void task_release(task_t *t) 279 { 280 if ((atomic_predec(&t->refcount)) == 0) 281 task_destroy(t); 245 TASK = NULL; 282 246 } 283 247 284 248 /** Syscall for reading task ID from userspace. 285 249 * 286 * @param uspace_task_id Userspace address of 8-byte buffer 287 * where to store current task ID. 288 * 289 * @return Zero on success or an error code from @ref errno.h. 290 * 250 * @param uspace_task_id userspace address of 8-byte buffer 251 * where to store current task ID. 252 * 253 * @return Zero on success or an error code from @ref errno.h. 291 254 */ 292 255 unative_t sys_task_get_id(task_id_t *uspace_task_id) … … 304 267 * The name simplifies identifying the task in the task list. 305 268 * 306 * @param name 307 * 269 * @param name The new name for the task. (typically the same 270 * as the command used to execute it). 308 271 * 309 272 * @return 0 on success or an error code from @ref errno.h. 310 *311 273 */ 312 274 unative_t sys_task_set_name(const char *uspace_name, size_t name_len) … … 314 276 int rc; 315 277 char namebuf[TASK_NAME_BUFLEN]; 316 278 317 279 /* Cap length of name and copy it from userspace. */ 318 280 319 281 if (name_len > TASK_NAME_BUFLEN - 1) 320 282 name_len = TASK_NAME_BUFLEN - 1; 321 283 322 284 rc = copy_from_uspace(namebuf, uspace_name, name_len); 323 285 if (rc != 0) 324 286 return (unative_t) rc; 325 287 326 288 namebuf[name_len] = '\0'; 327 289 str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf); 328 290 329 291 return EOK; 330 292 } … … 335 297 * interrupts must be disabled. 336 298 * 337 * @param id Task ID. 338 * 339 * @return Task structure address or NULL if there is no such task ID. 340 * 341 */ 342 task_t *task_find_by_id(task_id_t id) 343 { 344 avltree_node_t *node = 345 avltree_search(&tasks_tree, (avltree_key_t) id); 346 299 * @param id Task ID. 300 * 301 * @return Task structure address or NULL if there is no such task 302 * ID. 303 */ 304 task_t *task_find_by_id(task_id_t id) { avltree_node_t *node; 305 306 node = avltree_search(&tasks_tree, (avltree_key_t) id); 307 347 308 if (node) 348 309 return avltree_get_instance(node, task_t, tasks_tree_node); 349 350 310 return NULL; 351 311 } … … 356 316 * already disabled. 357 317 * 358 * @param t Pointer to thread. 359 * @param ucycles Out pointer to sum of all user cycles. 360 * @param kcycles Out pointer to sum of all kernel cycles. 361 * 362 */ 363 void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles) 364 { 365 /* Accumulated values of task */ 366 uint64_t uret = t->ucycles; 367 uint64_t kret = t->kcycles; 318 * @param t Pointer to thread. 319 * 320 * @return Number of cycles used by the task and all its threads 321 * so far. 322 */ 323 uint64_t task_get_accounting(task_t *t) 324 { 325 /* Accumulated value of task */ 326 uint64_t ret = t->cycles; 368 327 369 328 /* Current values of threads */ … … 377 336 if (thr == THREAD) { 378 337 /* Update accounting of current thread */ 379 thread_update_accounting( false);338 thread_update_accounting(); 380 339 } 381 uret += thr->ucycles; 382 kret += thr->kcycles; 340 ret += thr->cycles; 383 341 } 384 342 spinlock_unlock(&thr->lock); 385 343 } 386 344 387 *ucycles = uret; 388 *kcycles = kret; 345 return ret; 389 346 } 390 347 … … 392 349 { 393 350 link_t *cur; 394 351 395 352 /* 396 353 * Interrupt all threads. … … 420 377 * It signals all the task's threads to bail it out. 421 378 * 422 * @param id ID of the task to be killed. 423 * 424 * @return Zero on success or an error code from errno.h. 425 * 379 * @param id ID of the task to be killed. 380 * 381 * @return Zero on success or an error code from errno.h. 426 382 */ 427 383 int task_kill(task_id_t id) … … 450 406 task_t *t = avltree_get_instance(node, task_t, tasks_tree_node); 451 407 int j; 452 408 453 409 spinlock_lock(&t->lock); 454 455 uint64_t ucycles; 456 uint64_t kcycles; 457 char usuffix, ksuffix; 458 task_get_accounting(t, &ucycles, &kcycles); 459 order_suffix(ucycles, &ucycles, &usuffix); 460 order_suffix(kcycles, &kcycles, &ksuffix); 461 410 411 uint64_t cycles; 412 char suffix; 413 order(task_get_accounting(t), &cycles, &suffix); 414 462 415 #ifdef __32_BITS__ 463 printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %9" 464 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, 465 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount), 466 atomic_get(&t->active_calls)); 467 #endif 468 416 printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 417 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, 418 suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); 419 #endif 420 469 421 #ifdef __64_BITS__ 470 printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %9" 471 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, 472 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount), 473 atomic_get(&t->active_calls)); 474 #endif 475 422 printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 423 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, 424 suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); 425 #endif 426 476 427 for (j = 0; j < IPC_MAX_PHONES; j++) { 477 428 if (t->phones[j].callee) … … 479 430 } 480 431 printf("\n"); 481 432 482 433 spinlock_unlock(&t->lock); 483 434 return true; … … 492 443 ipl = interrupts_disable(); 493 444 spinlock_lock(&tasks_lock); 494 495 #ifdef __32_BITS__ 496 printf("taskid name ctx address as "497 " ucycles kcyclesthreads calls callee\n");498 printf("------ ------------ --- ---------- ---------- "499 " -------------------- ------- ------ ------>\n");500 #endif 501 445 446 #ifdef __32_BITS__ 447 printf("taskid name ctx address as " 448 "cycles threads calls callee\n"); 449 printf("------ ------------ --- ---------- ---------- " 450 "---------- ------- ------ ------>\n"); 451 #endif 452 502 453 #ifdef __64_BITS__ 503 printf("taskid name ctx address as "504 " ucycles kcyclesthreads calls callee\n");505 printf("------ ------------ --- ------------------ ------------------ "506 " ---------- -------------------- ------- ------ ------>\n");507 #endif 508 454 printf("taskid name ctx address as " 455 "cycles threads calls callee\n"); 456 printf("------ ------------ --- ------------------ ------------------ " 457 "---------- ------- ------ ------>\n"); 458 #endif 459 509 460 avltree_walk(&tasks_tree, task_print_walker, NULL); 510 461 511 462 spinlock_unlock(&tasks_lock); 512 463 interrupts_restore(ipl);
Note:
See TracChangeset
for help on using the changeset viewer.