C* C* COMMON DE POINTAGE, CONTIENT LES INFOS PERSONNELLES ET LES POINTEURS C* SUR LES SEGMENTS DE BASE C* PARAMETER(MAXFRAGSIZE=100000) INTEGER DEBUG COMMON /OOOCO2/ MYNUM,DEBUG,MYPID,MYTID, 1 MZPCL,MZPAC,MZPCP,MZPEV,MZPLO, 2 NPSEG,LISRC,MSGTAG,NMACH,MMACH,IPQPOS C C --------- C I CLIENTS I C --------- C C* LE SEGMENT DES CLIENTS PERMET DE STOCKER LES C* INFORMATIONS DE BASE POUR LA GESTION DES CLIENTS. C* C* LES MOTS D'UN SEGMENT SONT L'ID DE LA TACHE, L'ID DE SON SERVEUR, C* L'ETAT DE LA TACHE, LE SLOT DANS LEQUEL CETTE TACHE DEPOSE SES REQUETES C* ET LIT SES REPONSES C* C* SCHEMA D'UN DESCRIPTEUR DE CLIENT. C* C* +--------+--------+--------+--------+--------+--------+--------+--------+ C* | TASKID | SERVER | STATUS | <--------TSLOT---------> | NEXT | PREV | C* +--------+--------+--------+--------+--------+--------+--------+--------+ C* 0 1 2 3 ............... 70 71 C* C* C* TASKID EST LE NUMERO DE TACHE AU SENS PVM, LES CLIENTS SONT NUMEROTES C* SEQUENTIELLEMENT A PARTIR DE 1. LES CLIENTS EN ATTENTE SUR UN SEGMENT SONT C* CHAINES ENTRE EUX, LA TETE DE CHAINE ETANT LE MOT MDQCL DU DESCRIPTEUR C* DU SEGMENT CONSIDERE. C* SEGMENT , CLIENTS INTEGER CLISLOCKED(NCL) INTEGER CLLOCKEDBY(NCL) REAL*8 CLVLOCK(NCL) INTEGER CLPID(NCL) INTEGER CLTID(NCL) INTEGER CLHOST(NCL) INTEGER CLSTATUS(NCL) INTEGER CLCACHE(NCL) INTEGER RQOPER(NCL) INTEGER RQLRET(NCL) INTEGER RQPSEG(NCL) INTEGER RQKOD(NCL) INTEGER RQVERS(NCL) INTEGER RQNACC(NCL) INTEGER RQNACT(NCL) INTEGER RQWORK(65,NCL) POINTEUR CLNEXT(NCL).CLIENTS POINTEUR CLPREV(NCL).CLIENTS ENDSEGMENT POINTEUR CL1.CLIENTS,CL2.CLIENTS,CLX.CLIENTS C* C* CACHE DU SEGMENT DES DESCRIPTEURS C* C'EST ICI QUE CHAQUE TACHE LOGGUE SES ACCES A SES SEGMENTS C* LORSQU'UNE TACHE DECIDE D'AIDER UN SERVEUR EN DIFFICULTE, C* LES SEGMENTS DONT LA DESACTIVATION EST ATTENDUE SONT CHAINES C* ENTRE EUX PAR LE SERVEUR LUI-MEME. C* LE SEGMENT 1 SERT DE TETE DE CHAINE A CE TYPE DE SEGMENTS. C* SEGMENT , CACHE INTEGER CSTAT(NSGC) INTEGER CNACC(NSGC) INTEGER CNACT(NSGC) INTEGER CNEXT(NSGC) INTEGER CPREV(NSGC) ENDSEGMENT C* C* MACROS D'ACCES AUX CHAMPS DE L'ETAT DU SEGMENT C* MACRO , MCVERS(ID) MCVERS = (CSTAT(((ID)-MDIDX0)/MDLDE)/512) PSEUDO , MAVERS CSTAT(((ID)-MDIDX0)/MDLDE) = 2MOD(CSTAT(((ID)-MDIDX0)/MDLDE),512)+(MAVERS)*512 ENDMACRO MACRO , MCSTAT(ID) MCSTAT=MOD(CSTAT(((ID)-MDIDX0)/MDLDE),256) PSEUDO , LESTAT CSTAT(((ID)-MDIDX0)/MDLDE) = 1(CSTAT(((ID)-MDIDX0)/MDLDE)/256)*256+(LESTAT) ENDMACRO MACRO , MCDES(ID) MCDES=(MOD(CSTAT(((ID)-MDIDX0)/MDLDE),512)/256) PSEUDO , LEDES CSTAT(((ID)-MDIDX0)/MDLDE) = 1(CSTAT(((ID)-MDIDX0)/MDLDE)/512)*512+(LEDES)*256+ 2MOD(CSTAT(((ID)-MDIDX0)/MDLDE),256) ENDMACRO MACRO , MCNACC(ID) MCNACC = (CNACC(((ID)-MDIDX0)/MDLDE)) PSEUDO , MANACC CNACC(((ID)-MDIDX0)/MDLDE) = (MANACC) ENDMACRO MACRO , MCNACT(ID) MCNACT = (CNACT(((ID)-MDIDX0)/MDLDE)) PSEUDO , MANACT CNACT(((ID)-MDIDX0)/MDLDE) = (MANACT) ENDMACRO C* C* CHAINAGE DES SEGMENTS C* C* METTRE UN SEGMENT DANS LA CHAINE DES SEGMENTS DONT LA DESACTIVATION C* EST ATTENDUE PAR LE SERVEUR. C* MACRO , MCDDID0=1 MACRO , MCDDEM(ID) IIID=((ID)-MDIDX0)/MDLDE IF(CNEXT(IIID).EQ.0) THEN IIITMP=CNEXT(MCDDID0) CNEXT(MCDDID0)=IIID CPREV(IIID)=MCDDID0 CNEXT(IIID)=IIITMP CPREV(IIITMP)=IIID ENDIF ENDMACRO C* C* ENLEVER UN SEGMENT DE LA CHAINE DES SEGMENTS DONT LA DESACTIVATION C* EST DEMANDEE. C* MACRO , MCDDRM(ID) IIID=((ID)-MDIDX0)/MDLDE IF(CNEXT(IIID).NE.0) THEN IIIPRC=CPREV(IIID) IIINXT=CNEXT(IIID) CNEXT(IIIPRC)=IIINXT CPREV(IIINXT)=IIIPRC CNEXT(IIID)=0 CPREV(IIID)=0 ENDIF ENDMACRO C* C* LISTE DES CODES OPERATION LOCAUX C* MACRO ,( U2S_SEGSSG,U2S_SEGSTP,U2S_SEGINI,U2S_SEGACT,U2S_SEGDES, 1 U2S_SEGSUP,U2S_SEGADJ,U2S_SEGEXT,U2S_SEGETA,U2S_SEGVAL, 2 U2S_SEGDMP,U2S_SEGACC,U2S_SEGVPN,U2S_VERBOSE,U2S_PEORIG, 3 U2S_PEPOST,U2S_SEGXDS,U2S_SEGMRU,U2S_SEGLIS,U2S_FORK, 4 U2S_HELP ,U2S_ALLOC ,U2S_PEWAIT,U2S_PETERM, C*) C* C* LISTE DES CODES OPERATION RESEAU C* C* MACRO ,( 1 S2M_SEGINI ,M2S_SEGINI ,S2M_SEGININACK, 2 M2S_SEGININACK ,M2S_SEGINIACK ,M2S_SEGINIACK2, 3 M2S_SEGININACK2 ,S2S_SEGCNT ,M2S_SEGACT, 4 S2S_SEGACTACK ,S2S_SEGACTNACK ,S2M_SEGACT, 5 S2M_SEGACTACK ,M2S_SEGACTACK ,S2S_SEGACC, 6 M2S_SEGACC ,S2S_SEGACCACK ,S2S_SEGACCNACK, 7 S2M_SEGACC ,S2M_SEGSUP ,M2S_SEGSUPACK, 8 S2S_SEGDES ,S2S_SEGDESACK ,PEM_DOWN, 9 S2M_FORK ,S2M_FORKACK ,S2M_FORKNACK, A M2S_FORK ,M2S_FORKACK ,M2S_FORKNACK, A S2M_INSTALLACK ,S2M_INSTALLNACK,S2S_INSTALLACK, B S2S_INSTALLNACK ,M2S_SEGACTNACK ,S2M_SEGACTNACK, C S2M_SEGINIACK ,S2M_PEORIG ,M2S_PEORIG, D S2M_PEPOST ,M2S_PEPOST ,S2M_PEWAIT, E M2S_PEWAIT ,S2M_PETERM ,M2S_PETERM) C* C* MACROS C* C* C* METTRE UN CLIENT EN ATTENTE SUR UN SEGMENT C* MACRO , ATTEND (CL,PSEG) IF(MDQCL(PSEG).EQ.0) THEN MDQCL(PSEG)=CL CLNEXT(CL)=CL CLPREV(CL)=CL RQWORK(65,CL)=RQOPER(CL) ELSE CLX=MDQCL(PSEG) III=CLPREV(CLX) CLNEXT(III)=CL CLPREV(CL)=III CLNEXT(CL)=CLX CLPREV(CLX)=CL RQWORK(65,CL)=RQOPER(CL) ENDIF ENDMACRO C* C* ENLEVER UN CLIENT DU SEGMENT PSEG C* MACRO , MDCLRM(CL,PSEG) III=MDQCL(PSEG) IF(III.EQ.CL) THEN IF(CLPREV(III).EQ.III.AND.CLNEXT(III).EQ.III) THEN MDQCL(PSEG)=0 ELSE CLPREV(CLNEXT(CL))=CLPREV(CL) CLNEXT(CLPREV(CL))=CLNEXT(CL) MDQCL(PSEG)=CLNEXT(CL) ENDIF ELSE CLPREV(CLNEXT(CL))=CLPREV(CL) CLNEXT(CLPREV(CL))=CLNEXT(CL) ENDIF ENDMACRO C C ------- C I ACCES I C ------- C C* LE SEGMENT DES ACCES PERMET DE STOCKER LES C* INFORMATIONS DE BASE POUR LA GESTION DES ACCES RO LOCAUX. ON SCRUTE C* LES ACCES LOCAUX ET LES COPIES DISTANTES AVANT DE PRENDRE DES C* DECISIONS POUR LE TRAITEMENT DES REQUETES. C* C* LES CHAMPS D'UN SEGMENT ACCES SONT L'ID DE LA TACHE QUI ACCEDE LE SEGMENT, C* LE MODE D'ACCES ET DES POINTEURS AVANT ET ARRIERE C* POUR LE CHAINAGE. LE SEGMENT 1 SERT DE TETE DE CHAINE POUR LES C* ACCES LIBRES, LES DESCRIPTEURS ATTRIBUES SONT CHAINES SUR LE CHAMP C* ACCES DU DESCRIPTEUR DU SEGMENT CONSIDERE. C* SEGMENT , ACCES INTEGER ACCLIENT(NAC) INTEGER ACMODE(NAC) POINTEUR ACNEXT(NAC).ACCES POINTEUR ACPREV(NAC).ACCES ENDSEGMENT POINTEUR IA3.ACCES,IAX.ACCES C* C* SCHEMA D'UN SEGMENT ACCES LIBRE. C* C* +--------+--------+--------+--------+ C* |////////|////////| NEXT | PREV | C* +--------+--------+--------+--------+ C* 0 1 2 3 C* C* SCHEMA D'UN SEGMENT ACCES ATTRIBUE. C* C* +--------+--------+--------+--------+ C* | CLIENT | MODE | NEXT | PREV | C* +--------+--------+--------+--------+ C* 0 1 2 3 C* MACRO , (RO , RW ) C* C* ZEROISATION C* MACRO , MDACZERO(ID) ACCLIENT(ID)=0 ACMODE(ID)=0 ACNEXT(ID)=0 ACPREV(ID)=0 ENDMACRO C* C* MANIPULATION DES CHAINES C* C* C* INTRODUIRE IA1 DANS LA CHAINE DEVANT IA2 C* MACRO , MDACCHN(IA1,IA2) IA3=ACNEXT(IA2) ACPREV(IA3)=IA1 ACNEXT(IA1)=IA3 ACPREV(IA1)=IA2 ACNEXT(IA2)=IA1 ENDMACRO C* C* RAJOUTER UN ACCES RO SUR PSEG PAR NUMCL C* MACRO , ATTACHE (NUMCL,PSEG) IA2=ACNEXT(1) IA3=ACNEXT(IA2) ACNEXT(1)=IA3 ACPREV(IA3)=1 ACCLIENT(IA2)=NUMCL ACMODE(IA2)=RO ACNEXT(IA2)=IA2 ACPREV(IA2)=IA2 IF(MDACCS(PSEG).EQ.0) THEN MDACCS(PSEG)=IA2 ELSE IA1=MDACCS(PSEG) IA3=ACNEXT(IA1) ACPREV(IA3)=IA2 ACNEXT(IA2)=IA3 ACPREV(IA2)=IA1 ACNEXT(IA1)=IA2 ENDIF ENDMACRO C* C* ENLEVER IA1 DU SEGMENT PSEG C* MACRO , MDACRM(IA1,PSEG) IA2=MDACCS(PSEG) IF(IA2.EQ.IA1) THEN IF(ACPREV(IA2).EQ.IA2.AND.ACNEXT(IA2).EQ.IA2) THEN MDACCS(PSEG)=0 ELSE ACPREV(ACNEXT(IA1))=ACPREV(IA1) ACNEXT(ACPREV(IA1))=ACNEXT(IA1) MDACCS(PSEG)=ACNEXT(IA1) ENDIF ELSE ACPREV(ACNEXT(IA1))=ACPREV(IA1) ACNEXT(ACPREV(IA1))=ACNEXT(IA1) ENDIF IA3=ACNEXT(1) ACPREV(IA3)=IA1 ACNEXT(IA1)=IA3 ACPREV(IA1)=1 ACNEXT(1)=IA1 ENDMACRO C C -------- C I COPIES I C -------- C C* LE SEGMENT DES COPIES PERMET DE STOCKER LES C* INFORMATIONS DE BASE POUR LA GESTION DES COPIES DE SEGMENTS. ON SCRUTE C* LES ACCES LOCAUX ET LES COPIES DISTANTES AVANT DE PRENDRE DES C* DECISIONS POUR LE TRAITEMENT DES REQUETES. UNE COPIE EST CARACTERISEE C* PAR UN ETAT QUI PEUT ETRE VALIDE OU NON, UTILISEE OU NON C* C* LES MOTS D'UN SEGMENT SONT L'ID DU SERVEUR QUI EST EN COPIE DE CE C* SEGMENT, L'ETAT DE LA COPIE ET DES POINTEURS C* AVANT ET ARRIERE POUR LE CHAINAGE. LE SEGMENT 1 SERT DE TETE DE C* CHAINE POUR LES COPIES LIBRES, LES COPIES ATTRIBUEES SONT C* CHAINES SUR LE CHAMP COPIES DU DESCRIPTEUR DU SEGMENT CONSIDERE. C* C* SCHEMA D'UN SEGMENT COPIE LIBRE. C* C* +--------+--------+--------+--------+ C* |////////|////////| NEXT | PREV | C* +--------+--------+--------+--------+ C* 0 1 2 3 C* C* SCHEMA D'UN SEGMENT COPIE ATTRIBUE. C* C* +--------+--------+--------+--------+ C* | SERVER | MODE | NEXT | PREV | C* +--------+--------+--------+--------+ C* 0 1 2 3 C* SEGMENT COPIES INTEGER CPSERVER(NCP) INTEGER CPMODE(NCP) POINTEUR CPNEXT(NCP).COPIES POINTEUR CPPREV(NCP).COPIES ENDSEGMENT POINTEUR IC3.COPIES,ICX.COPIES C* C* ZEROISATION C* MACRO , MDCPZERO(ID) CPSERVER(ID)=0 CPMODE(ID)=0 CPNEXT(ID)=0 CPPREV(ID)=0 ENDMACRO C* C* MANIPULATION DES CHAINES C* C* C* INTRODUIRE IC1 DANS LA CHAINE DEVANT IC2 C* MACRO , MDCPCHN(IC1,IC2) IC3=CPPREV(IC2) CPPREV(IC3)=IC1 CPNEXT(IC1)=IC3 CPPREV(IC1)=IC2 CPNEXT(IC2)=IC1 ENDMACRO C* C* RAJOUTER UNE COPIE DE PSEG PAR NUMCL C* MACRO , ENCOPIE (NUMCL,PSEG) IC2=CPNEXT(1) IC3=CPNEXT(IC2) CPNEXT(1)=IC3 CPPREV(IC3)=1 CPSERVER(IC2)=NUMCL CPMODE(IC2)=RO CPPREV(IC2)=IC2 CPNEXT(IC2)=IC2 IF(MDRCPY(PSEG).EQ.0) THEN MDRCPY(PSEG)=IC2 ELSE IC1=MDRCPY(PSEG) IC3=CPNEXT(IC1) CPPREV(IC3)=IC2 CPNEXT(IC2)=IC3 CPPREV(IC2)=IC1 CPNEXT(IC1)=IC2 ENDIF ENDMACRO C* C* ENLEVER IC1 DU SEGMENT PSEG C* MACRO , MDCPRM(IC1,PSEG) IC2=MDRCPY(PSEG) IF(IC2.EQ.IC1) THEN IF(CPPREV(IC2).EQ.IC2.AND.CPNEXT(IC2).EQ.IC2) THEN MDRCPY(PSEG)=0 ELSE CPPREV(CPNEXT(IC1))=CPPREV(IC1) CPNEXT(CPPREV(IC1))=CPNEXT(IC1) MDRCPY(PSEG)=CPNEXT(IC1) ENDIF ELSE CPPREV(CPNEXT(IC1))=CPPREV(IC1) CPNEXT(CPPREV(IC1))=CPNEXT(IC1) ENDIF IC3=CPNEXT(1) CPPREV(IC3)=IC1 CPNEXT(IC1)=IC3 CPPREV(IC1)=1 CPNEXT(1)=IC1 ENDMACRO C C ----------------------- C I EVENEMENTS PARALLELES I C ----------------------- C* C* LE SEGMENT DES EVENEMENTS PARALLELES EXISTE UNIQUEMENT CHEZ LE MAITRE C* IL SERT A STOCKER LES INFORMATIONS RELATIVES AU EVENEMENTS PARALLELES C* CREES PAR LES DIFFERENTES TACHES. C* SEGMENT LPEVENT INTEGER PEID(NEV) ENDSEGMENT SEGMENT PEVENT INTEGER OWNER INTEGER DONE INTEGER PCOUNT INTEGER PREACH INTEGER WCOUNT INTEGER WREACH INTEGER WCLNT(NWCL) INTEGER UNIQUE ENDSEGMENT C C ----------------------- C I SEGMENT DES LOCKS I C ----------------------- C* C* LE SEGMENT DES LOCKS SERT A TENIR LES VERROUS SUR LES SEGMENTS. IL DEVRAIT C* ETRE FIXE EN MEMOIRE. LA TAILLE D'UN LOCK DEPEND DU SYSTEME. EN UTILISANT C* LES msemaphores DE AIX V4, CHAQUE LOCK PREND DEUX ENTIERS. C* SEGMENT PLOCK INTEGER ISLOCKED(NLO) INTEGER LOCKEDBY(NLO) REAL*8 VLOCK(NLO) ENDSEGMENT