Lu,

il y avait bien un bug dans le classement de la liste. Un élément
n'était jamais inséré en tete de liste, sauf lorsque la liste est
vide.

Du coup si on fait deux add_event() et que le 2e a une priorité plus
forte, il sera qd meme executé en 1er.

Le patch corrigeant le pb est attaché.

Olivier.

PS: je te mets un bon 19.5/20 pour ton exemple récursif sur la
fonction main() qui permet une incompréhension totale du code :)




On Sun, Sep 07, 2008 at 06:05:01PM +0900, tof wrote:
>
>
> Salut
>
>
> j'ai trouve un pti bug du scheduler :
> la prio n est pas prise en compte correctement selon l'ordre d'init....
> si on ajoute une fonction de haute prio apres avoir ajoute celle de  
> basse prio, la fonction de haute prio est bloquee pendant l'execution de  
> celle de basse prio....
>
> j'avoue que je n ai pas compris pourquoi ca ne fonctionne pas, en  
> parcourant le code du scheduler...
>
> voici donc un ptit bout de code qui met en evidence le bug. (pour ceux  
> qui n ont pas de HW sous la main, le resultat est dans le log)
> normalement les fonctions sont classes avant exec dans une table...
>
> oliv as tu une idee ?
> au pire on pourrait classer les fonctions dans une table reclassee a  
> chaque ajout, non ?
> ca eviterait de faire du classement en int periodique ....
>
> a++
>
>
> christoph
>

> /*  
>  *  Copyright Droids Corporation, Microb Technology, Eirbot (2005)
>  * 
>  *  This program is free software; you can redistribute it and/or modify
>  *  it under the terms of the GNU General Public License as published by
>  *  the Free Software Foundation; either version 2 of the License, or
>  *  (at your option) any later version.
>  *
>  *  This program is distributed in the hope that it will be useful,
>  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  *  GNU General Public License for more details.
>  *
>  *  You should have received a copy of the GNU General Public License
>  *  along with this program; if not, write to the Free Software
>  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>  *
>  *  Revision : $Id: main.c,v 1.15.8.5 2008-02-11 10:40:57 tof Exp $
>  *
>  */
> #include <uart.h>
> #include <aversive/wait.h>
> 
> #include <stdio.h>
> 
> #include <avr/io.h>
> #include <avr/pgmspace.h>  // for printf_P and PSTR
> 
> #include <stdio.h>
> #include <scheduler.h>
> 
> 
> volatile int high_cpt;
> volatile int  low_cpt;
> 
> volatile int  sucess;
> 
> 
> // high prio : counts
> void high_prio_func(void * dummy)
> {
>       high_cpt++;
> }
> 
> 
> // low prio : displays, and waits a very long time
> void low_prio_func(void * dummy)
> {
>       printf("h_prio_int count=%i\n", high_cpt);
>       low_cpt++;
>       wait_ms(1000);
> }
> 
> 
> 
> int main(void)
> {
>       
>       uart_init();  
>       fdevopen(uart0_dev_send, NULL);
>       scheduler_init();
>       
>       if (sucess)
>               {
>               printf("\nThis test succeeds\n");
>               printf("the counter increments a lot between each low prio\n");
>               printf("the high prio sched is initialized first\n\n");
>               
>               /* working init */
>               scheduler_add_periodical_event_priority(high_prio_func, NULL, 
> 1, 200); // high prio, 1 tick
>               scheduler_add_periodical_event_priority( low_prio_func, NULL, 
> 1, 100); // low  prio, 1 tick
>               }
>       else
>               {
>               printf("\nThis test fails\n");
>               printf("the counter increments ONLY ONCE between each low 
> prio\n");
>               printf("the hlow prio sched is initialized first\n\n");
>               
>               /* this init leads to failure of the prio system */
>               scheduler_add_periodical_event_priority( low_prio_func, NULL, 
> 1, 100); // low  prio, 1 tick
>               scheduler_add_periodical_event_priority(high_prio_func, NULL, 
> 1, 200); // high prio, 1 tick
>               }
>       
>       
>       /** autorize interrupts */
>       sei();
>       
>       
>       
>   while(1)
>       {
>               sei();
>               nop();  /** autorize interrupts */
>               cli();
>               
>               // restart after 10 low prio ints.
>               if( low_cpt >= 10)
>                       {
>                       high_cpt =0; // rst counters
>                       low_cpt  =0;
>                       sucess = !sucess; // invert sucess
>                       
>                       main(); // restart
>                       }
>               
>       };
>       
>   
>       return 0;
>       
> }
> 
> 


> Terminal log file
> Date: 07/09/2008 - 10:51:43
> -----------------------------------------------
> 
> This test fails
> the counter increments ONLY ONCE between each low prio
> the hlow prio sched is initialized first
> 
> h_prio_int count=0
> h_prio_int count=1
> h_prio_int count=2
> h_prio_int count=3
> h_prio_int count=4
> h_prio_int count=5
> h_prio_int count=6
> h_prio_int count=7
> h_prio_int count=8
> h_prio_int count=9
> 
> This test succeeds
> the counter increments a lot between each low prio
> the high prio sched is initialized first
> 
> h_prio_int count=1
> h_prio_int count=9392
> h_prio_int count=18777
> h_prio_int count=28164
> h_prio_int count=-27985
> h_prio_int count=-18596
> h_prio_int count=-9207
> h_prio_int count=180
> h_prio_int count=9563
> h_prio_int count=18948
> 
> This test fails
> the counter increments ONLY ONCE between each low prio
> the hlow prio sched is initialized first
> 
> h_prio_int count=0
> h_prio_int count=1
> h_prio_int count=2
> h_prio_int count=3
> h_prio_int count=4
> h_prio_int count=5
> h_prio_int count=6
> h_prio_int count=7
> h_prio_int count=8
> h_prio_int count=9
> 
> This test succeeds
> the counter increments a lot between each low prio
> the high prio sched is initialized first
> 
> h_prio_int count=1
> h_prio_int count=9392
> h_prio_int count=18777
> h_prio_int count=28164
> h_prio_int count=-27985
> h_prio_int count=-18596
> h_prio_int count=-9207
> h_prio_int count=180
> h_prio_int count=9563
> h_prio_int count=18948
> 
> This test fails
> the counter increments ONLY ONCE between each low prio
> the hlow prio sched is initialized first
> 
> h_prio_int count=0
> h_prio_int count=1
> 
> -----------------------------------------------
> Date: 07/09/2008 - 10:52:34
> End log file

> _______________________________________________
> Avr-list mailing list
> Avr-list@droids-corp.org
> CVSWEB : http://cvsweb.droids-corp.org/cgi-bin/viewcvs.cgi/aversive
> WIKI : http://wiki.droids-corp.org/index.php/Aversive
> DOXYGEN : http://zer0.droids-corp.org/doxygen_aversive/html/
> BUGZILLA : http://bugzilla.droids-corp.org
> COMMIT LOGS : http://zer0.droids-corp.org/aversive_commitlog
--- aversive-1.1_orig/modules/base/scheduler/scheduler_interrupt.c	2008-01-08 21:05:02.000000000 +0100
+++ aversive-1.1/modules/base/scheduler/scheduler_interrupt.c	2008-09-08 13:47:54.000000000 +0200
@@ -109,8 +109,15 @@ scheduler_interrupt(void)
 		   this should be quite fast since the list is
 		   expected to be small. */
 
+		e = SLIST_FIRST(&event_list);
 		/* easy case : list is empty */
-		if (SLIST_FIRST(&event_list) == NULL) {
+		if (e == NULL) {
+			SLIST_INSERT_HEAD(&event_list, &g_tab_event[i], next);
+			continue;
+		}
+
+		/* insert at head if it's the event with highest prio */
+		if (g_tab_event[i].priority >= e->priority) {
 			SLIST_INSERT_HEAD(&event_list, &g_tab_event[i], next);
 			continue;
 		}
_______________________________________________
Avr-list mailing list
Avr-list@droids-corp.org
CVSWEB : http://cvsweb.droids-corp.org/cgi-bin/viewcvs.cgi/aversive
WIKI : http://wiki.droids-corp.org/index.php/Aversive
DOXYGEN : http://zer0.droids-corp.org/doxygen_aversive/html/
BUGZILLA : http://bugzilla.droids-corp.org
COMMIT LOGS : http://zer0.droids-corp.org/aversive_commitlog

Répondre à