Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
No more need of these ones...
[simgrid.git] / README.coding
index dd18e22..1f31d9c 100644 (file)
+**
+** Source tree organization
+**
+******************************************************
+
+There is 4 projects in the tree:
+
+ - GROS: no fancy name yet (low-level toolbox: logging, datatypes).
+ - GRAS: Grid Reality And Simulation (message passing API with two
+         implementations allowing to compile programs on top of the
+         simulator or for the real life without code modification)
+ - SURF: Server for the Use of Resource Fictions (the simulator used 
+         in GRAS and more)
+ - AMOK: Advanced Metacomputing Overlay Kit (high level toolbox; Grid
+         application elements such as distributed database, topology
+         discovery service, and so on)
+
+They are all in the same tree because GRAS depends on SURF which depends on
+GRAS (that's the only cycle here, we're not *that* vicious).
+
+The tree is not splited on projects, but on file finality:
+ include/            -> all *public* headers
+ include/gros/*.h    -> one file per module
+ include/gros.h      -> file including all modules headers
+  (same for gras, surf and amok instead of gros)
+  
+ src/Makefile.am     -> main makefile. All projects should fit in only one
+                        library (I mean 2, RL+SG), which is compiled here.
+                       
+                       Since all object.o files are placed here, you should
+                        choose the name of c files carfully to avoid
+                        conflict. 
+                       
+ src/gras/DataDesc                      -> typical project module
+ src/gras/DataDesc/datadesc_interface.h -> visible to any GRAS modules;
+                                           masked to the user and GROS/AMOK/SURF
+ src/gras/DataDesc/datadesc_private.h   -> visible only from this module                                          
+  
+   So, the modules have 3 levels of publicity for their interface. 
+   Private, internal to GRAS, public. Of course, I try to keep as much stuff
+   private as possible.
+  
+ testsuite/ -> The more test the better. 
+               Same organization than src/ and include/
+               Tests are allowed to load some headers of the module they test.
+              All tests should be listed in run_test.in so that they get
+                  run on 'make check'. 
+              They are not listed directly in the check_PROGRAMS part of
+                  the makefile because run_test knows about the gras logging
+                  features and relaunch with full details the failed tests.
+                 
+ examples/ -> Supposed to be copy/pastable by the user, so keep it clear and
+                avoid any kind of trick. In particular, do only include the
+                public headers here.
+
+**
+** Type naming standard
+**
+*****************************************************
+
+It may sound strange, but the type naming convention was source of intense
+discution between da GRAS posse members. The convention we came to may not
+be the best solution, but it has the merit to exist and leave everyone work.
+So please stick to it.
+
+  - ???_t is a valid type (builded with typedef)
+  - s_toto_t is a structure (access to fields with .)
+  - s_toto   is a structure needing 'struct' keyword to be used
+  - e_toto_t is an enum
+  - u_toto_t is an union
+  - u_toto   is an union needing 'union' keyword to be used
+  -   toto_t is an 'object' (struct*)
+  
+Please to not call toto_t something else than an 'object' (ie, something you
+have to call _new and _free on it).
+
+Exemple:
+  typedef struct s_toto {} s_toto_t, *toto_t;
+  typedef enum {} e_toto_t;
+  
+Moreover, only toto_t (and e_toto_t) are public. The rest (mainly s_toto_t)
+is private.
+
+If you see any part of the code not following this convention, this is a
+bug. Please report it (or fix it yourself if you can).
+
 **
 ** Random bits about coding standards and portability
+**
+*****************************************************
 
 MALLOC:
  You must cast the result of malloc on AIX. 
  It's even better to use gras_new when possible.
 
 SIZE_T
+ If possible, avoid size_t and use unsigned long instead. If not,
+
  #include <sys/types.h> in all files manipulating size_t
  do cast it to unsigned long before printing (and use %lu)
  
+PRINTF pointer difference
+ printf ("diff = %ld\n", (long) (pointer2 - pointer1));
   
+
+**             
+** Commenting the source
+**
+****************************************************
+
+Le format pour cela est :
+
+/**                              (très important, la deuxieme étoile)
+ * nomDeFonction:                (faut les deux points)
+ * @param1: blabla               (faut le @ et les deux points, et ca peut
+ *                                courir sur plusieurs lignes)
+ * @param2: blabla
+ *                               (fin des paramètres: ligne vide)
+ * blabla sur la fonction        (autant de lignes que tu veux)
+ */
+
+Si tu met () apres un nom de fonction, il essaye d'ajouter un lien
+automatiquement, il me semble.
+
+
+Ensuite, quand tu fais "make -C doc", il ne se passe rien de particulier ;)
+Avant que ca marche, il faut créer une nouvelle section dans
+doc/gras-sections.txt Attention, on dirait du xml, mais le parseur est
+stupide. Je me suis arraché les cheveux plusieurs heures pour un "<SECTION<"
+
+Tout ce qui n'est pas dans une section se trouve listé dans gras-unused.txt
+Pour éviter que ca ne soit le cas sans pour autant les documenter, place les
+symboles après <SUBSECTION Standard> (regarde tbx_log dans le fichier pour
+un exemple).
+
+Une fois la section crée, un "make -C doc" crée un bout de doc, mais ne
+l'inclue pas dans la documentation finale. Pour cela, il faut éditer le
+fichier gras-docs.sgml (qui est un fichier xml de bon aloi, malgré son
+nom). Il te faut ajouter une entité système dans le prologue (avant "]>")
+style: <!ENTITY tbx-cfg SYSTEM "xml/tbx_cfg.xml">
+Ensuite dans le corps du document, tu colles: &tbx-cfg; et t'es arrivé. Au
+milleu du gras-docs.sgml, y'a un bout de code mort en commentaire. Autant le
+laisser, je nettoyerais un jour, peut etre.
+
+
+Il te faut maintenant mettre un titre long et une description de module.
+Pour cela, édite le fichier "tmpl/<nom_de_section>.sgml". Juste en haut, les
+parties "SECTION Title", "SECTION Short_Description", "SECTION
+Long_Description" et "SECTION See_Also". Pr les deux premiers, faut mettre
+une seule ligne et pas de tags. Pour les autres, il faut faire des
+paragraphes. Donc, tout ce que t'as le droit de mettre dans un <para> passe.
+
+Attention, les fichiers dans doc/xml sont les morceaux prêts à être intégrés
+par gras-doc.sgml. Ils sont donc générés et écrasés à tout bout de champ.
+Mais les fichiers de doc/tmpl (templates) sont aussi partiellement générés.
+Les doc de fonction extraites du code y sont placées, et les modification
+que t'y a fait (titre, desc_courte/longue, voir_aussi) sont préservées,
+normalement.
+
+
+Voila, une fois ceci fait, la doc devrait être bonne. Comme tu peux le voir,
+gtk-doc est bien plus bordelique à utiliser que doxygen (j'utilise souvent
+"make clean all" car il semble manquer des dépendances). Mais je préfere car
+on peut faire exactement ce qu'on veut. Et pis rose bonbon, c'est plus joli
+que bleu triste.
+
+**             
+** Using the logs
+**
+****************************************************
+
+Dans gras, tu ne te contente pas d'écrire des choses à l'écran, mais tu
+écris sur un sujet particulier (notion de canal) des choses d'une gravité
+particulière. Il y a 7 niveaux de gravité.
+ trace: tracer les entrées dans une fonction, retour de fonction
+        (famille de macros XBT_IN/XBT_OUT)
+ debug: pour t'aider à mettre au point le module, potentiellement tres bavard
+ verbose: quelques infos succintes sur les internals du module
+ info: niveau normal, ton de la conversation
+ warning: problème potentiel, mais auquel on a su faire face
+ error: problème qui t'as empêché de faire ton job
+ critical: juste avant de mourir
+
+Quand on compile avec -DNDEBUG (par défaut dans le paquet Debian), tout ce
+qui est '>= verbose' est supprimé au moment de la compilation. Retiré du
+binaire, killé.
+
+Ensuite, tu écris dans un canal particulier. Tous les canaux sont rangés en
+arbre. Il faudrait faire un ptit script qui fouille les sources à la
+recherche des macros XBT_LOG_NEW_* utilisées pour créer des canaux. Le
+dernier argument de ces macros est ignoré dans le source. Il est destiné à
+être la documentation de la chose en une ligne. En gros, ca fait:
+root
+ +--xbt
+ |   +--config
+ |   +--dict
+ |   |   +--dict_cursor
+ |   |   +--dict_elm
+ |   |   ...
+ |   +--dynar
+ |   +--set
+ |   +--log
+ |   +--module
+ +--gras
+     +--datadesc
+     |   +--ddt_cbps
+     |   +--ddt_convert
+     |   +--ddt_exchange
+     |   +--ddt_parse
+     |       +--lexer
+     +--msg
+     +--transport
+         +--raw_trp (Je devrais tuer ce module, un jour)
+         +--trp_buf
+         +--trp_sg
+         +--trp_file
+         +--trp_tcp
+        
+Et ensuite les utilisateurs peuvent choisir le niveau de gravité qui les
+interresse sur tel ou tel sujet.
+
+Toute la mécanique de logging repose sur des variables statiques dont le nom
+dépend du nom du canal.
+ => attention aux conflits de nom de canal
+ => il faut une macro XBT_LOG dans chaque fichier où tu fais des logs.
+XBT_LOG_NEW_CATEGORY: nouveau canal sous "root". Rare, donc.
+XBT_LOG_NEW_SUBCATEGORY: nouveau canal dont on précise le père.
+XBT_LOG_DEFAULT_CATEGORY: indique quel est le canal par défaut dans ce fichier
+XBT_LOG_NEW_DEFAULT_CATEGORY: Crèe un canal et l'utilise par défaut
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY: devine
+XBT_LOG_EXTERNAL_CATEGORY: quand tu veux utiliser par défaut un canal créé
+                           dans un autre fichier.
+                          
+Une fois que ton canal est créé, tu l'utilise avec les macros LOG, DEBUG,
+VERB, WARN, ERROR et CRITICAL. Il faut que tu donne le nombre d'arguments
+après le nom de macro. Exemple: LOG2("My name is %s %s","Martin","Quinson")
+Si tu veux préciser explicitement le canal où écrire, ajoute un C devant le
+nom de la macro. Exemple: CCRITICAL0(module, "Cannot initialize GRAS")
+
+Toutes ces macros (enfin, ce en quoi elles se réécrivent) vérifient leurs
+arguments comme printf le fait lorsqu'on compile avec gcc. 
+LOG1("name: %d","toto"); donne un warning, et donc une erreur en mode
+mainteneur.
+
+Enfin, tu peux tester si un canal est ouvert à une priorité donnée (pour
+préparer plus de débug, par exemple. Dans le parseur, je fais du pretty
+printing sur ce qu'il faut parser dans ce cas).
+XBT_LOG_ISENABLED(catName, priority) Le second argument doit être une valeur
+de e_xbt_log_priority_t (log.h). Par exemple: xbt_log_priority_verbose
+
+Voila sur comment mettre des logs dans ton code. N'hesite pas à faire pleins
+de canaux différents pour des aspects différents de ton code. En
+particulier, dans les dict, j'ai un canal pour l'ajout, le retrait, le
+netoyage du code après suppression et ainsi de suite. De cette façon, je
+peux choisir qui m'interresse.
+
+
+Pour utiliser les logs, tu déjà faire, non ? Tu colle sur la ligne de
+commande un ou plusieurs arguments de la forme
+  --gras-log="<réglage> [<reglage>+]" (ou sans " si t'as pas d'espace)
+chaque réglage étant de la forme:
+  <canal>.thres=<priorité>
+Les différents réglages sont lus de gauche à droite.
+"root.thres=debug root.thres=critical" ferme tout, normalement.