#include "libnazgul.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). */ #define ANYPOOL -1 #define SPECIFICPOOL 0 void * msgAllocate(msgSpace *space, int pool, int taille, int option ){ void * resultAddr; int i, mSPoolDataTabFd; msgSpacePoolId resultPoolID; float sems[space->poolNb]; /* tableau des valeurs des sems/pool pour identifier le pool qui sera libéré le plus rapidement */ sem_t * sem; /* TODO: verifier le premier arg du shm_open */ mSPoolDataTabFd=shm_open(space->poolDataId,O_RDWR,MSGSPACE_DEFAULT_MODE); if (mSPoolDataTabFd == -1 ) { fprintf( stderr, "Allocate %s failed: %s\n", (char*)space->poolDataId, strerror( errno ) ); return NULL; } msgPoolData * mSPoolDataTab; mSPoolDataTab = mmap( 0, (space->poolNb) * sizeof( msgPoolData ), PROT_READ | PROT_WRITE, MAP_SHARED, mSPoolDataTabFd, 0 ); if( mSPoolDataTab == MAP_FAILED) { fprintf( stderr, "mmap failed: %s\n", strerror( errno ) ); return NULL; } bool gotSem=false; int gotIdx=-1; int * sval; if (pool == ANYPOOL){ /* se debrouiller pour choisir la 1ere pool de taille plus grande libre si possible */ for(i=0; i<(space->poolNb); i++) { if(mSPoolDataTab[i].bufferSize >= taille) { /* TODO: choisir le numero du semaphore en fonction du nombre de lock poses / nombre de buffer */ sem = sem_open(mSPoolDataTab[i]->id,O_CREAT); gotIdx=i; if(sem_trywait(sem)) { gotSem=true; resultPoolID=mSPoolDataTab[gotIdx]->id; break; } else { // on remplit le tableau avec les valeurs des semaphores sem_getvalue(sem, sval); sems[i] = (float*)sval / (mSPoolDataTab[i]->bufferNb); } } if(!gotSem) { float min = sems[0]; int idxPoolOptimum; // on cherche le pool avec le moins de lock poses / nbre de buffer for(i=1; i<(space->poolNb); i++) { if(sems[i] < min) { min = sems[i]; idxPoolOptimum = i; } } resultPoolID=mSPoolDataTab[idxPoolOptimum]->id; } } }else { resultPoolID=mSPoolDataTab[pool]->id; } /* TODO: trouver un buffer libre, ou dormir */ /* TODO: mapper le buffer dans l'esp addr du proc */ /* TODO: unmapper le msgPoolDataTab */ return resultAddr; }