Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » KhiCAS, add-in calcul formel pour Graph 90+e et 35eii
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

KhiCAS, add-in calcul formel pour Graph 90+e et 35eii

Posté le 15/07/2018 12:09

KhiCAS est le portage de Xcas pour Casio Graph 90+e et 35eii. En résumé, il transforme votre calculatrice en calculatrice CAS (ce qui en fait de la 35eii la calculatrice CAS la moins chère du marché!), programmable en Python (soit avec MicroPython, soit en syntaxe Python dans Xcas).
Documentation
Version complète pour Graph 90 Fichier g3a et Fichier complémentaire (attention pour l'émulateur il faut utiliser ces fichiers g3a et complément).
Version courte pour Graph 90 Fichier g3a ou pour Graph 35eii Fichier g1a : certaines fonctions de Xcas ne sont pas disponibles (géométrie, moteur de rendu 3d, tableur, certaines commandes Xcas manquent, pas d'interpréteur MicroPython)
Video sur des exercices niveau lycee


Précédente 1, 2, 3 ··· 6, 7, 8, 9, 10 Suivante
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 02/09/2022 14:34 | #


Sur la question de l'overclock, il y a certainement un probleme avec clock_set_speed(5);
Lorsque je lance ptune et que je fais F5, je peux lancer KhiCAS avec overclock (le code clock_set_speed(5) s'execute sans probleme). Par contre ptune F1 (normal) puis KhiCAS avec overclock crashe. Symptome: l'ecran devient noir puis ca reboote au bout de quelques secondes.
Slyvtt Hors ligne Community Manager Points: 834 Défis: 0 Message

Citer : Posté le 02/09/2022 14:54 | #


Bernard,

j'ai regardé dans le code de gint : https://gitea.planet-casio.com/Lephenixnoir/gint/src/branch/master/src/cpg/overclock.c les valeurs des paramètres pour les différents niveaux d'overclock.

J'ai comparé avec la première mouture que j'avais utilisé sur Outrun (beaucoup) à la fois sur CG20 et sur la G90 sans problème et que tu peux trouver ici : https://gitea.planet-casio.com/Slyvtt/OutRun/src/branch/master/src/clock.cc

Je ne vois rien qui cloche sur les valeurs des paramètres, en particulier pour le mode F5. Je sais que tu utilises une version "ré-écrite" de la partie overclock pour ta toolchain. J'avais vérifié il y avait quelques temps sans non plus voir de soucis, mais peut être devrais tu re-checker en comparant avec les data de gint/outrun. C'est le genre de chose où un œil "externe" peut faire toute la différence.

J'ai depuis réécrit Outrun pour utiliser le module de gint, je n'ai pas eu de plantage/crash. Il y a peut être des choses qui interfèrent entre elles et qui amènent au crash.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 02/09/2022 15:29 | #


ce qui est encore plus etonnant dans l'histoire, c'est que ce matin ca marchait sur cette meme calculatrice.
Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 02/09/2022 18:13 | #


1/ peut-on faire un backtrace sur le cross-gdb avec l'emulateur lorsque la fenetre de crash apparait? Sur PC, je fais bt dans gdb et je peux voir les frames appelant le code qui crashe

Si tu gardes les symboles de debug et les unwind tables ça devrait être possible. Est-ce que l'ELF que tu utilises pour debugger a les sections de debug (en plus des symboles) ? Je demande parce que je me souviens t'avoir suggéré comme optimisation de taille de les supprimer, et que tu n'avais rapporté aucun changement, suggérant que tu ne les as jamais eues.

2/ peut-on faire un output vers le cross-gdb sh3? Avec le cross-debugger arm et firebird-emu sur nspire, ca marche et c'est tres utile pour visualiser des giac::gen et des giac::vecteur parce que j'ai une fonction membre dbgprint() pour voir les valeurs de maniere comprehensible.

Ça j'admets ne pas savoir comment ça marche ; je laisse Redoste estimer si c'est possible.

Lorsque je lance ptune et que je fais F5, je peux lancer KhiCAS avec overclock (le code clock_set_speed(5) s'execute sans probleme). Par contre ptune F1 (normal) puis KhiCAS avec overclock crashe. Symptome: l'ecran devient noir puis ca reboote au bout de quelques secondes.

Aha, enfin tu peux reproduire ! Je peux avoir le g3a correspondant pour tester moi-même ? Si possible les sources qui vont avec.
Redoste Hors ligne Membre Points: 42 Défis: 0 Message

Citer : Posté le 02/09/2022 20:06 | #


Lephenixnoir a écrit :
2/ peut-on faire un output vers le cross-gdb sh3? Avec le cross-debugger arm et firebird-emu sur nspire, ca marche et c'est tres utile pour visualiser des giac::gen et des giac::vecteur parce que j'ai une fonction membre dbgprint() pour voir les valeurs de maniere comprehensible.

Ça j'admets ne pas savoir comment ça marche ; je laisse Redoste estimer si c'est possible.

Je ne suis pas sûr de comprendre de quoi tu parles mais si je ne me trompe pas tu voudrais pouvoir print dans la console de GDB directement depuis l'émulateur. Ça ne me semble pas possible car le protocole GDB n'a pas de commande le permettant à ma connaissance.

En revanche j'ai implémenté quelque chose qui s'en apparente, si tu écris sur le port série de la calculatrice (i.e. le port jack 3-pin), cela sera réécris sur le stderr de l’émulateur, comme expliqué dans ce post.

Faire fonctionner le port série peut être un peu tricky en fonction du setup mais il ne me semble pas que tu utilises gint, si tu as accès aux syscalls de l'OS et que tu veux faire ça bien Serial_Open et Serial_Write devraient suffire.
Si ce n'est pas possible, tu peux juste écrire sur le registre SCFTDR à 0x0441000c car fxCG50gdb ignore complètement l'état du contrôleur série et fait juste un coup de fputc(3) à chaque écriture dans le registre.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 02/09/2022 20:32 | #


Je ne sais pas en fait, mon Makefile a bien du -g dans CXXFLAGS et LDFLAGS, mais sh3eb-elf-objdump -g khicas.elf
me renvoie seulement khicas.elf: file format elf32-sh

CXXFLAGS = -Wno-narrowing -Wno-write-strings -g -Os -mb -m4a-nofpu  -mhitachi -std=c++11 -fpermissive -fno-use-cxa-atexit -fno-threadsafe-statics -fno-strict-aliasing -fno-exceptions -DHAVE_CONFIG_H -DTIMEOUT -DRELEASE  -I. -I/home/parisse/casiolocal/include/ustl -DFILEICON -DKMALLOC  -DGINT_MALLOC -DTURTLETAB -DMICROPY_LIB -DCONFIG_BIGNUM -DCONFIG_VERSION=\"2020-11-08\"

%.o: %.cc
    $(CXX) $(CXXFLAGS) -c $<
...
khicas.elf: $(CAS_OBJS) $(GUI_OBJS) khelpfr.o catalogfr.o prizm.ld
    $(CXX) $(LDFLAGS) -Wl,-Map=khicas.map catalogfr.o  $(CAS_OBJS) khelpfr.o $(GUI_OBJS) $(LIBS) -o $@
    sh3eb-elf-objdump -C -t khicas.elf | sort > dump_t



L'archive https://www-fourier.univ-grenoble-alpes.fr/~parisse/casio/giacbf.tgz contient le source et un zip avec les g3a correspondants.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 02/09/2022 22:19 | #


Merci Redoste, j'ai mis ca en laissant le port serie ouvert

  const char * gen::dbgprint() const {
    if (Serial_IsOpen() != 1) {
      unsigned char mode[6] = {0, 5, 0, 0, 0, 0};
      Serial_Open(mode);
    }
    string S=this->print(context0);      
    Serial_Write((unsigned char *)S.c_str(), S.size());
    return "";
    // Serial_Close(1);
  }  

mais ca n'a pas l'air de fonctionner quand je fais call g.dbgprint()

Program received signal SIGTRAP, Trace/breakpoint trap.
giac::gen::dbgprint (this=0x881dfd04) at kgen.cc:12733
12733      const char * gen::dbgprint() const {
(gdb) The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(giac::gen::dbgprint() const) will be abandoned.
When the function is done executing, GDB will silently stop.

je peux alors executer le code de dbgprint pas a pas, mais rien ne s'affiche dans la console du cross-debugger et ca interagit mal avec l'historique de khicas. Peut-etre que je n'ai pas une DLL de debug a jour, ou puis-je en recuperer une?
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 03/09/2022 08:13 | #


Ce matin ma calculatrice remarche normalement en overclock, je ne sais pas pourquoi! Est-ce que la fragmentation du systeme de fichiers pourrait avoir une influence et dans ce cas faudrait-il ajouter un delai avant/apres lecture du 2eme morceau de l'addin?
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 03/09/2022 16:13 | #


A force de faire des essais, j'ai reuni quelques infos supplementaires. D'abord contrairement a ce que je pensais, je n'ai jamais ete dans la situation ou j'utilisais le malloc systeme seul, car j'initialisais toujours une 2eme arene en 0x8c480000 de taille 512K et c'est certainement pour cela que le crash se produisait plus tard qu'en utilisant la 1ere arene de taille 200K environ. Du coup je commence a me demander s'il n'y a pas un probleme du cote de kmalloc/kfree. En observant quelques valeurs d'allocation memoire au debugger quand on calcule mon integrale, il apparait que les allocations se font a des adresses de plus en plus elevees , comme si la memoire n'etait pas rendue ou plutot comme si l'allocateur n'arrivait pas a allouer a nouveau un bloc rendu. Ce n'est pas systematique, parfois il y arrive. Mais ce n'est pas normal qu'il ait autant besoin de memoire car l'ancien addin khicas en 1 morceau qui utilise l'allocation systeme arrive a calculer l'integrale avec 128K de heap.
De plus le crash semble se produire au moment precis ou la zone memoire allouee juste avant est a la limite superieure de l'arene. Il n'y a pas de lancement de recherche de zone libre dans la 2eme arene. Donc il y a peut-etre un probleme dans la recherche d'une zone libre dans l'arene existante lorsqu'on atteint le haut de la zone (et potentiellement avant). Je vais regarder avec cross-gdb, j'ai recompile la libc et kmalloc/arena* avec -g.
Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 03/09/2022 16:30 | #


(...) il apparait que les allocations se font a des adresses de plus en plus elevees , comme si la memoire n'etait pas rendue ou plutot comme si l'allocateur n'arrivait pas a allouer a nouveau un bloc rendu.

C'est certainement suspect. L'allocateur réutilise évidemment la mémoire, donc pour que ça échoue il faudrait soit qu'elle ne soit pas rendue (irréaliste) soit qu'elle revienne très fragmentée (improbable). Hmm...

Donc il y a peut-etre un probleme dans la recherche d'une zone libre dans l'arene existante lorsqu'on atteint le haut de la zone (et potentiellement avant).

Ça ce serait possible dans la mesure où en pratique on atteint rarement la fin de la première arène donc ce n'est pas testé autant. Côté positif, toute cette partie de l'allocateur tient dans 100 lignes de code donc ça devrait pas être dur à débusquer.

Note un piège qui est que kmalloc() doit être capable de retrouver l'arène à laquelle chaque pointeur appartient pour les libérer dans kfree(). Pour ça, les bornes arena.start et arena.end sont utilisées, sauf pour le tas de l'OS (dont l'adresse n'est pas fixe/connue), pour lequel il y a NULL/NULL, et qui est testé en dernier comme cas par défaut. D'ailleurs peut-être que ça plante quand kmalloc atteint le tas de l'OS ?
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 03/09/2022 16:48 | #


Non, parce que ca plante a la fin de la 1ere arene alors que la 2eme est accessible et encore vide.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 03/09/2022 21:26 | #


Quelques infos apres une bonne dizaine de minutes d'execution avec des points d'arrets dans arena_gint.c gint_malloc et gint_free. D'abord le nombre de free est a peu pres le meme que le nombre de malloc (je fais par exemple c 200 sur chaque point d'arret et je regarde ou ca s'arrete en premier et combien de c il faut faire pour egaliser). Voici par exemple ce que j'ai si je fais p *index dans malloc:

Breakpoint 7, gint_malloc (size=20, data=0x812fb28 <malloc_heap>) at arena_gint.c:239
239        size = round(size);
(gdb) p *index
$7 = {classes = {0x8139958 <malloc_heap+40496>, 0x813a2e4 <malloc_heap+42940>, 0x813a2a4 <malloc_heap+42876>, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x81397bc <malloc_heap+40084>, 0x0, 0x0, 0x8132a5c <malloc_heap+12084>, 0x813a5e8 <malloc_heap+43712>}, stats = 0x812fb6c <malloc_heap+68>}

Environ un millier de breakpoints plus tard

$9 = {classes = {0x813b2a0 <malloc_heap+46968>, 0x81382f4 <malloc_heap+34764>, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x813b3b0 <malloc_heap+47240>}, stats = 0x812fb6c <malloc_heap+68>}

Vers la fin du calcul de arclen([3cos(x)-cos(3x),3sin(x)-sin(3x)],x,0,pi):

$12 = {classes = {0x0, 0x813ace8 <malloc_heap+45504>, 0x0, 0x813afec <malloc_heap+46276>, 0x0, 0x0, 0x0, 0x813af84 <malloc_heap+46172>, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x813b088 <malloc_heap+46432>, 0x813c540 <malloc_heap+51736>}, stats = 0x812fb6c <malloc_heap+68>}

Beaucoup d'allocations de 8, 16 et 20 octets.
Le nombre d'allocations/free est gigantesque, ca doit depasser la dizaine de milliers. Du coup l'hypothese de la fragmentation qui fait petit a petit grimper l'adresse moyenne des allocations est plausible. Il n'y a plus d'adresse base dans *index, je ne sais pas si c'est normal.

Si on essaie avec un calcul plus complexe (arclen jusqu'a 2pi par exemple) on a un crash, mon impression c'est que le crash se produit lorsqu'il n'y a plus de place dans la 1ere arene, en tout cas je n'ai pas vu d'allocation dans la 2eme arene (je ne sais pas si on peut mettre un point d'arret conditionnel pour tester).

Faute de mieux, j'envisage de neutraliser la 1ere arene de 200K, et de renvoyer vers le menu principal avec un message memoire pleine si un new me renvoie un pointeur proche du haut de la 2eme arene de 512K. Ceci afin d'eviter le crash et permettre a l'utilisateur de lancer n'importe quelle autre appli puis revenir a KhiCAS continuer ses calculs avec une memoire vierge.
Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 03/09/2022 21:36 | #


Il n'y a plus d'adresse base dans *index, je ne sais pas si c'est normal.

Oui c'est normal ça veut dire qu'il n'y a pas de blocs dans la liste concernée. En fait, si tu regardes la dernière liste :

$12 = {classes = {0x0, 0x813ace8 <malloc_heap+45504>, 0x0, 0x813afec <malloc_heap+46276>, 0x0, 0x0, 0x0, 0x813af84 <malloc_heap+46172>, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x813b088 <malloc_heap+46432>, 0x813c540 <malloc_heap+51736>}, stats = 0x812fb6c <malloc_heap+68>}

Chaque pointeur dans classes est le début d'une liste de blocs d'une taille donnée : 8, 12, 16, 20, ..., 60, 64--252, ≥256. Le pointeur est nul quand il n'y a aucun bloc libre de la taille indiquée. Ici, il y a donc des blocs de 12 octets, 20 octets, 36 octets, 64--252 octets, et ≥256 octets. L'absence d'un grand nombre de petits blocs alloués souvent (16/20 octets) et la présence de gros blocs démontre que l'allocateur est plutôt en "bonne santé", ie. que les blocs libérés ont bien été fusionnés entre eux. Bien sûr il pourrait y avoir des milliers de blocs de 12, il faudrait voir plus en détail.

N'oublie pas que la fragmentation résulte normalement d'un schéma d'allocation où des blocs de courte durée de vie sont mélangés avec des blocs de longue durée de vie. Si tu alloues des milliers de blocs consécutifs mais que tu les libères à peu près tous en même temps alors il n'y a pas de trou à la fin.

(...) en tout cas je n'ai pas vu d'allocation dans la 2eme arene (je ne sais pas si on peut mettre un point d'arret conditionnel pour tester).

Tu peux mettre un breakpoint à cet endroit pour attraper ce cas.

Faute de mieux, j'envisage de neutraliser la 1ere arene de 200K, et de renvoyer vers le menu principal avec un message memoire pleine si un new me renvoie un pointeur proche du haut de la 2eme arene de 512K. Ceci afin d'eviter le crash et permettre a l'utilisateur de lancer n'importe quelle autre appli puis revenir a KhiCAS continuer ses calculs avec une memoire vierge.

Argh, ça pique. Désolé pour les problèmes, j'admets ne pas voir comment on en arrive là.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 03/09/2022 22:36 | #


Je viens de le faire (je veux eviter que les telechargements de la rentree ne creent des desillusions!) et en fait je ne pense pas que ce soit si genant. En utilisation normale, on peut faire pas mal de calculs de suite avec 512K meme avec une petite fuite de memoire disponible, en comparaison les calculs que je teste sont assez exigeants (ils durent plusieurs dizaines de seconde avec beaucoup d'allocations memoire). Je vais encore tester, mais la version que j'ai mise a jour ce soir devrait permettre de passer un exam ou une seance de TD de 1h30 sans avoir besoin de quitter. Et quitter pour revenir n'est pas une si grande contrainte, contrairement a perdre son travail s'il y a un crash...
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 04/09/2022 11:13 | #


En attendant le fin mot de l'histoire (qui risque de prendre du temps), j'ai mis le tas micropython dans les 200K ou j'avais ma 1ere arene, et les 512K de l'autre arene pour Xcas.
Une possible amelioration pour eviter la fragmentation, au moins au debut, ce serait de reserver des tableaux en RAM statique pour un nombre fixe d'alloc de <= 8 octets, puis peut-etre aussi pour 12, 16, 20, 24?
Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 04/09/2022 11:26 | #


Une possible amelioration pour eviter la fragmentation, au moins au debut, ce serait de reserver des tableaux en RAM statique pour un nombre fixe d'alloc de <= 8 octets, puis peut-etre aussi pour 12, 16, 20, 24?

Ça pose quand même le problème que du coup tu as plein de blocs de taille 24 qui vont rester inutilisés et ne peuvent même pas être coupés en des allocs de 8. Mais c'est possible, et d'ailleurs tu peux expérimenter directement (sans dépendre de mon temps de réponse) si tu le souhaites, en ajoutant une arène avec la logique de ton choix.

Brièvement, tu peux accomplir ceci en partant de cet exemple minimal. Dans malloc() tu testes si la taille vaut la constante (eg. 8) et tu renvoies NULL sinon. Ensuite tu peux utiliser ton tableau, sachant que tu dois traquer quels blocs sont libres. Dans free() il suffit de noter que le bloc est de nouveau libre. realloc() peut être esquivé en faisant juste un malloc(), une copie et un free().

Comme tu peux le voir c'est ensuite une simple affaire de déclarer les trois fonctions dans le kmalloc_arena_t. Il faut que la zone que tu gères soit continue, donc je conseille de faire une arène par taille/tableau. Par défaut tu a 8 arènes en tout (il t'en reste donc 5), tu peux monter ce total dans kmalloc.h si besoin.

Ah, d'ailleurs en relisant le code je réalise un problème potentiel que j'avais oublié. krealloc() ne réalloue quand dans la même arène. Si la réallocation échoue dans l'arène d'origine, la fonction ne tente pas de réallouer dans une autre arène, ce qui est contre-intuitif. Peut-être que tu as des vecteurs qui dépendent de realloc() et échouent donc quand la première arène est pleine parce que realloc() finit par renvoyer NULL ?
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 04/09/2022 14:32 | #


En fait j'ai essaye de modifier directement dans stdlib.c en utilisant le meme code que celui pour allouer les symboliques et les complexes de Xcas sans passer par malloc. Mais ca echoue et je ne vois pas pourquoi, si jamais tu as une idee, je mets le code ci-dessous.

A propos de realloc, je ne l'appelle jamais directement, mais il semble que la ustl le fait souvent.

Le mystere s'epaissit, parce que j'ai recompile KhiCAS en 2 addins mais en desactivant la gestion des bigfloats de quickjs et la il n'y a pas de fuite memoire (il y a encore des bizarreries ceci dit). Du coup la fuite memoire ne semble pas etre due a de la fragmentation, mais etre une vraie fuite memoire, mais pour le moment je ne vois pas ou.


//#define ALLOCSMALL

/* also define GINT_MALLOC in Makefile, does not work with OFF/ON */
/* #define GINT_MALLOC  */
#ifdef GINT_MALLOC
#include <gint/kmalloc.h>
#else
#ifdef ALLOCSMALL
#undef ALLOCSMALL
#endif
#endif

static inline size_t allocround(size_t size){
  return (size < 8) ? 8 : ((size + 3) & ~3);
}

static inline size_t allocmin(size_t a,size_t b){
  return a<b?a:b;
}

#ifdef ALLOCSMALL

typedef struct  {
  int i1,i2,i3,i4;
} two_int; // 8

typedef struct  {
  int i1,i2,i3,i4;
} four_int ; // 16

typedef struct  {
  int i1,i2,i3,i4,i5,i6;
} six_int; // 24
  
typedef struct  {
  int i1,i2,i3,i4,i5,i6,i7,i8;
} eight_int; // 32
  
// ALLOCA  constants must be multiples of 2*32
#define ALLOC8 32*32
#define ALLOC16 32*32
#define ALLOC24 24*32

static unsigned int freeslot8[ALLOC8/32]={
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};
static unsigned int freeslot16[ALLOC16/32]={
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};
static unsigned int freeslot24[ALLOC24/32]={
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};
static two_int slottab8[ALLOC8];
static four_int slottab16[ALLOC16];
static six_int slottab24[ALLOC24];
  
unsigned freeslotpos(unsigned n){
  unsigned r=1;
  if ( (n<<16)==0 ){
    r+= 16;
    n>>=16;
  }
  if ( (n<<24)==0 ) {
    r+= 8;
    n>>=8;
  }
  if ( (n<<28)==0 ) {
    r+= 4;
    n>>=4;
  }
  if ( (n<<30)==0 ) {
    r+= 2;
    n>>=2;
  }
  r -= n&1;
  return r;
}
  
void * slotalloc(size_t size){
  int i,pos;
  if (size<=8){
    for (i=0;i<ALLOC8/32;){
      if (!(freeslot8[i] || freeslot8[i+1])){
    i+=2;
    continue;
      }
      if (freeslot8[i]){
    pos=freeslotpos(freeslot8[i]);
    freeslot8[i] &= ~(1<<pos);
    return (void *) (slottab8+i*32+pos);
      }
      i++;
      pos=freeslotpos(freeslot8[i]);
      freeslot8[i] &= ~(1<<pos);
      return (void *) (slottab8+i*32+pos);
    }
    return kmalloc(size,NULL);
  }
  if (size<=16){
    for (i=0;i<ALLOC16/32;){
      if (!(freeslot16[i] || freeslot16[i+1])){
    i+=2;
    continue;
      }
      if (freeslot16[i]){
    pos=freeslotpos(freeslot16[i]);
    freeslot16[i] &= ~(1<<pos);
    return (void *) (slottab16+i*32+pos);
      }
      ++i;
      pos=freeslotpos(freeslot16[i]);
      freeslot16[i] &= ~(1<<pos);
      return (void *) (slottab16+i*32+pos);
    }
    return kmalloc(size,NULL);
  }
  if (size<=24){
    for (i=0;i<ALLOC24/32;){
      if (!(freeslot24[i] || freeslot24[i+1])){
    i+=2;
    continue;
      }
      if (freeslot24[i]){
    pos=freeslotpos(freeslot24[i]);
    freeslot24[i] &= ~(1<<pos);
    return (void *) (slottab24+i*32+pos);
      }
      i++;
      pos=freeslotpos(freeslot24[i]);
      freeslot24[i] &= ~(1<<pos);
      return (void *) (slottab24+i*32+pos);
    }
    return kmalloc(size,NULL);
  }
  void * p =  kmalloc(size,NULL);  
  return p;
}  
  
void slotfree(void* obj){
  if ( ((size_t)obj >= (size_t) &slottab8[0]) &&
       ((size_t)obj < (size_t) &slottab8[ALLOC8]) ){
    int pos= ((size_t)obj -((size_t) &slottab8[0]))/sizeof(six_int);
    freeslot8[pos/32] |= (1 << (pos%32));
    return;
  }
  if ( ((size_t)obj>=(size_t) &slottab16[0] ) &&
       ((size_t)obj<(size_t) &slottab16[ALLOC16] ) ){
    int pos= ((size_t)obj -((size_t) &slottab16[0]))/sizeof(four_int);
    freeslot16[pos/32] |= (1 << (pos%32));
    return;
  }
  if ( ((size_t)obj >= (size_t) &slottab24[0]) &&
       ((size_t)obj < (size_t) &slottab24[ALLOC24]) ){
    int pos= ((size_t)obj -((size_t) &slottab24[0]))/sizeof(six_int);
    freeslot24[pos/32] |= (1 << (pos%32));
    return;
  }
  kfree(obj);
}
unsigned hamdist(unsigned val){
  size_t res=0;
  if (!val) return res;
  for (int i=0;i<32;++i){
    res += ((val >>i) & 1);
  }
  return res;
}

size_t slotfreemem(){
  size_t res=0;
  for (int i=0;i<ALLOC8/32;++i){
    res += 16*hamdist(freeslot8[i]);
  }
  for (int i=0;i<ALLOC16/32;++i){
    res += 16*hamdist(freeslot16[i]);
  }
  for (int i=0;i<ALLOC24/32;++i){
    res += 24*hamdist(freeslot24[i]);
  }
  return res;
}
#else // ALLOCSMALL
size_t slotfreemem(){
  return 0;
}
#endif // ALLOCSMALL

void *malloc(size_t sz) {
#ifdef GINT_MALLOC
#ifdef ALLOCSMALL
  return slotalloc(sz);
#else
  return kmalloc(sz, NULL);
#endif
#else
  void * ptr= sys_malloc(sz); // __malloc(size);
  if ( ((size_t) ptr&stack_mask) > stackptr)
    interrupted=ctrl_c=1;
  return ptr;
#endif
}

void *realloc(void *ptr, size_t sz) {
#ifdef GINT_MALLOC
#ifdef ALLOCSMALL
  if (sz==0){
    free(ptr);
    return;
  }
    if ( ((size_t)ptr >= (size_t) &slottab8[0]) &&
     ((size_t)ptr < (size_t) &slottab8[ALLOC8]) ){
      if (sz<=8) return ptr;
      void * newptr=slotalloc(sz);
      slotfree(ptr);
      if (!newptr) return 0;
      memcpy(newptr, ptr, allocmin(8,sz));
      return newptr;
    }
    if ( ((size_t)ptr >= (size_t) &slottab16[0]) &&
     ((size_t)ptr < (size_t) &slottab16[ALLOC16]) ){
      if (sz<=16) return ptr;
      void * newptr=slotalloc(sz);
      slotfree(ptr);
      if (!newptr) return 0;
      memcpy(newptr, ptr, allocmin(16,sz));
      return newptr;
    }
    if ( ((size_t)ptr >= (size_t) &slottab24[0]) &&
     ((size_t)ptr < (size_t) &slottab24[ALLOC24]) ){
      if (sz<=24) return ptr;
      void * newptr=slotalloc(sz);
      slotfree(ptr);
      if (!newptr) return 0;
      memcpy(newptr, ptr, allocmin(24,sz));
      return newptr;
    }
#endif
  return krealloc(ptr, sz);
#else
  ptr=sys_realloc(ptr, sz);    // return __realloc(ptr, newsize);
  if ( ((size_t) ptr&stack_mask) > stackptr)
    interrupted=ctrl_c=1;
  return ptr;
#endif
}

void free(void *ptr) {
#ifdef GINT_MALLOC
#ifdef ALLOCSMALL
  slotfree(ptr);
#else
  kfree(ptr);
#endif
#else
  sys_free(ptr);
#endif
}

Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 04/09/2022 14:44 | #


typedef struct  {
  int i1,i2,i3,i4;
} two_int; // 8

Ta structure de 8 octets fait 16 octets. Et le malloc() renvoie bien slottab8+i*32+pos ie. une structure complète par allocation, donc tu perds la moitié de chaque structure ?

     int pos= ((size_t)obj -((size_t) &slottab8[0]))/sizeof(six_int);
    freeslot8[pos/32] |= (1 << (pos%32));

Probablement le bug, ici tu es dans freeslot8 mais tu divises par sizeof(six_int) donc tu libères la mauvaise entrée.

   for (int i=0;i<ALLOC8/32;++i){
    res += 16*hamdist(freeslot8[i]);
  }

Comme au-dessus du coup, tu comptes 16 octets par objet de taille 8.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 04/09/2022 16:30 | #


Oups, ca m'apprendra a faire du copier-coller trop rapidement, je vais retester...
J'ai fini par trouver la fuite memoire, c'etait du code que j'avais enleve pour l'addin en 1 morceau pour gagner de la place, plus precisement le destructeur des flottants multiprecisions (il n'y en a pas dans l'ancien addin) grrrrr....
Merci mille fois pour ta patience et ta relecture!
Lephenixnoir Hors ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 04/09/2022 16:46 | #


Cool que ça progresse ! Si j'ai bien suivi tu as donc tout réparé jusqu'au crash initial donc plus du tout de souci ?

Si c'est ça alors tant mieux. Faudra que je voie pour l'overlock.
Parisse Hors ligne Membre Points: 374 Défis: 0 Message

Citer : Posté le 04/09/2022 17:01 | #


L'allocation freeslot ne marche toujours pas, mais je laisse tomber pour le moment, la fuite memoire etant rebouchee, kmalloc fait parfaitement l'affaire.
Ca progresse oui, mais j'ai encore des erreurs inexpliquees sur mon calcul d'integrale, je veux dire que ca marche dans certains cas et ca renvoie une erreur dans d'autres cas, un peu comme l'overclock! Pour l'overclock, j'ai rajoute une boite de dialogue en debut d'addin, ce qui laissera la possibilite aux gens de choisir et si ca crashe en overclocke, ils pourront quand meme utiliser xcas.
Précédente 1, 2, 3 ··· 6, 7, 8, 9, 10 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 68 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd