Skip to content

atmega: thread exit deadlock #9058

@Josar

Description

@Josar

When a thread ends and was not set to sleep there is a deadlock, might be related to #6526.
Enabling debug in scheduler.c removes the deadlock but then all xtimer values are wrong.

Testing with this

#include <inttypes.h>
#include <stdio.h>

#include "xtimer.h"
#include "timex.h"
#include "thread.h"

#include "Board.h"

volatile uint32_t end_times[2];

static char stack[THREAD_STACKSIZE_MAIN];
static void *_thread(void *arg)
{
    (void) arg;

    puts("thread(): waiting going to sleep!");

    //while (1) {
        thread_sleep();
        end_times[1] = _xtimer_now();
        printf("Woke up.\n");
        /* deadlock if thread is not put to sleep before return */
        /* But if ENABLE_DEBUG is activated in sched.c no deadlock,
         *  but then the timer values are wrong */
        //thread_sleep();
    //}
    return NULL;
}

int main(void)
{
    xtimer_t xtimer[2];
    uint32_t start[2];
    uint32_t interval[2];

    kernel_pid_t pid_main = thread_getpid();

    kernel_pid_t pid_1 = thread_create(stack,
                                       sizeof(stack),
                                       THREAD_PRIORITY_MAIN - 1,
                                       THREAD_CREATE_STACKTEST,
                                       _thread,
                                       NULL,
                                       "second_thread");

    interval[1] = _xtimer_usec_from_ticks(40000);
    start[1] = _xtimer_now();
    xtimer_set_wakeup(&xtimer[1], interval[1], pid_1);

    interval[0] = _xtimer_usec_from_ticks(50000);
    start[0] = _xtimer_now();
    xtimer_set_wakeup(&xtimer[0], interval[0], pid_main);

    thread_sleep();
    end_times[0] = _xtimer_now();
    for (unsigned n = 0; n < 2; n++) {
        uint32_t diff = end_times[n] - start[n];
        printf("%" PRIu32 " %" PRIu32 " slept for %" PRIu32 " ticks (%" PRIu32
               " us) expected %" PRIu32 " ticks, diff %" PRIu32 " ticks\n",
               start[n], end_times[n], diff, _xtimer_usec_from_ticks(diff),
               _xtimer_ticks_from_usec(interval[n]), diff - _xtimer_ticks_from_usec(interval[n])
               );
    }

    for (unsigned n = 0; n < 5; n++) {
        uint32_t start, end, diff, interval= 10000;

        start = _xtimer_now();
        _xtimer_tsleep32(interval);
        end = _xtimer_now();

        diff = end - start;

        printf("%" PRIu32 " %" PRIu32 " slept for %" PRIu32 " ticks (%" PRIu32
               " us) expected %" PRIu32 " ticks, diff %" PRIu32 " ticks\n",
               start, end, diff, _xtimer_usec_from_ticks(diff),
               interval, diff - interval );
    }

    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions