Changeset 875c629 in mainline


Ignore:
Timestamp:
2011-01-27T17:19:49Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
577f042a, f579760
Parents:
bf75e3cb (diff), 5b7a107 (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 'btrace' kernel console command (a last resort debugging means for printing uspace stack traces from within kernel console)

Location:
kernel/generic
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/debug.h

    rbf75e3cb r875c629  
    5555        do { \
    5656                if (!(expr)) \
    57                         panic_assert("%s", #expr); \
     57                        panic_assert("%s() at %s:%u:\n%s", \
     58                            __func__, __FILE__, __LINE__, #expr); \
    5859        } while (0)
    5960
     
    7273        do { \
    7374                if (!(expr)) \
    74                         panic_assert("%s, %s", #expr, msg); \
     75                        panic_assert("%s() at %s:%u:\n%s, %s", \
     76                            __func__, __FILE__, __LINE__, #expr, msg); \
    7577        } while (0)
    7678
  • kernel/generic/include/proc/thread.h

    rbf75e3cb r875c629  
    9191       
    9292        /** Function implementing the thread. */
    93         void (* thread_code)(void *);
     93        void (*thread_code)(void *);
    9494        /** Argument passed to thread_code() function. */
    9595        void *thread_arg;
    9696       
    9797        /**
    98          * From here, the stored context is restored when the thread is
    99          * scheduled.
     98         * From here, the stored context is restored
     99         * when the thread is scheduled.
    100100         */
    101101        context_t saved_context;
    102         /**
    103          * From here, the stored timeout context is restored when sleep times
    104          * out.
     102       
     103        /**
     104         * From here, the stored timeout context
     105         * is restored when sleep times out.
    105106         */
    106107        context_t sleep_timeout_context;
    107         /**
    108          * From here, the stored interruption context is restored when sleep is
    109          * interrupted.
     108       
     109        /**
     110         * From here, the stored interruption context
     111         * is restored when sleep is interrupted.
    110112         */
    111113        context_t sleep_interruption_context;
     
    125127         */
    126128        bool in_copy_from_uspace;
     129       
    127130        /**
    128131         * True if this thread is executing copy_to_uspace().
     
    187190       
    188191#ifdef CONFIG_UDEBUG
     192        /**
     193         * If true, the scheduler will print a stack trace
     194         * to the kernel console upon scheduling this thread.
     195         */
     196        bool btrace;
     197       
    189198        /** Debugging stuff */
    190199        udebug_thread_t udebug;
     
    237246extern bool thread_exists(thread_t *);
    238247
     248#ifdef CONFIG_UDEBUG
     249extern void thread_stack_trace(thread_id_t);
     250#endif
     251
    239252/** Fpu context slab cache. */
    240253extern slab_cache_t *fpu_context_slab;
  • kernel/generic/src/console/cmd.c

    rbf75e3cb r875c629  
    7878static cmd_info_t help_info = {
    7979        .name = "help",
    80         .description = "List of supported commands.",
     80        .description = "List supported commands.",
    8181        .func = cmd_help,
    8282        .argc = 0
    8383};
    8484
     85/* Data and methods for 'reboot' command. */
    8586static int cmd_reboot(cmd_arg_t *argv);
    8687static cmd_info_t reboot_info = {
    8788        .name = "reboot",
    88         .description = "Reboot.",
     89        .description = "Reboot system.",
    8990        .func = cmd_reboot,
    9091        .argc = 0
    9192};
    9293
     94/* Data and methods for 'uptime' command. */
    9395static int cmd_uptime(cmd_arg_t *argv);
    9496static cmd_info_t uptime_info = {
    9597        .name = "uptime",
    96         .description = "Print uptime information.",
     98        .description = "Show system uptime.",
    9799        .func = cmd_uptime,
    98100        .argc = 0
    99101};
    100102
     103/* Data and methods for 'continue' command. */
    101104static int cmd_continue(cmd_arg_t *argv);
    102105static cmd_info_t continue_info = {
     
    108111
    109112#ifdef CONFIG_TEST
     113
     114/* Data and methods for 'test' command. */
    110115static char test_buf[MAX_CMDLINE + 1];
    111116static int cmd_test(cmd_arg_t *argv);
     
    119124static cmd_info_t test_info = {
    120125        .name = "test",
    121         .description = "Print list of kernel tests or run a test.",
     126        .description = "<test> List kernel tests or run a test.",
    122127        .func = cmd_test,
    123128        .argc = 1,
     
    125130};
    126131
     132/* Data and methods for 'bench' command. */
    127133static int cmd_bench(cmd_arg_t *argv);
    128134static cmd_arg_t bench_argv[] = {
     
    138144static cmd_info_t bench_info = {
    139145        .name = "bench",
    140         .description = "Run kernel test as benchmark.",
     146        .description = "<test> <count> Run kernel test as benchmark.",
    141147        .func = cmd_bench,
    142148        .argc = 2,
    143149        .argv = bench_argv
    144150};
    145 #endif
     151
     152#endif /* CONFIG_TEST */
    146153
    147154/* Data and methods for 'description' command. */
    148155static int cmd_desc(cmd_arg_t *argv);
    149156static void desc_help(void);
    150 static char desc_buf[MAX_CMDLINE+1];
     157static char desc_buf[MAX_CMDLINE + 1];
    151158static cmd_arg_t desc_argv = {
    152159        .type = ARG_TYPE_STRING,
     
    156163static cmd_info_t desc_info = {
    157164        .name = "describe",
    158         .description = "Describe specified command.",
     165        .description = "<command> Describe specified command.",
    159166        .help = desc_help,
    160167        .func = cmd_desc,
     
    165172/* Data and methods for 'symaddr' command. */
    166173static int cmd_symaddr(cmd_arg_t *argv);
    167 static char symaddr_buf[MAX_CMDLINE+1];
     174static char symaddr_buf[MAX_CMDLINE + 1];
    168175static cmd_arg_t symaddr_argv = {
    169176        .type = ARG_TYPE_STRING,
     
    173180static cmd_info_t symaddr_info = {
    174181        .name = "symaddr",
    175         .description = "Return symbol address.",
     182        .description = "<symbol> Return symbol address.",
    176183        .func = cmd_symaddr,
    177184        .argc = 1,
     
    179186};
    180187
    181 static char set_buf[MAX_CMDLINE+1];
     188/* Data and methods for 'set4' command. */
     189static char set_buf[MAX_CMDLINE + 1];
    182190static int cmd_set4(cmd_arg_t *argv);
    183191static cmd_arg_t set4_argv[] = {
     
    193201static cmd_info_t set4_info = {
    194202        .name = "set4",
    195         .description = "set <dest_addr> <value> - 4byte version",
     203        .description = "<addr> <value> Set 4B memory location to a value.",
    196204        .func = cmd_set4,
    197205        .argc = 2,
     
    213221static cmd_info_t call0_info = {
    214222        .name = "call0",
    215         .description = "call0 <function> -> call function().",
     223        .description = "<function> Call function().",
    216224        .func = cmd_call0,
    217225        .argc = 1,
     
    228236static cmd_info_t mcall0_info = {
    229237        .name = "mcall0",
    230         .description = "mcall0 <function> -> call function() on each CPU.",
     238        .description = "<function> Call function() on each CPU.",
    231239        .func = cmd_mcall0,
    232240        .argc = 1,
     
    250258static cmd_info_t call1_info = {
    251259        .name = "call1",
    252         .description = "call1 <function> <arg1> -> call function(arg1).",
     260        .description = "<function> <arg1> Call function(arg1).",
    253261        .func = cmd_call1,
    254262        .argc = 2,
     
    277285static cmd_info_t call2_info = {
    278286        .name = "call2",
    279         .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
     287        .description = "<function> <arg1> <arg2> Call function(arg1, arg2).",
    280288        .func = cmd_call2,
    281289        .argc = 3,
     
    310318static cmd_info_t call3_info = {
    311319        .name = "call3",
    312         .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
     320        .description = "<function> <arg1> <arg2> <arg3> Call function(arg1, arg2, arg3).",
    313321        .func = cmd_call3,
    314322        .argc = 4,
     
    340348cmd_info_t tlb_info = {
    341349        .name = "tlb",
    342         .description = "Print TLB of current processor.",
     350        .description = "Print TLB of the current CPU.",
    343351        .help = NULL,
    344352        .func = cmd_tlb,
     
    377385};
    378386
     387#ifdef CONFIG_UDEBUG
     388
     389/* Data and methods for 'btrace' command */
     390static int cmd_btrace(cmd_arg_t *argv);
     391static cmd_arg_t btrace_argv = {
     392        .type = ARG_TYPE_INT,
     393};
     394static cmd_info_t btrace_info = {
     395        .name = "btrace",
     396        .description = "<threadid> Show thread stack trace.",
     397        .func = cmd_btrace,
     398        .argc = 1,
     399        .argv = &btrace_argv
     400};
     401
     402#endif /* CONFIG_UDEBUG */
    379403
    380404static int cmd_sched(cmd_arg_t *argv);
    381405static cmd_info_t sched_info = {
    382406        .name = "scheduler",
    383         .description = "List all scheduler information.",
     407        .description = "Show scheduler information.",
    384408        .func = cmd_sched,
    385409        .argc = 0
     
    406430static cmd_info_t zones_info = {
    407431        .name = "zones",
    408         .description = "List of memory zones.",
     432        .description = "List memory zones.",
    409433        .func = cmd_zones,
    410434        .argc = 0
     435};
     436
     437/* Data and methods for 'zone' command */
     438static int cmd_zone(cmd_arg_t *argv);
     439static cmd_arg_t zone_argv = {
     440        .type = ARG_TYPE_INT,
     441};
     442
     443static cmd_info_t zone_info = {
     444        .name = "zone",
     445        .description = "<zone> Show memory zone structure.",
     446        .func = cmd_zone,
     447        .argc = 1,
     448        .argv = &zone_argv
    411449};
    412450
     
    418456static cmd_info_t ipc_info = {
    419457        .name = "ipc",
    420         .description = "ipc <taskid> Show IPC information of given task.",
     458        .description = "<taskid> Show IPC information of a task.",
    421459        .func = cmd_ipc,
    422460        .argc = 1,
     
    431469static cmd_info_t kill_info = {
    432470        .name = "kill",
    433         .description = "kill <taskid> Kill a task.",
     471        .description = "<taskid> Kill a task.",
    434472        .func = cmd_kill,
    435473        .argc = 1,
    436474        .argv = &kill_argv
    437 };
    438 
    439 /* Data and methods for 'zone' command */
    440 static int cmd_zone(cmd_arg_t *argv);
    441 static cmd_arg_t zone_argv = {
    442         .type = ARG_TYPE_INT,
    443 };
    444 
    445 static cmd_info_t zone_info = {
    446         .name = "zone",
    447         .description = "Show memory zone structure.",
    448         .func = cmd_zone,
    449         .argc = 1,
    450         .argv = &zone_argv
    451475};
    452476
     
    482506        &cpus_info,
    483507        &desc_info,
    484         &reboot_info,
    485         &uptime_info,
    486508        &halt_info,
    487509        &help_info,
    488510        &ipc_info,
    489511        &kill_info,
     512        &physmem_info,
     513        &reboot_info,
     514        &sched_info,
    490515        &set4_info,
    491516        &slabs_info,
     517        &symaddr_info,
    492518        &sysinfo_info,
    493         &symaddr_info,
    494         &sched_info,
     519        &tasks_info,
    495520        &threads_info,
    496         &tasks_info,
    497         &physmem_info,
    498521        &tlb_info,
     522        &uptime_info,
    499523        &version_info,
    500524        &zones_info,
     
    504528        &bench_info,
    505529#endif
     530#ifdef CONFIG_UDEBUG
     531        &btrace_info,
     532#endif
    506533        NULL
    507534};
     
    530557        }
    531558}
    532 
    533559
    534560/** List supported commands.
     
    574600}
    575601
    576 
    577602/** Reboot the system.
    578603 *
     
    588613        return 1;
    589614}
    590 
    591615
    592616/** Print system uptime information.
     
    824848}
    825849
    826 
    827850/** Print detailed description of 'describe' command. */
    828851void desc_help(void)
     
    911934 * @return Always 1
    912935 */
    913 int cmd_slabs(cmd_arg_t * argv)
     936int cmd_slabs(cmd_arg_t *argv)
    914937{
    915938        slab_print_list();
     
    923946 * @return Always 1
    924947 */
    925 int cmd_sysinfo(cmd_arg_t * argv)
     948int cmd_sysinfo(cmd_arg_t *argv)
    926949{
    927950        sysinfo_dump(NULL);
     
    929952}
    930953
    931 
    932 /** Command for listings Thread information
     954/** Command for listing thread information
    933955 *
    934956 * @param argv Ignored
     
    948970}
    949971
    950 /** Command for listings Task information
     972/** Command for listing task information
    951973 *
    952974 * @param argv Ignored
     
    966988}
    967989
    968 /** Command for listings Thread information
     990#ifdef CONFIG_UDEBUG
     991
     992/** Command for printing thread stack trace
     993 *
     994 * @param argv Integer argument from cmdline expected
     995 *
     996 * return Always 1
     997 *
     998 */
     999int cmd_btrace(cmd_arg_t *argv)
     1000{
     1001        thread_stack_trace(argv[0].intval);
     1002        return 1;
     1003}
     1004
     1005#endif /* CONFIG_UDEBUG */
     1006
     1007/** Command for printing scheduler information
    9691008 *
    9701009 * @param argv Ignores
     
    9721011 * @return Always 1
    9731012 */
    974 int cmd_sched(cmd_arg_t * argv)
     1013int cmd_sched(cmd_arg_t *argv)
    9751014{
    9761015        sched_print_list();
     
    9841023 * return Always 1
    9851024 */
    986 int cmd_zones(cmd_arg_t * argv)
     1025int cmd_zones(cmd_arg_t *argv)
    9871026{
    9881027        zones_print_list();
     
    9961035 * return Always 1
    9971036 */
    998 int cmd_zone(cmd_arg_t * argv)
     1037int cmd_zone(cmd_arg_t *argv)
    9991038{
    10001039        zone_print_one(argv[0].intval);
     
    10021041}
    10031042
    1004 /** Command for printing task ipc details
     1043/** Command for printing task IPC details
    10051044 *
    10061045 * @param argv Integer argument from cmdline expected
     
    10081047 * return Always 1
    10091048 */
    1010 int cmd_ipc(cmd_arg_t * argv)
     1049int cmd_ipc(cmd_arg_t *argv)
    10111050{
    10121051        ipc_print_task(argv[0].intval);
     
    10201059 * return 0 on failure, 1 on success.
    10211060 */
    1022 int cmd_kill(cmd_arg_t * argv)
     1061int cmd_kill(cmd_arg_t *argv)
    10231062{
    10241063        if (task_kill(argv[0].intval) != EOK)
  • kernel/generic/src/proc/scheduler.c

    rbf75e3cb r875c629  
    6262#include <print.h>
    6363#include <debug.h>
    64 
    65 static void before_task_runs(void);
    66 static void before_thread_runs(void);
    67 static void after_thread_ran(void);
     64#include <stacktrace.h>
     65
    6866static void scheduler_separated_stack(void);
    6967
     
    7169
    7270/** Carry out actions before new task runs. */
    73 void before_task_runs(void)
     71static void before_task_runs(void)
    7472{
    7573        before_task_runs_arch();
     
    8078 * Perform actions that need to be
    8179 * taken before the newly selected
    82  * tread is passed control.
     80 * thread is passed control.
    8381 *
    8482 * THREAD->lock is locked on entry
    8583 *
    8684 */
    87 void before_thread_runs(void)
     85static void before_thread_runs(void)
    8886{
    8987        before_thread_runs_arch();
     88       
    9089#ifdef CONFIG_FPU_LAZY
    91         if(THREAD == CPU->fpu_owner)
     90        if (THREAD == CPU->fpu_owner)
    9291                fpu_enable();
    9392        else
     
    102101        }
    103102#endif
     103       
     104#ifdef CONFIG_UDEBUG
     105        if (THREAD->btrace) {
     106                istate_t *istate = THREAD->udebug.uspace_state;
     107                if (istate != NULL) {
     108                        printf("Thread %" PRIu64 " stack trace:\n", THREAD->tid);
     109                        stack_trace_istate(istate);
     110                }
     111               
     112                THREAD->btrace = false;
     113        }
     114#endif
    104115}
    105116
     
    113124 *
    114125 */
    115 void after_thread_ran(void)
     126static void after_thread_ran(void)
    116127{
    117128        after_thread_ran_arch();
     
    391402         * possible destruction should thread_destroy() be called on this or any
    392403         * other processor while the scheduler is still using them.
    393          *
    394404         */
    395405        if (old_task)
     
    417427                                 * The thread structure is kept allocated until
    418428                                 * somebody calls thread_detach() on it.
    419                                  *
    420429                                 */
    421430                                if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
    422431                                        /*
    423432                                         * Avoid deadlock.
    424                                          *
    425433                                         */
    426434                                        irq_spinlock_unlock(&THREAD->lock, false);
     
    443451                        /*
    444452                         * Prefer the thread after it's woken up.
    445                          *
    446453                         */
    447454                        THREAD->priority = -1;
     
    451458                         * waitq_sleep(). Address of wq->lock is kept in
    452459                         * THREAD->sleep_queue.
    453                          *
    454460                         */
    455461                        irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
     
    461467                        /*
    462468                         * Entering state is unexpected.
    463                          *
    464469                         */
    465470                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    480485       
    481486        /*
    482          * If both the old and the new task are the same, lots of work is
    483          * avoided.
    484          *
     487         * If both the old and the new task are the same,
     488         * lots of work is avoided.
    485489         */
    486490        if (TASK != THREAD->task) {
     
    488492               
    489493                /*
    490                  * Note that it is possible for two tasks to share one address
    491                  * space.
    492                  (
     494                 * Note that it is possible for two tasks
     495                 * to share one address space.
    493496                 */
    494497                if (old_as != new_as) {
     
    496499                         * Both tasks and address spaces are different.
    497500                         * Replace the old one with the new one.
    498                          *
    499501                         */
    500502                        as_switch(old_as, new_as);
     
    527529         * necessary, is to be mapped in before_thread_runs(). This
    528530         * function must be executed before the switch to the new stack.
    529          *
    530531         */
    531532        before_thread_runs();
     
    534535         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    535536         * thread's stack.
    536          *
    537537         */
    538538        the_copy(THE, (the_t *) THREAD->kstack);
     
    658658                                /*
    659659                                 * Ready thread on local CPU
    660                                  *
    661660                                 */
    662661                               
  • kernel/generic/src/proc/task.c

    rbf75e3cb r875c629  
    449449static void task_kill_internal(task_t *task)
    450450{
     451        irq_spinlock_lock(&task->lock, false);
     452        irq_spinlock_lock(&threads_lock, false);
     453       
     454        /*
     455         * Interrupt all threads.
     456         */
     457       
    451458        link_t *cur;
    452        
    453         /*
    454          * Interrupt all threads.
    455          */
    456         irq_spinlock_lock(&task->lock, false);
    457459        for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
    458460                thread_t *thread = list_get_instance(cur, thread_t, th_link);
     
    471473        }
    472474       
     475        irq_spinlock_unlock(&threads_lock, false);
    473476        irq_spinlock_unlock(&task->lock, false);
    474477}
  • kernel/generic/src/proc/thread.c

    rbf75e3cb r875c629  
    239239 * Switch thread to the ready state.
    240240 *
    241  * @param t Thread to make ready.
     241 * @param thread Thread to make ready.
    242242 *
    243243 */
     
    246246        irq_spinlock_lock(&thread->lock, true);
    247247       
    248         ASSERT(!(thread->state == Ready));
     248        ASSERT(thread->state != Ready);
    249249       
    250250        int i = (thread->priority < RQ_COUNT - 1)
     
    350350       
    351351#ifdef CONFIG_UDEBUG
    352         /* Init debugging stuff */
     352        /* Initialize debugging stuff */
     353        thread->btrace = false;
    353354        udebug_thread_initialize(&thread->udebug);
    354355#endif
     
    535536/** Detach thread.
    536537 *
    537  * Mark the thread as detached, if the thread is already in the Lingering
    538  * state, deallocate its resources.
     538 * Mark the thread as detached. If the thread is already
     539 * in the Lingering state, deallocate its resources.
    539540 *
    540541 * @param thread Thread to be detached.
     
    740741        ASSERT(interrupts_disabled());
    741742        ASSERT(irq_spinlock_locked(&threads_lock));
    742 
     743       
    743744        thread_iterator_t iterator;
    744745       
     
    751752}
    752753
     754#ifdef CONFIG_UDEBUG
     755
     756void thread_stack_trace(thread_id_t thread_id)
     757{
     758        irq_spinlock_lock(&threads_lock, true);
     759       
     760        thread_t *thread = thread_find_by_id(thread_id);
     761        if (thread == NULL) {
     762                printf("No such thread.\n");
     763                irq_spinlock_unlock(&threads_lock, true);
     764                return;
     765        }
     766       
     767        irq_spinlock_lock(&thread->lock, false);
     768       
     769        /*
     770         * Schedule a stack trace to be printed
     771         * just before the thread is scheduled next.
     772         *
     773         * If the thread is sleeping then try to interrupt
     774         * the sleep. Any request for printing an uspace stack
     775         * trace from within the kernel should be always
     776         * considered a last resort debugging means, therefore
     777         * forcing the thread's sleep to be interrupted
     778         * is probably justifiable.
     779         */
     780       
     781        bool sleeping = false;
     782        istate_t *istate = thread->udebug.uspace_state;
     783        if (istate != NULL) {
     784                printf("Scheduling thread stack trace.\n");
     785                thread->btrace = true;
     786                if (thread->state == Sleeping)
     787                        sleeping = true;
     788        } else
     789                printf("Thread interrupt state not available.\n");
     790       
     791        irq_spinlock_unlock(&thread->lock, false);
     792       
     793        if (sleeping)
     794                waitq_interrupt_sleep(thread);
     795       
     796        irq_spinlock_unlock(&threads_lock, true);
     797}
     798
     799#endif /* CONFIG_UDEBUG */
    753800
    754801/** Process syscall to create new thread.
     
    793840                                 * has already been created. We need to undo its
    794841                                 * creation now.
    795                                  *
    796842                                 */
    797843                               
     
    815861                 * THREAD_B events for threads that already existed
    816862                 * and could be detected with THREAD_READ before.
    817                  *
    818863                 */
    819864                udebug_thread_b_event_attach(thread, TASK);
  • kernel/generic/src/synch/waitq.c

    rbf75e3cb r875c629  
    127127/** Interrupt sleeping thread.
    128128 *
    129  * This routine attempts to interrupt a thread from its sleep in a waitqueue.
    130  * If the thread is not found sleeping, no action is taken.
     129 * This routine attempts to interrupt a thread from its sleep in
     130 * a waitqueue. If the thread is not found sleeping, no action
     131 * is taken.
     132 *
     133 * The threads_lock must be already held and interrupts must be
     134 * disabled upon calling this function.
    131135 *
    132136 * @param thread Thread to be interrupted.
     
    138142        DEADLOCK_PROBE_INIT(p_wqlock);
    139143       
    140         irq_spinlock_lock(&threads_lock, true);
    141         if (!thread_exists(thread))
    142                 goto out;
     144        /*
     145         * The thread is quaranteed to exist because
     146         * threads_lock is held.
     147         */
    143148       
    144149grab_locks:
     
    150155                        /*
    151156                         * The sleep cannot be interrupted.
    152                          *
    153157                         */
    154158                        irq_spinlock_unlock(&thread->lock, false);
    155                         goto out;
     159                        return;
    156160                }
    157161               
    158162                if (!irq_spinlock_trylock(&wq->lock)) {
     163                        /* Avoid deadlock */
    159164                        irq_spinlock_unlock(&thread->lock, false);
    160165                        DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD);
    161                         /* Avoid deadlock */
    162166                        goto grab_locks;
    163167                }
     
    173177                irq_spinlock_unlock(&wq->lock, false);
    174178        }
     179       
    175180        irq_spinlock_unlock(&thread->lock, false);
    176181       
    177182        if (do_wakeup)
    178183                thread_ready(thread);
    179        
    180 out:
    181         irq_spinlock_unlock(&threads_lock, true);
    182184}
    183185
     
    370372                 * If the thread was already interrupted,
    371373                 * don't go to sleep at all.
    372                  *
    373374                 */
    374375                if (THREAD->interrupted) {
     
    381382                 * Set context that will be restored if the sleep
    382383                 * of this thread is ever interrupted.
    383                  *
    384384                 */
    385385                THREAD->sleep_interruptible = true;
Note: See TracChangeset for help on using the changeset viewer.