From f45166af32a9c554f83327c6bc5868022ac721c9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 12 Feb 2016 18:03:08 -0600 Subject: [PATCH] SMP: Fix a IDLE task semaphore operation --- mm/mm_heap/mm_sem.c | 2 +- sched/init/os_smpstart.c | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mm/mm_heap/mm_sem.c b/mm/mm_heap/mm_sem.c index 4be65b623c..6a38f9b5a7 100644 --- a/mm/mm_heap/mm_sem.c +++ b/mm/mm_heap/mm_sem.c @@ -86,7 +86,7 @@ void mm_seminitialize(FAR struct mm_heap_s *heap) { /* Initialize the MM semaphore to one (to support one-at-a-time access to - * private data sets. + * private data sets). */ (void)sem_init(&heap->mm_semaphore, 0, 1); diff --git a/sched/init/os_smpstart.c b/sched/init/os_smpstart.c index 53a451f1cc..4dce113d1d 100644 --- a/sched/init/os_smpstart.c +++ b/sched/init/os_smpstart.c @@ -98,12 +98,34 @@ int os_idletask(int argc, FAR char *argv[]) /* Finish TCB initialization */ FAR struct task_tcb_s *rtcb = (FAR struct task_tcb_s *)this_task(); + int ret; /* Create stdout, stderr, stdin on the IDLE task. These will be * inherited by all of the threads created by the IDLE task. + * + * We must have exclusive access to the memory manager to do this BUT the + * idle task cannot wait on a semaphore (at least not later in the + * initialzation sequency when this thread is started). So loop until + * we do finally get access + * */ - DEBUGVERIFY(group_setupidlefiles(rtcb)); + do + { + ret = kmm_trysemaphore(); + if (ret >= 0) + { + DEBUGVERIFY(group_setupidlefiles(rtcb)); + kmm_givesemaphore(); + } + else + { + /* Perform any processor-specific idle state operations */ + + up_idle(); + } + } + while (ret < 0); #endif /* Enter the IDLE loop */