Changeset ad7a6c9 in mainline for kernel/generic/src/proc/task.c


Ignore:
Timestamp:
2011-03-30T13:10:24Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4ae90f9
Parents:
6e50466 (diff), d6b81941 (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.
Message:

Merge mainline changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/task.c

    r6e50466 rad7a6c9  
    342342sysarg_t sys_task_set_name(const char *uspace_name, size_t name_len)
    343343{
    344         int rc;
    345344        char namebuf[TASK_NAME_BUFLEN];
    346345       
    347346        /* Cap length of name and copy it from userspace. */
    348        
    349347        if (name_len > TASK_NAME_BUFLEN - 1)
    350348                name_len = TASK_NAME_BUFLEN - 1;
    351349       
    352         rc = copy_from_uspace(namebuf, uspace_name, name_len);
     350        int rc = copy_from_uspace(namebuf, uspace_name, name_len);
    353351        if (rc != 0)
    354352                return (sysarg_t) rc;
    355353       
    356354        namebuf[name_len] = '\0';
     355       
     356        /*
     357         * As the task name is referenced also from the
     358         * threads, lock the threads' lock for the course
     359         * of the update.
     360         */
     361       
     362        irq_spinlock_lock(&tasks_lock, true);
     363        irq_spinlock_lock(&TASK->lock, false);
     364        irq_spinlock_lock(&threads_lock, false);
     365       
     366        /* Set task name */
    357367        str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
    358368       
     369        irq_spinlock_unlock(&threads_lock, false);
     370        irq_spinlock_unlock(&TASK->lock, false);
     371        irq_spinlock_unlock(&tasks_lock, true);
     372       
    359373        return EOK;
     374}
     375
     376/** Syscall to forcefully terminate a task
     377 *
     378 * @param uspace_taskid Pointer to task ID in user space.
     379 *
     380 * @return 0 on success or an error code from @ref errno.h.
     381 *
     382 */
     383sysarg_t sys_task_kill(task_id_t *uspace_taskid)
     384{
     385        task_id_t taskid;
     386        int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(taskid));
     387        if (rc != 0)
     388                return (sysarg_t) rc;
     389       
     390        return (sysarg_t) task_kill(taskid);
    360391}
    361392
     
    430461static void task_kill_internal(task_t *task)
    431462{
     463        irq_spinlock_lock(&task->lock, false);
     464        irq_spinlock_lock(&threads_lock, false);
     465       
     466        /*
     467         * Interrupt all threads.
     468         */
     469       
    432470        link_t *cur;
    433        
    434         /*
    435          * Interrupt all threads.
    436          */
    437         irq_spinlock_lock(&task->lock, false);
    438471        for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
    439472                thread_t *thread = list_get_instance(cur, thread_t, th_link);
     
    452485        }
    453486       
     487        irq_spinlock_unlock(&threads_lock, false);
    454488        irq_spinlock_unlock(&task->lock, false);
    455489}
     
    481515        irq_spinlock_unlock(&tasks_lock, true);
    482516       
     517        return EOK;
     518}
     519
     520/** Kill the currently running task.
     521 *
     522 * @param notify Send out fault notifications.
     523 *
     524 * @return Zero on success or an error code from errno.h.
     525 *
     526 */
     527void task_kill_self(bool notify)
     528{
     529        /*
     530         * User space can subscribe for FAULT events to take action
     531         * whenever a task faults (to take a dump, run a debugger, etc.).
     532         * The notification is always available, but unless udebug is enabled,
     533         * that's all you get.
     534        */
     535        if (notify) {
     536                if (event_is_subscribed(EVENT_FAULT)) {
     537                        /* Notify the subscriber that a fault occurred. */
     538                        event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
     539                            UPPER32(TASK->taskid), (sysarg_t) THREAD);
     540               
     541#ifdef CONFIG_UDEBUG
     542                        /* Wait for a debugging session. */
     543                        udebug_thread_fault();
     544#endif
     545                }
     546        }
     547       
     548        irq_spinlock_lock(&tasks_lock, true);
     549        task_kill_internal(TASK);
     550        irq_spinlock_unlock(&tasks_lock, true);
     551       
     552        thread_exit();
     553}
     554
     555/** Process syscall to terminate the current task.
     556 *
     557 * @param notify Send out fault notifications.
     558 *
     559 */
     560sysarg_t sys_task_exit(sysarg_t notify)
     561{
     562        task_kill_self(notify);
     563       
     564        /* Unreachable */
    483565        return EOK;
    484566}
Note: See TracChangeset for help on using the changeset viewer.