From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.182.213.166 with SMTP id nt6mr8257799obc.3.1438979685582; Fri, 07 Aug 2015 13:34:45 -0700 (PDT) X-Received: by 10.182.33.10 with SMTP id n10mr50172obi.18.1438979685559; Fri, 07 Aug 2015 13:34:45 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!news.glorb.com!pg9no7867399igb.0!news-out.google.com!nt1ni1923igb.0!nntp.google.com!pg9no7867389igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 7 Aug 2015 13:34:45 -0700 (PDT) In-Reply-To: <50e2f61b-bdc3-485d-a492-b44bac1f8fc0@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=74.203.194.21; posting-account=bXcJoAoAAAAWI5APBG37o4XwnD4kTuQQ NNTP-Posting-Host: 74.203.194.21 References: <27492d6c-3bf8-4eb9-8ebb-4d9f621235eb@googlegroups.com> <14a3a434-73a8-434f-9196-45c46b381e21@googlegroups.com> <50e2f61b-bdc3-485d-a492-b44bac1f8fc0@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <8eb4eed3-7d0e-4d3c-a6df-292bcfb8f2de@googlegroups.com> Subject: Re: Ravenscar and context switching for Cortex-M4 From: Patrick Noffke Injection-Date: Fri, 07 Aug 2015 20:34:45 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:27389 Date: 2015-08-07T13:34:45-07:00 List-Id: On Thursday, August 6, 2015 at 4:43:52 PM UTC-5, Patrick Noffke wrote: > >=20 > > There is another bug that I've discovered in the GNAT 2015 Ravenscar-fu= ll runtime (Cortex-M4) that appears to be caused by the Interrupt_Wrapper c= hanging the task's priority. When there is no Runnable task, Leave_Kernel = will Insert the non-Runnable task back into the ready queue (with state of = Delayed or Suspended). This task is also stored in the Running_Thread_Tabl= e (only one value in the table for a single CPU). Then an interrupt comes = along and raises the priority of the Runnable_Thread_Table task (which is D= elayed) to that of the interrupt. And the task that is woken up by the int= errupt goes later in the ready queue, since its priority is now lower than = the Delayed task. > >=20 > > This ultimately causes the task that was readied by the interrupt to no= t run (in my case, it never runs again). I haven't traced all the subseque= nt behavior to know exactly why this happens, but if I don't change priorit= ies in the Interrupt_Wrapper, the problem seems to be gone. > >=20 I just sent the following bug report to AdaCore: I have discovered another bug in your GNAT 2015 Ravenscar runtime on a Cort= ex-M4 processor. In s-bbthqu.adb, in the Change_Priority procedure, there is this comment: -- When raising the priority, it is not possible that there is anoth= er -- task with a higher priority (otherwise the other task would be -- running). Hence, there is no displacement required within the -- queue, because the thread is already in the first position. That assumption is not correct when there are simultaneous interrupts befor= e PendSV has had a chance to run. I will detail how the bug manifests, but first I wanted to point out that t= he calls to Change_Priority in the Interrupt_Handler are not always (if eve= r) associated with the task that the interrupt may wake up, if there is eve= n a task related to that interrupt. Typically, when the interrupt fires, t= he current task is the Environment_Task, which is either Delayed or Suspend= ed. That task is assigned to Self_Id in the interrupt handler, which has n= othing to do with the interrupt in my case. The call to Change_Priority in Interrupt_Handler is part of the reason for = this specific problem. I have three tasks and two interrupts: Main Loop (Environment_Task), priority =3D 0x00 PWM Task, priority =3D 0xC8 SPI Task, priority =3D 0x50 PWM ISR, priority =3D 0xFC SPI ISR, priority =3D 0xFB The PWM task is woken up by a PO associated with the PWM ISR, and similarly= for the SPI task/ISR. The condition for this error is the PWM ISR fires, and is immediately follo= wed by the SPI ISR. PendSV does not fire between (confirmed by an ITM trac= e capture). In that case, the following sequence happens. I will list act= ive and base priorities for a task below as 0xAA/0xBB (0xAA =3D active prio= rity, 0xBB =3D base priority). 1. 0x00 is the current task (i.e. in Runnable_Thread_Table, with Delayed st= ate). 2. PWM ISR fires and calls Change_Priority, raising 0x00 priority to 0xFC. 3. PWM ISR causes PWM task (0xC8) to become ready, so Insert is called and = ready queue order is 0xFC/0x00, 0xC8/0xC8. 4. PWM ISR calls Change_Priority to lower current task, so ready queue is 0= xC8/0xC8, 0x00/0x00. 5. SPI ISR fires and raises 0x00 to 0xFB (PendSV hasn't fired, so 0x00 is s= till current task), but Change_Priority does not move it up in the queue (t= he faulty assumption in the above comment), so the ready queue is then 0xC8= /0xC8, 0xFB/0x00. 6. Insert is called with the 0x50 task, so the ready queue is then 0xC8/0xC= 8, 0xFB/0x00, 0x50/0x50. 7. SPI ISR calls Change_Priority to lower current task, which puts 0x50 at = the head (Change_Priority assigns Thread.Next to the head, and 0x00's "Next= " is 0x50). This causes 0xC8 to be thrown away, leaving the order at 0x50/= 0x50, 0x00/0x00. 8. 0x50 is run, followed by Extract, leaving only 0x00/0x00 on the queue. Regards, Patrick