#include "libnazgul.h" #include "nzg_ids.h" /* TODO: remplacer le bool de msgPoolData par un identifiant de semaphore. Le semaphore contient poolNb valeurs (et indique donc le nombre de ressources disponnibles). */ /* TODO: prevoir le cas des négatifs dans la taille ... */ void * msgAllocate(msgSpace *space, int pool, int taille, int option ){ void * resultAddr=NULL; int i, mSPoolDataTabFd; msgPoolId resultPoolId; /* tableau des valeurs des semPoolCoef/pool pour identifier le pool * qui sera libéré le plus rapidement */ float semPoolCoef[space->poolNb]; int idxPoolOptimum; bool gotRessourceSem; sem_t * poolDataTabSemFd=NULL; msgPoolDataTabSemId ressourceSemId; sem_t * ressourceSemFd=NULL; int ressourceSemVal; float minPoolCoef; int selectedPoolIndex; int bufferFreeIndex; selectedPoolIndex=-1; /* TODO: verifier le premier arg du shm_open */ mSPoolDataTabFd=shm_open(space->poolDataTabId, O_RDWR, MSGSPACE_DEFAULT_MODE); if (mSPoolDataTabFd == -1 ) { fprintf( stderr, "Allocate %s failed: %s\n", (char*)space->poolDataTabId, strerror( errno ) ); return NULL; } msgPoolData * mSPoolDataTabAddr; mSPoolDataTabAddr = mmap( 0, (space->poolNb) * sizeof( msgPoolData ), PROT_READ | PROT_WRITE, MAP_SHARED, mSPoolDataTabFd, 0 ); if( mSPoolDataTabAddr == MAP_FAILED) { fprintf( stderr, "mmap failed: %s\n", strerror( errno ) ); return NULL; } gotRessourceSem=false; /* initialisation des coefs */ for (i=0;i<(space->poolNb);i++){ semPoolCoef[i]=-1; } int nbLockedSem=0; if ( pool == ANYPOOL){ fprintf(stderr,"[ ALLOCATION ANYPOOL : %d ]\n",(int)getpid()); // choisir le pool au hasard (ou presque) for(i=0; i<(space->poolNb); i++) { printf("ERRORDETECT boucle %d\n",i); fflush(stdout); if(mSPoolDataTabAddr[i].bufferSize >= taille) { printf("ERRORDETECT buffS > taill %d\n",i); fflush(stdout); /* choisir le numero du semaphore en fonction du nombre de lock poses / nombre de buffer */ msgPoolSemIdIntern(ressourceSemId,space->id,i); ressourceSemFd = sem_open(ressourceSemId,O_CREAT,SEM_DEFAULT_MODE,0); if (ressourceSemFd == SEM_FAILED){ NZG_ERROR("sem_open",ressourceSemId); return NULL; } /* on remplit le tableau avec les valeurs des semaphores */ if (sem_getvalue(ressourceSemFd, &ressourceSemVal) < 0){ NZG_ERROR("sem_getvalue",ressourceSemId); return NULL; } printf("RESSOURCESEMVAL %d\n",ressourceSemVal); if (ressourceSemVal <= 0){ printf("resVal < 0 : %d\n",ressourceSemVal); /* il y a ressourceSemVal processus qui attendent déja... */ semPoolCoef[nbLockedSem] = (float) (- (ressourceSemVal) / mSPoolDataTabAddr[i].bufferNb); nbLockedSem++; } if(sem_trywait(ressourceSemFd)==0) { printf("got try_wait\n"); /* choisir la 1ere pool de taille plus grande * libre si possible */ gotRessourceSem=true; selectedPoolIndex=i; break; } if( sem_close(ressourceSemFd) <0){ NZG_ERROR("sem_getvalue",ressourceSemId); return NULL; } } // if buffSize > taille } // for printf("ERRORDETECT outFor\n"); fflush(stdout); if (!gotRessourceSem) { printf("Calcul du meilleur en cas de liberation\n"); minPoolCoef= semPoolCoef[0]; idxPoolOptimum = 0; /* on cherche le pool avec le moins de lock poses / nbre de buffer * le numéro du pool est stocké dans idxPoolOptimum */ for(i=0; iid,selectedPoolIndex); ressourceSemFd=sem_open(ressourceSemId,O_CREAT,SEM_DEFAULT_MODE,0); if(ressourceSemFd==SEM_FAILED){ NZG_ERROR("sem_open",ressourceSemId); return NULL; } printf("SemWait... %s\n",ressourceSemId); if (sem_wait(ressourceSemFd) < 0){ NZG_ERROR("sem_wait",ressourceSemId); sem_close(ressourceSemFd); return NULL; } printf("Passed %s\n",ressourceSemId); } /* on a acqui un semaphore pour la ressouce */ /* on acquiert le droit de modifier les infos sur la ressource */ poolDataTabSemFd=sem_open(space->poolDataTabSemId,O_CREAT,SEM_DEFAULT_MODE,1); /* on modifie maintenant les données */ /* - on récupere l'index du premier buffer libre */ bufferFreeIndex = msgBufferGetFreeIndex(mSPoolDataTabAddr,selectedPoolIndex); if (bufferFreeIndex < 0){ sem_close(poolDataTabSemFd); // aucun buffer libre ? return NULL; } printf("Buffer %d libre a attacher !\n",bufferFreeIndex); /*TODO: mapper le buffer libre dans l'esp addr du proc */ //TODO: /* - on s'enregistre aupres de ce buffer */ //TODO: msgBufferAttachProc(space,selectedPoolIndex,resultAddr); sem_close(poolDataTabSemFd); /* TODO: unmapper le msgPoolDataTab */ return resultAddr; }