/*************************************************************************************************************************************/
/* */
/* G E S T I O N " I N T E R N E " D U P A R A L L E L I S M E : */
/* */
/* */
/* Author of '$xcg/parallele.1N$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20090414184411). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
@define PRAGMA_CL_____PAS_DE_LIBRAIRIES_DYNAMIQUES
/* Plus prudent, a cause de 'v $xcg/FindExec.01$Z .xcg.parallele.1..X'... */
@define PRAGMA_CL_____PAS_DE_FICHIER_____PARAM
/* Introduit le 20170416092947 a cause de l'argument 'nombre_de_processus_parallelisables' */
/* qui est local a chaque MACHINE ('v $xcg/parallele.14$I ProcessorNumber')... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_MINI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*===================================================================================================================================*/
#include xcg/parallele.14.I"
#define COMPATIBILITE_20120114 \
VRAI \
/* Permet de se placer dans l'etat anterieur a l'introduction des 'PRIORITE_DES_COMMANDES'. */
/* On notera que c'est l'etat par defaut et ceci a cause du fait qu'il y a de grosses */
/* differences entre 'LANCEMENT_D_UNE_COMMANDE_SOUS_SH_DE_BASE' et */
/* 'LANCEMENT_D_UNE_COMMANDE_SOUS_SH' en ce qui concerne la disponibilite de 'nice', le */
/* comportement vis a vis des parentheses ou encore des quotes. Or cette commande est tres */
/* utilisee par exemple dans 'execRVB' ou encore dans 'v $xcg/FindExec.01$Z PPaRaLlElE'. */
/* Donc pour ne pas perturber tout cela, retour avant le 20120114181453... */
#define BLOQUER_LE_PARALLELISME \
FAUX \
/* La possibilite d'inhiber le parallelisme directement a ete introduite le 20100630192050 */ \
/* pour 'v $Falias_execALBUM parallelisme='. Le 20100701095323, la logique de cet indicateur */ \
/* a ete inversee en passant de 'AUTORISER_LE_PARALLELISME' a 'BLOQUER_LE_PARALLELISME'... */
#define AJUSTER_AUTOMATIQUEMENT_PCMemorySizeMB \
VRAI \
/* La variable d'environnement '$PCMemorySizeMB' sera par defaut reduite proportionnellement */ \
/* a 'nombre_de_processus_parallelisables' (introduit le 20120214104603). */
#define COMPATIBILITE_PARALLELE_14 \
VRAI \
/* La possibilite d'inhiber la compatibilite avec 'v $xcg/parallele.14$K' a ete introduite */ \
/* le 20090416105323... */
#define EN_MODE_COMPATIBILITE_PARALLELE_14_AVERTIR_S_IL_Y_A_TROP_DE_PROCESS \
VRAI \
/* La possibilite d'inhiber le message correspondant a ete introduite le 20100412134427... */
#define DUPLIQUER_N_FOIS_LA_COMMANDE \
VRAI \
/* Faut-il dupliquer la commande autant de fois qu'il y a de processus paralleles possibles */ \
/* ('VRAI') ou pas ('FAUX') ? Cela fut introduit le 20140418122211. On notera qu'avant cette */ \
/* date, tout se passait comme si cette option (absente alors) etait 'VRAI'. La valeur par */ \
/* defaut est devenue 'VRAI' le 20140419102659 afin d'assurer la compatibilite avec les tres */ \
/* nombreux usages du type 'v $xiac/$Fnota .xcs.Linda.vv.Z''... */
#define EXECUTER_LES_COMMANDES_SOUS_CSH \
FAUX \
/* La possibilite d'executer les commandes sous '$CSH' a ete introduite le 20091021093824, */ \
/* la valeur par defaut assurant la compatibilite anterieure... */
#define PREMIER_NUMERO \
UN
#define NOMBRE_DE_CHIFFRES_A_EDITER \
QUATRE
/* Nombre de chiffres a editer pour les numeros (introduit le 20111116210724). */
#define CARACTERE_DE_SEPARATION_DES_COMMANDES \
K_DIESE \
/* Caractere de separation des commandes a paralleliser. */ \
/* */ \
/* Le 20090415081248, 'K_POINT_VIRGULE' fut remplace par 'K_DIESE' a fin de faciliter */ \
/* l'usage de chaines de commandes separees par des ";"s et parallelisables... */
#define EDITER_LES_COMMANDES_AVANT_LEUR_LANCEMENT \
FAUX \
/* Afin de permettre d'editer les commandes au lancement (introduit le 20120114184627)... */
#define QUOTE_DES_COMMANDES \
C_QUOTE \
/* Afin de pouvoir encadrer les commandes (introduit le 20120114190709)... */ \
/* */ \
/* Le 20120115111544 'C_VIDE' a ete remplace par 'C_QUOTE' a cause de "parentheser=VRAI" */ \
/* qui est utilise, par exemple, dans l'alias 'execRVB'. Or de toute evidence '$SH' utilise */ \
/* a partir de cette date dans 'v $xil/defi_c1$vv$DEF LANCEMENT_D_UNE_COMMANDE_SOUS_SH' */ \
/* ne tolere pas les parentheses si elles ne sont pas quotees... */
#define PRIORITE_DES_COMMANDES \
ZERO \
/* Priorite d'ordonnancement ("scheduling") des commandes (introduite le 20120114181453)... */
#define TEMPORISATION_APRES_CHAQUE_LANCEMENT \
ZERO \
/* La possibilite de temporiser apres chaque lancement d'une tache parallele a ete */ \
/* introduite le 20100122142622 afin de permettre d'eviter de saturer une MACHINE par */ \
/* le lancement simultane d'activites tres lourdes. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define PREMIER_PROCESS \
INDEX0
#define INITIALISATION_COMMANDE(commande) \
Bblock \
INCR(nombre_de_commandes_initialisees,I); \
\
Test(IFLE(nombre_de_commandes_initialisees,nombre_de_processus_parallelisables)) \
Bblock \
EGAL(commande,chain_Acopie(commande_unique_a_paralleliser)); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Introduit le 20090415081717 afin de disposer d'un mode compatible avec la commande */ \
/* 'v $xcg/parallele.14$K'. */
#define _____UN \
UN
#define ___DEUX \
DEUX
#define __TROIS \
TROIS
#define _QUATRE \
QUATRE
/* Afin d'ameliorer les tabulations... */
#define GENERE_COMMANDE__(commande,numero) \
COND(IFNE_chaine(commande,C_VIDE) \
,chain_Aconcaten2(commande \
,COND(IFNE_chaine(racine_des_fichiers_de_redirection,C_VIDE) \
,chain_Aconcaten5(C_BLANC \
,COND(IL_FAUT(executer_les_commandes_sous_CSH) \
,C_CSH__REDIRECTION_FICHIER \
,C_SH__REDIRECTION_FICHIER \
) \
,C_BLANC \
,racine_des_fichiers_de_redirection \
,chain_numero(numero,nombre_de_chiffres_a_editer) \
) \
,ccCHAR(C_VIDE) \
) \
) \
,ccCHAR(C_VIDE) \
)
#define GENERE_SEPARATEUR(commande) \
COND(IFNE_chaine(commande,C_VIDE),chaine_separateur,ccCHAR(C_VIDE))
/* Procedures introduites le 20090416094310 afin d'alleger la generation de la liste */
/* 'liste_des_commandes'... */
/* */
/* On notera que 'chaine_separateur' n'est pas insere lorsque la 'commande??' qui precede */
/* est vide ('v $xcg/parallele.1N$K 20090415114639') afin de maximiser le parallelisme... */
#define IL_N_Y_A_AUCUNE_COMMANDE_DE_TYPE_parallele_14 \
IFET(IFEQ_chaine(commande_unique_a_paralleliser,C_VIDE) \
,I4ET(IFEQ_chaine(commande11,C_VIDE) \
,IFEQ_chaine(commande12,C_VIDE) \
,IFEQ_chaine(commande21,C_VIDE) \
,IFEQ_chaine(commande22,C_VIDE) \
) \
) \
/* Introduit le 20090416135000 afin de simplifier les validations ulterieures, puis */ \
/* passage d'un 'Logical' a un '#define' le 20090417210844... */
#define COMMANDE_PARALLELE_COURANTE \
COND(IL_FAUT(compatibilite_20120114) \
,chain_Aconcaten2(COND(IL_FAUT(executer_les_commandes_sous_CSH) \
,ccCHAR(LANCEMENT_D_UNE_COMMANDE_SOUS_CSH) \
,ccCHAR(LANCEMENT_D_UNE_COMMANDE_SOUS_SH_DE_BASE) \
) \
,ITb1(commande_courante,INDX(numero_des_process,PREMIER_PROCESS)) \
) \
,chain_Aconcaten5(COND(IL_FAUT(executer_les_commandes_sous_CSH) \
,ccCHAR(LANCEMENT_D_UNE_COMMANDE_SOUS_CSH) \
,ccCHAR(LANCEMENT_D_UNE_COMMANDE_SOUS_SH) \
) \
,quote_des_commandes \
,COND(IZEQ(priorite_des_commandes) \
,ccCHAR(C_VIDE) \
,chain_Aconcaten3(COND(IL_FAUT(executer_les_commandes_sous_CSH) \
,ccCHAR(CHANGEMENT_DE_PRIORITE_D_UNE_COMMANDE_SOUS_CSH) \
,ccCHAR(CHANGEMENT_DE_PRIORITE_D_UNE_COMMANDE_SOUS_SH) \
) \
,chain_Aentier(priorite_des_commandes) \
,C_BLANC \
) \
) \
,ITb1(commande_courante,INDX(numero_des_process,PREMIER_PROCESS)) \
,quote_des_commandes \
) \
) \
/* Commande parallele courante (introduite le 20120114184627... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E S T I O N " I N T E R N E " D U P A R A L L E L I S M E : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Logical,INIT(compatibilite_20120114,COMPATIBILITE_20120114));
/* Permet de se placer dans l'etat anterieur a l'introduction des 'priorite_des_commandes'. */
/* On notera que c'est l'etat par defaut et ceci a cause du fait qu'il y a de grosses */
/* differences entre 'LANCEMENT_D_UNE_COMMANDE_SOUS_SH_DE_BASE' et */
/* 'LANCEMENT_D_UNE_COMMANDE_SOUS_SH' en ce qui concerne la disponibilite de 'nice', le */
/* comportement vis a vis des parentheses ou encore des quotes. Or cette commande est tres */
/* utilisee par exemple dans 'execRVB' ou encore dans 'v $xcg/FindExec.01$Z PPaRaLlElE'. */
/* Donc pour ne pas perturber tout cela, retour avant le 20120114181453... */
DEFV(Logical,INIT(bloquer_le_parallelisme,BLOQUER_LE_PARALLELISME));
/* La possibilite d'inhiber le parallelisme directement a ete introduite le 20100630192050 */
/* pour 'v $Falias_execALBUM parallelisme='. Le 20100701095323, la logique de cet indicateur */
/* a ete inversee en passant de 'autoriser_le_parallelisme' a 'bloquer_le_parallelisme'... */
DEFV(Logical,INIT(ajuster_automatiquement_PCMemorySizeMB,AJUSTER_AUTOMATIQUEMENT_PCMemorySizeMB));
/* La variable d'environnement '$PCMemorySizeMB' sera par defaut reduite proportionnellement */
/* a 'nombre_de_processus_parallelisables' (introduit le 20120214104603). */
DEFV(Logical,INIT(compatibilite_parallele_14,COMPATIBILITE_PARALLELE_14));
/* La possibilite d'inhiber la compatibilite avec 'v $xcg/parallele.14$K' a ete introduite */
/* le 20090416105323... */
DEFV(Logical,INIT(en_mode_compatibilite_parallele_14_avertir_s_il_y_a_trop_de_process
,EN_MODE_COMPATIBILITE_PARALLELE_14_AVERTIR_S_IL_Y_A_TROP_DE_PROCESS
)
);
/* La possibilite d'inhiber le message correspondant a ete introduite le 20100412134427... */
DEFV(Logical,INIT(dupliquer_N_fois_la_commande,DUPLIQUER_N_FOIS_LA_COMMANDE));
DEFV(Positive,INIT(nombre_de_duplications_de_la_commande,NOMBRE_DE_PROCESSUS_PARALLELISABLES));
/* Faut-il dupliquer la commande autant de fois qu'il y a de processus paralleles possibles */
/* ('VRAI') ou pas ('FAUX') ? Cela fut introduit le 20140418122211. On notera qu'avant cette */
/* date, tout se passait comme si cette option (absente alors) etait 'VRAI'. La valeur par */
/* defaut est devenue 'VRAI' le 20140419102659 afin d'assurer la compatibilite avec les tres */
/* nombreux usages du type 'v $xiac/$Fnota .xcs.Linda.vv.Z''... */
/* */
/* Ceci fut complete le 20140419111827 par le nombre de duplications... */
DEFV(CHAR,INIC(POINTERc(commande_unique_a_paralleliser),C_VIDE));
DEFV(CHAR,INIC(POINTERc(commande11),C_VIDE));
DEFV(CHAR,INIC(POINTERc(commande12),C_VIDE));
DEFV(CHAR,INIC(POINTERc(commande21),C_VIDE));
DEFV(CHAR,INIC(POINTERc(commande22),C_VIDE));
/* Introduit le 20090415081717 afin de disposer d'un mode compatible avec la commande */
/* 'v $xcg/parallele.14$K'. */
DEFV(CHAR,INIC(POINTERc(liste_des_commandes),C_VIDE));
/* Liste des commandes a paralleliser, sous la forme : */
/* */
/* COMMANDE1 # COMMANDE2 # (...) # COMMANDEi # (...) # COMMANDEn */
/* */
/* en supposant que 'caractere_de_separation_des_commandes' soit '#'. D'autre part, chaque */
/* 'COMMANDEi' peut etre de la forme : */
/* */
/* COMMANDEi1 ; COMMANDEi2 ; (...) ; COMMANDEij ; (...) ; COMMANDEim */
/* */
/* ou 'COMMANDEij' est une commande "simple" et les espaces ci-dessus etant purement */
/* "cosmetiques"... */
DEFV(CHAR,INIC(POINTERc(racine_des_fichiers_de_redirection),C_VIDE));
DEFV(Positive,INIT(premier_numero,PREMIER_NUMERO));
DEFV(Positive,INIT(nombre_de_chiffres_a_editer,NOMBRE_DE_CHIFFRES_A_EDITER));
/* Introduit le 20111116210724 afin de pouvoir eventuellement rediriger les sorties... */
DEFV(Logical,INIT(executer_les_commandes_sous_CSH,EXECUTER_LES_COMMANDES_SOUS_CSH));
/* La possibilite d'executer les commandes sous '$CSH' a ete introduite le 20091021093824, */
/* la valeur par defaut assurant la compatibilite anterieure... */
DEFV(CHAR,INIT(caractere_de_separation_des_commandes,CARACTERE_DE_SEPARATION_DES_COMMANDES));
/* Caractere de separation des commandes a paralleliser (voir le commentaire precedent...). */
DEFV(Positive,INIT(nombre_de_processus_parallelisables,NOMBRE_DE_PROCESSUS_PARALLELISABLES));
/* Nombre de processus parallelisables. */
/* */
/* On notera le 20090415132416 qu'en faisant : */
/* */
/* NombreProcessParalleles=1 */
/* */
/* on se place dans une situation equivalente au : */
/* */
/* parallelisme=FAUX */
/* */
/* de 'v $xcg/parallele.14$K, c'est-a-dire que l'on se met en mode "sequentiel"... */
DEFV(Logical,INIT(editer_les_commandes_avant_leur_lancement,EDITER_LES_COMMANDES_AVANT_LEUR_LANCEMENT));
/* Afin de permettre d'editer les commandes avant le lancement et dans un ordre qui n'est */
/* pas a priori l'ordre numerique 'numero_des_process' (introduit le 20120114184627)... */
DEFV(CHAR,INIC(POINTERc(quote_des_commandes),QUOTE_DES_COMMANDES));
/* Afin de pouvoir encadrer les commandes (introduit le 20120114190709)... */
DEFV(Positive,INIT(priorite_des_commandes,PRIORITE_DES_COMMANDES));
/* Priorite d'ordonnancement ("scheduling") des commandes (introduite le 20120114181453)... */
DEFV(Int,INIT(temporisation_apres_chaque_lancement,TEMPORISATION_APRES_CHAQUE_LANCEMENT));
/* La possibilite de temporiser apres chaque lancement d'une tache parallele a ete */
/* introduite le 20100122142622 afin de permettre d'eviter de saturer une MACHINE par */
/* le lancement simultane d'activites tres lourdes. */
DEFV(Int,INIT(index_du_premier_caractere_de_la_commande_courante,PREMIER_CARACTERE));
DEFV(Logical,INIT(toutes_les_commandes_ont_ete_recuperees,FAUX));
/* Afin de recuperer toutes les commandes a paralleliser... */
/*..............................................................................................................................*/
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(GET_ARGUMENT_L("compatibilite_20120114=",compatibilite_20120114);
GET_ARGUMENT_L("sequentiel=""seq=",bloquer_le_parallelisme);
GET_ARGUMENT_N("parallelisme=""parallele=""para=",bloquer_le_parallelisme);
/* Argument introduit le 20100630192050. Le 20100701095323, la logique de cet indicateur */
/* a ete inversee en passant de 'autoriser_le_parallelisme' a 'bloquer_le_parallelisme'... */
GET_ARGUMENT_L("PCMemorySizeMB=""PCM=",ajuster_automatiquement_PCMemorySizeMB);
/* Arguments introduits le 20120214104603... */
GET_ARGUMENT_L("compatibilite_parallele_14=""parallele_14=""p14=",compatibilite_parallele_14);
GET_ARGUMENT_L("avertir_trop_de_process_compatibilite_parallele_14=""atp="
,en_mode_compatibilite_parallele_14_avertir_s_il_y_a_trop_de_process
);
/* Arguments introduits le 20100412134427... */
GET_ARGUMENT_L("dupliquer_N_fois=""dupliquer=""dup=",dupliquer_N_fois_la_commande);
GET_ARGUMENT_I("nombre_duplications=""duplications=""ndup=",nombre_de_duplications_de_la_commande);
/* Arguments introduits le 20140418122211 et completes le 20140419111827... */
GET_ARGUMENT_C("commande=""cm=""c=""C=",commande_unique_a_paralleliser);
GET_ARGUMENT_C("commande1=""commande11=""cm1=""c1=""c11=""C1=""C11=",commande11);
GET_ARGUMENT_C("commande2=""commande12=""cm2=""c2=""c12=""C2=""C12=",commande12);
GET_ARGUMENT_C("commande3=""commande21=""cm3=""c3=""c21=""C3=""C21=",commande21);
GET_ARGUMENT_C("commande4=""commande22=""cm4=""c4=""c22=""C4=""C22=",commande22);
/* Le 20090415111836, je note que les cinq 'GET_ARGUMENT_C(...)'s qui precedent doivent etre */
/* identiques a ceux de 'v $xcg/parallele.14$K GET_ARGUMENT_C' pour assurer la compatibilite */
/* de 'v $xcg/parallele.1N$K' et de 'v $xcg/parallele.14$K'. */
GET_ARGUMENT_C("liste_commandes=""lc=""liste=""commandes=""cms=""cs=""Cs=",liste_des_commandes);
GET_ARGUMENT_C("fichiers_redirection=""redirection=""fr=",racine_des_fichiers_de_redirection);
GET_ARGUMENT_I("chiffres=",nombre_de_chiffres_a_editer);
GET_ARGUMENT_I("premier_numero=""premier=""p=",premier_numero);
/* Arguments introduits le 20111116210724... */
GET_ARGUMENT_L("CSH=""csh=",executer_les_commandes_sous_CSH);
GET_ARGUMENT_N("SH=""sh=",executer_les_commandes_sous_CSH);
GET_ARGUMENT_K("separateur=""sep=",caractere_de_separation_des_commandes);
GET_ARGUMENT_I("NombreProcessParalleles=""process=""processus=""np=""nombre=""NP="
,nombre_de_processus_parallelisables
);
GET_ARGUMENT_L("editer_commandes=""ec=",editer_les_commandes_avant_leur_lancement);
/* Arguments introduits le 20120114184627... */
PROCESS_ARGUMENT_C("quotes=""q=",quote_des_commandes
,BLOC(VIDE;)
,BLOC(Test(IFGT(chain_Xtaille(quote_des_commandes),size_CHAR))
Bblock
PRINT_ATTENTION("la 'quote' des commandes est a priori un caractere unique");
Eblock
ATes
Bblock
Eblock
ETes
)
);
/* Arguments introduits le 20120114190709... */
GET_ARGUMENT_I("temporisation=""tempo=",temporisation_apres_chaque_lancement);
/* Arguments introduits le 20100122142622... */
GET_ARGUMENT_I("priorite_commandes=""priorite=""nice=",priorite_des_commandes);
/* Arguments introduits le 20100122142622... */
)
);
Test(IL_FAUT(compatibilite_20120114))
/* Test introduit le 20120115120709... */
Bblock
Eblock
ATes
Bblock
Test(IFET(IZGT(priorite_des_commandes)
,IFET(IFNE_chaine(quote_des_commandes,C_APOSTROPHE)
,IFNE_chaine(quote_des_commandes,C_QUOTE)
)
)
)
/* Test introduit le 20120114192311... */
Bblock
PRINT_ATTENTION("il est preferable de 'quoter' les commandes non prioritaires");
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
begin_nouveau_block
Bblock
DEFV(CHAR,INIS(DTb0(chaine_separateur),Ichaine01(caractere_de_separation_des_commandes)));
/* ATTENTION : c'est 'INIS(...)' qui est utilise (et non pas 'INIT(...)') afin de ne pas */
/* parentheser la liste 'Ichaine01(...)'. */
Test(IL_FAUT(bloquer_le_parallelisme))
/* Test introduit le 20100630192050. Le 20100701095323, la logique de cet indicateur */
/* a ete inversee en passant de 'autoriser_le_parallelisme' a 'bloquer_le_parallelisme'... */
Bblock
EGAL(nombre_de_processus_parallelisables,UN);
/* Et voila comment bloquer le parallelisme... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(compatibilite_parallele_14))
/* Test introduit le 20090416105323... */
Bblock
Test(IFEQ_chaine(liste_des_commandes,C_VIDE))
/* Lorsque la liste des commandes est vide, cela declenche le mode de compatibilite avec */
/* '$xcg/parallele.14$K'. Les commandes individuelles vont etre concatenees (si elles */
/* existent afin de donner naissance a la liste...). */
Bblock
Test(IFGT(nombre_de_processus_parallelisables,NOMBRE_DE_PROCESSUS_PARALLELISABLES_4))
Bblock
Test(EST_VRAI(en_mode_compatibilite_parallele_14_avertir_s_il_y_a_trop_de_process))
/* Test introduit le 20100412134427... */
Bblock
PRINT_ATTENTION("en mode compatible '$xcg/parallele.14$K' le nombre de process paralleles est limite");
CAL1(Prer2("(%d process etaient demandes alors que %d seront utilises au maximum)\n"
,nombre_de_processus_parallelisables
,NOMBRE_DE_PROCESSUS_PARALLELISABLES_4
)
);
Eblock
ATes
Bblock
Eblock
ETes
EGAL(nombre_de_processus_parallelisables,NOMBRE_DE_PROCESSUS_PARALLELISABLES_4);
/* Limitation introduite le 20090415123925... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IFNE_chaine(commande_unique_a_paralleliser,C_VIDE))
Bblock
Test(I4ET(IFEQ_chaine(commande11,C_VIDE)
,IFEQ_chaine(commande12,C_VIDE)
,IFEQ_chaine(commande21,C_VIDE)
,IFEQ_chaine(commande22,C_VIDE)
)
)
Bblock
DEFV(Int,INIT(nombre_de_commandes_initialisees,ZERO));
INITIALISATION_COMMANDE(commande11);
INITIALISATION_COMMANDE(commande12);
INITIALISATION_COMMANDE(commande21);
INITIALISATION_COMMANDE(commande22);
Eblock
ATes
Bblock
PRINT_ATTENTION("la 'commande unique' est ignoree, l'une au moins des quatre commandes etant definie");
CAL1(Prer1("(elle etait '%s')\n",commande_unique_a_paralleliser));
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
EGAL(liste_des_commandes
,chain_Aconcaten7(GENERE_COMMANDE__(commande11,_____UN),GENERE_SEPARATEUR(commande11)
,GENERE_COMMANDE__(commande12,___DEUX),GENERE_SEPARATEUR(commande12)
,GENERE_COMMANDE__(commande21,__TROIS),GENERE_SEPARATEUR(commande21)
,GENERE_COMMANDE__(commande22,_QUATRE)
)
);
Eblock
ATes
Bblock
Test(EST_FAUX(IL_N_Y_A_AUCUNE_COMMANDE_DE_TYPE_parallele_14))
Bblock
PRINT_ATTENTION("le mode compatible '$xcg/parallele.14$K' est bloque, une liste de commandes etant presente");
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
ATes
Bblock
Test(EST_FAUX(IL_N_Y_A_AUCUNE_COMMANDE_DE_TYPE_parallele_14))
Bblock
Test(IL_FAUT(dupliquer_N_fois_la_commande))
/* Test introduit le 20140418122211... */
Bblock
DEFV(Int,INIT(numero_courant,premier_numero));
/* Numero courant eventuel du fichier de redirection... */
Repe(nombre_de_duplications_de_la_commande)
Bblock
EGAL(liste_des_commandes
,chain_Aconcaten2(liste_des_commandes,GENERE_COMMANDE__(commande_unique_a_paralleliser,numero_courant))
);
/* Cette possibilite a ete introduite le 20100329085302 afin de favoriser l'execution de */
/* 'v $xcs/Linda$vv$Z' (par exemple dans 'v $xiac/$Fnota .xcs.Linda.vv.Z'). */
Test(IFLT(compteur_des_repetitions_du_Repe,nombre_de_duplications_de_la_commande))
/* ATTENTION, jusqu'au 20200114143902, il y avait ici (par erreur ?) : */
/* */
/* Test(IFLT(compteur_des_repetitions_du_Repe,nombre_de_processus_parallelisables)) */
/* */
/* Cela s'est vu en introduisant l'alias 'v $xE/.alias.2$vv$y execPar_F'... */
Bblock
EGAL(liste_des_commandes
,chain_Aconcaten2(liste_des_commandes,GENERE_SEPARATEUR(commande_unique_a_paralleliser))
);
Eblock
ATes
Bblock
Eblock
ETes
INCR(numero_courant,I);
/* Numero courant eventuel du fichier de redirection... */
Eblock
ERep
Eblock
ATes
Bblock
EGAL(liste_des_commandes
,chain_Aconcaten2(liste_des_commandes,GENERE_COMMANDE__(commande_unique_a_paralleliser,premier_numero))
);
/* Introduit le 20140418122211 a cause de 'v $xcg/FindExec.01$Z LiMiTeUr' qui met toutes les */
/* commandes "bout a bout" seperees par le "#"... */
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
end_nouveau_block
Test(IL_FAUT(ajuster_automatiquement_PCMemorySizeMB))
/* Test introduit le 20120214104603. */
Bblock
Pval("PCMemorySizeMB"
,DIVI(sHOTE_____TAILLE_DE_LA_MEMOIRE_DE_REFERENCE_EN_MEGA_OCTETS,nombre_de_processus_parallelisables)
);
/* Ainsi le pourcentage de la memoire physique a priori utilisable est partage equitablement */
/* entre tous les processus qui vont etre lances (introduit le 20120214104603). */
Eblock
ATes
Bblock
Eblock
ETes
Tant(EST_FAUX(toutes_les_commandes_ont_ete_recuperees))
Bblock
/* Bouclage sur l'integralite des commandes arguments : */
DEFV(CHAR,POINTERc(DTb1(commande_courante,nombre_de_processus_parallelisables)));
/* Liste des commandes courantes parallelisees. */
DEFV(processus,DTb1(process_parallelises,nombre_de_processus_parallelisables));
/* Identificateur des process correspondant aux commandes courantes parallelisees. */
DEFV(Int,INIT(numero_des_process,PREMIER_PROCESS));
/* Index des differents process... */
Tant(IFET(IFLE(numero_des_process,LSTX(PREMIER_PROCESS,nombre_de_processus_parallelisables))
,EST_FAUX(toutes_les_commandes_ont_ete_recuperees)
)
)
/* Bouclage sur un "paquet" de 'nombre_de_processus_parallelisables' commandes arguments : */
Bblock
BSaveModifyVariable(Int
,chain_copie_____index_du_premier_caractere_d_une_chaineA
,index_du_premier_caractere_de_la_commande_courante
);
BSaveModifyVariable(CHAR
,chain_copie_____caractere_d_arret_secondaire
,caractere_de_separation_des_commandes
);
BSaveModifyVariable(Logical
,chain_copie_____copier_le_caractere_d_arret_secondaire
,FAUX
);
BSaveModifyVariable(Int
,chain_copie_____premier_index_de_test_du_caractere_d_arret_secondaire
,PREMIER_CARACTERE
);
/* Afin de recuperer la commande courante dans la liste des commandes. */
EGAL(ITb1(commande_courante,INDX(numero_des_process,PREMIER_PROCESS)),chain_Acopie(liste_des_commandes));
/* Recuperation de la commande courante. */
/* */
/* On notera qu'il n'est en fait pas utile que 'commande_courante' soit un vecteur de */
/* chaines de caracteres. Il suffirait en fait de le definir par: */
/* */
/* DEFV(CHAR,POINTERc(commande_courante)); */
/* */
/* mais on ne sait jamais, peut-etre que plus tard... */
ESaveModifyVariable(Int,chain_copie_____premier_index_de_test_du_caractere_d_arret_secondaire);
ESaveModifyVariable(Logical,chain_copie_____copier_le_caractere_d_arret_secondaire);
ESaveModifyVariable(CHAR,chain_copie_____caractere_d_arret_secondaire);
ESaveModifyVariable(Int,chain_copie_____index_du_premier_caractere_d_une_chaineA);
/* Restaurations... */
iPARALLELE(BLOC(
Bblock
Test(IL_FAUT(editer_les_commandes_avant_leur_lancement))
Bblock
CAL3(Prme3("Commande parallele %0*d='%s'\n"
,NOMBRE_DE_CHIFFRES_DECIMAUX(nombre_de_processus_parallelisables)
,numero_des_process
,COMMANDE_PARALLELE_COURANTE
)
);
/* Possibilite introduite le 20120114184627... */
/* */
/* Le 20120115172535 fut introduit l'edition de 'numero_des_process'... */
/* */
/* On notera evidemment que les differentes commandes ne sortent pas necessairement dans */
/* l'ordre numerique de 'numero_des_process' a cause de 'iPARALLELE(...)' qui possede un */
/* fonctionnement asynchrone... */
Eblock
ATes
Bblock
Eblock
ETes
CALS(SYSTEM(COMMANDE_PARALLELE_COURANTE));
Eblock
)
,ITb1(process_parallelises,INDX(numero_des_process,PREMIER_PROCESS))
);
/* Lancement en parallele de la commande courante. */
/* */
/* On notera le 20090415114639 le fonctionnement suivant : */
/* */
/* soit (par exemple...) : */
/* */
/* NombreProcessParalleles=2 */
/* */
/* Ensuite : */
/* */
/* liste_commandes="COMMANDE1#COMMANDE2" */
/* */
/* provoquera l'execution simultanee et parallele de 'COMMANDE1' et 'COMMANDE2', alors */
/* que : */
/* */
/* liste_commandes="COMMANDE1##COMMANDE2" */
/* _ */
/* provoquera l'execution simultanee et parallele de 'COMMANDE1' et d'une commande vide */
/* a cause du deuxieme '#'), puis ENSUITE de 'COMMANDE2'. C'est pour eviter cela que le */
/* separateur (via 'chaine_separateur') n'est pas insere si une commande vide le precede */
/* lors du mode compatible '$xcg/parallele.14$K'... */
/* */
/* Le 20091021093824 fut introduite la possibilite d'executer les commandes sous '$CSH', */
/* autorisant ainsi l'utilisation d'alias... */
DODO(temporisation_apres_chaque_lancement);
/* Temporisation eventuelle introduite le 20100122142622... */
/* */
/* Celle-ci est destinee a permettre (si besoin est) d'eviter de saturer une MACHINE par */
/* le lancement simultane d'activites tres lourdes. C'est par exemple le cas avec : */
/* */
/* execRVB $xci/accumule.41$X ... */
/* */
/* dans 'v $xiirc/$Fnota execRVB....xci.accumule.41.X' qui provoquent la lecture simultanee */
/* de tres gros fichiers au demarrage... */
EGAL(index_du_premier_caractere_de_la_commande_courante
,chain_copie_____successeur_de_l_index_du_dernier_caractere_d_une_chaineA
);
/* Pour preparer le 'chain_Acopie(...)' eventuel suivant... */
Test(EST_VRAI(chain_copie_____la_chaineA_a_ete_copiee_jusqu_au_END_OF_CHAIN))
Bblock
EGAL(toutes_les_commandes_ont_ete_recuperees,VRAI);
/* Toutes les commandes ont apparemment ete recuperees... */
Eblock
ATes
Bblock
Eblock
ETes
INCR(numero_des_process,I);
Eblock
ETan
Tant(IFGT(numero_des_process,PREMIER_PROCESS))
Bblock
DECR(numero_des_process,I);
WAIT(ITb1(process_parallelises,INDX(numero_des_process,PREMIER_PROCESS)));
/* Attente de fin de toutes les commandes lancees en parallele. En fait, ainsi on */
/* attend celle dont l'execution est la plus longue... */
Eblock
ETan
Eblock
ETan
RETU_Commande;
Eblock
ECommande