Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1469 connectés 

  FORUM HardWare.fr
  Programmation
  Ada

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

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

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

n°2038634
Profil sup​primé
Posté le 26-11-2010 à 12:04:03  answer
 

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.

mood
Publicité
Posté le 26-11-2010 à 12:04:03  profilanswer
 

n°2038640
breizhbugs
Posté le 26-11-2010 à 12:45:30  profilanswer
 

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...
n°2038645
Profil sup​primé
Posté le 26-11-2010 à 12:56:29  answer
 

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.

n°2038674
breizhbugs
Posté le 26-11-2010 à 14:55:28  profilanswer
 

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


---------------
Seul Google le sait...
n°2038730
Profil sup​primé
Posté le 26-11-2010 à 19:03:51  answer
 

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

n°2038734
Profil sup​primé
Posté le 26-11-2010 à 19:33:25  answer
 

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
n°2038740
breizhbugs
Posté le 26-11-2010 à 20:05:39  profilanswer
 

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...
n°2038743
Profil sup​primé
Posté le 26-11-2010 à 20:23:15  answer
 

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


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Ada

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

 

Sujets relatifs
[C sur µprocesseur] Calcul de bit de paritéProblème de bdd simple mais pas évident à trouver
Trouver quelle appli utilise une ressource / un fichier lockétrouver un nom de programme qui existe pas déjà
Trouver une forme dans une image (réseau de neurones)problème avec main.js
Evaluation de variable globale avant celle du mainBug d'affichage incompréhensible : Espace vide sans raison ?
Header puis bloc occupant 100% du reste de la pageImpossible de trouver l'objet dans la collection correspondant au nom
Plus de sujets relatifs à : Un coup de main pour trouver la raison de 100% de conso du processeur


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR