Un coup de main pour trouver la raison de 100% de conso du processeur

Un coup de main pour trouver la raison de 100% de conso du processeur - Ada - Programmation

Marsh Posté le 26-11-2010 à 12:04:03    

Bonjour, merci pour votre aide.
J'écris actuellement un petit programme pour piloter une instrument MIDI mais qui malheureusement consomme 100% des ressource du processeur.
J'ai révisé mon code et ai trouvé une cause mais il en reste.
 
Donc, cette consommation survient à la création d'un tache qui lit sur le port MIDI, via un binding C vers la bibliothèque portmidi, dont voici le l'implémentation (de la tache) avec Ada.

Code :
  1. task type T_Input_Driver(Input_address : Address_Access) is
  2.         entry Halt;
  3.      end T_Input_Driver;
  4.  
  5.      task body T_Input_Driver is
  6.  
  7.         task type T_Input(Input_address : Address_Access) is
  8.            entry Initialize;
  9.            entry Send(Message : out Interfaces.C.Long);
  10.         end T_Input;
  11.         task body T_Input is
  12.            Pm_Event : PmEvent;
  13.         begin
  14.  
  15.            accept Initialize;
  16.            loop
  17.               if Input_Address /= null then
  18.                  Put_Line("Reading input" );
  19.                  Pm_Event.Message := Read_handler(Input_address.All);
  20.                  Put_Line("Sending input" );
  21.                  accept Send(Message : out Interfaces.C.Long) do
  22.                     Message := Pm_Event.Message;
  23.                  end Send;
  24.               else
  25.                  delay 1.0;
  26.               end if;
  27.            end loop;
  28.         end T_Input;
  29.  
  30.         The_Chord :  T_Chord(1..24);
  31.         The_Status : T_Status;
  32.         Step_Time : Time := clock;
  33.         Step_Length : Duration := 0.1;
  34.         Index : Natural := 0;
  35.         Message : Interfaces.C.Long;
  36.         Input : T_Input(Input_Address);
  37.         End_Of_Task : Boolean := False;
  38.      begin
  39.  
  40.         Input.Initialize;
  41.         Put_Line("Initialize input" );
  42.         while not End_Of_Task loop
  43.            select
  44.               accept Halt do
  45.                  End_Of_Task := True;
  46.               end Halt;
  47.            else
  48.               null;
  49.            end select;
  50.            select
  51.               Input.Send(Message);
  52.               Put_Line("Receive message" );
  53.               The_Status := Status(Message);
  54.               case The_Status is
  55.                  when Noteon =>
  56.                     if Clock < Step_Time then
  57.                        if Index < 5 then
  58.                           Index := Index + 1;;
  59.                           The_Chord(Index) :=
  60.                             (T_value'Value("16#" & data1(Message) & '#'),
  61.                              T_value'Value("16#" & data2(Message) & '#' ),
  62.                              0);
  63.                        end if;
  64.                     else
  65.                        if Index /= 0 then
  66.                           T_MidiCtrl.Receive(The_Chord(1..Index), Channel(Message));
  67.                           Index := 0;
  68.                        end if;
  69.                        Index := 1;
  70.                        The_Chord(Index) := (T_value'Value("16#" & data1(Message) & '#'),
  71.                                             T_value'Value("16#" & data2(Message) & '#' ),
  72.                                             0);
  73.                        Step_Time := Clock + 0.125;
  74.                     end if;
  75.                  when Noteoff =>
  76.                     null;
  77.                  when others =>
  78.                     T_MidiCtrl.Receive(Message);
  79.               end case;
  80.            or
  81.               delay 0.1;
  82.               if Index /= 0 then
  83.                  T_MidiCtrl.Receive(The_Chord(1..Index), Channel(message));
  84.                  Index := 0;
  85.               end if;
  86.            end select;
  87.         end loop;
  88.         abort Input;
  89.      end T_Input_Driver;


 
Je ne comprend pas, vraiment, je suis dérouté. Au cas où, voici le lien sur les sources+bin pour linux, avec Ada, Gtkada, trois bout de langage C := El-Softare.tar.gz
Malheureusement, je n'ai pas encore produit de documentation (pas taper).
La tache T_Input_Driver est déclaré dans le fichier src/lib/MidiSurf/el-instrument.adb dans le corps de la tache T_MidiCtrl.
Si vous avez du temps, l'oeil, merci pour votre aide.

Reply

Marsh Posté le 26-11-2010 à 12:04:03   

Reply

Marsh Posté le 26-11-2010 à 12:45:30    

Bonjour,
Bon je suis pas doué avec le Ada, mais ligne 17, c'est quoi? tu testes si le parametre est nul ou s'il y a quelque chose dans le buffer?
Si tu teste juste si le paramètre est null tu essaie de lire son contenu en boucle ->occupation a 100% ?
En général on teste s'il y a des donnée à lire et en fonction de ce test on fait un delay...
(enfin si j'ai bien compris ton code)


Message édité par breizhbugs le 26-11-2010 à 12:46:23

---------------
Seul Google le sait...
Reply

Marsh Posté le 26-11-2010 à 12:56:29    

bonjour breizhbugs, j'ai commenté ce petit bout de code.

Code :
  1. if Input_Address /= null then                                          -- si l'adresse n'est pas nulle,
  2.   Put_Line("Reading input" );
  3.   Pm_Event.Message := Read_handler(Input_address.All);   -- je lis à l'adresse, ici on devrais s'arrêter si il n'y a pas de donnée en sortie à l'adresse.
  4.   Put_Line("Sending input" );
  5.   accept Send(Message : out Interfaces.C.Long) do           -- j'accepte le lecture du buffer Pm_Event. Qui est appelé en continue.
  6.        Message := Pm_Event.Message;
  7.   end Send;
  8. else                                                                             -- si l'adresse est null, j'attends 1 seconde.
  9.  delay 1.0;
  10. end if;


Si ça venait de la, j'aurais un listing de "Reading input" et de "Sending input", c'est pas le cas.
Merci en tout cas.

Reply

Marsh Posté le 26-11-2010 à 14:55:28    

Et en mettant des put_line un peu partout tu verrais ou ca boucle trop vite?


---------------
Seul Google le sait...
Reply

Marsh Posté le 26-11-2010 à 19:03:51    

je pense que ça viens de read_handler, c'est une petite fonction C qui lit l'entrée Midi en boucle.

Reply

Marsh Posté le 26-11-2010 à 19:33:25    

Rho ! Oui, c'est ça mais je n'arrive pas à andiguer le phénomène...
 
Est-ce que t'es meilleur en C breizhbugs ?
 
 
Mon bout de code C, j'ai placé des usleep, mais rien à faire. ça consomme encore.
 

Code :
  1. #include "unistd.h"
  2. #include "portmidi.h"
  3. #include "porttime.h"
  4. #include "stdio.h"
  5.  
  6. #define INPUT_BUFFER_SIZE 100
  7. #define OUTPUT_BUFFER_SIZE 0
  8. #define DRIVER_INFO NULL
  9. #define TIME_PROC ((long (*)(void *)) Pt_Time)
  10. #define TIME_INFO NULL
  11. #define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
  12.  
  13.  
  14.  
  15. long Read_Handler(long midi) {
  16.  PmError status, length;
  17.  PmEvent buffer[1];
  18.  int i = 0;
  19.  int num = 1;
  20.    /* It is recommended to start timer before Midi; otherwise, PortMidi may                                                                                                                                        
  21.       start the timer with its (default) parameters                                                                                                                                                                
  22.     */
  23.  /*TIME_START;*/
  24.  
  25.  /* open input device                                                                                                                                                                                              
  26.    Pm_OpenInput(,                                                                                                                                                                                                  
  27.                 i,                                                                                                                                                                                                  
  28.                 DRIVER_INFO,                                                                                                                                                                                        
  29.                 INPUT_BUFFER_SIZE,                                                                                                                                                                                  
  30.                 TIME_PROC,                                                                                                                                                                                          
  31.                 TIME_INFO);*/
  32.  
  33.    /*printf("Midi Input opened. Reading %d Midi messages...\n",num);*/
  34.    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
  35.    /* empty the buffer after setting filter, just in case anything                                                                                                                                                  
  36.       got through */
  37.    while (Pm_Poll(midi)) {
  38.        Pm_Read(midi, buffer, 1);
  39.        usleep(0.05);
  40.    }
  41.    /* now start paying attention to messages */
  42.    i = 0; /* count messages as they arrive */
  43.    buffer[0].message = 0;
  44.    while (i < num) {
  45.        status = Pm_Poll(midi);
  46.        if (status == TRUE) {
  47.            length = Pm_Read(midi,buffer, 1);
  48.            if (length > 0)
  49.              i++;
  50.        }
  51.        usleep(0.05);
  52.    }
  53.  
  54.    /* close device (this not explicitly needed in most implementations) */
  55.    /*printf("ready to close..." );*/
  56.  
  57.    /*Pm_Close(midi);*/
  58.    /*printf("done closing..." );*/
  59.    return buffer[0].message;
  60. }


Message édité par Profil supprimé le 26-11-2010 à 19:33:48
Reply

Marsh Posté le 26-11-2010 à 20:05:39    

t'es sur que usleep prends des nombre a virgule? http://www.linux-kheops.com/doc/ma [...] eep.3.html
 
mets un temps genre 100 millisecondes...


---------------
Seul Google le sait...
Reply

Marsh Posté le 26-11-2010 à 20:23:15    

:lol: je suis un fou....
 
Merci breizhbugs. Ca marche impec !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed