// Shuts down the system (global variables) by freeing memory // @par: none // @ret: none void closeSystem(void) { //TODO anything else here? /*reset resource counters?*/ /*reset memory limit?*/ // Empty all queues cleanQueue(dispatcher); }
void RtpPacketQueue::pushPacket(const char *data, int length) { const RTPHeader *header = reinterpret_cast<const RTPHeader*>(data); uint16_t nseq = header->getSeqNumber(); uint32_t ts = header->getTimestamp(); long long int ltsdiff = (long long int)ts - (long long int)lastTs_; int tsdiff = (int)ltsdiff; int nseqdiff = nseq - lastNseq_; /* // nseq sequence cicle test if ( abs(nseqdiff) > ( USHRT_MAX - MAX_DIFF ) ) { NOTIFY("Vuelta del NSeq ns=%d last=%d\n", nseq, lastNseq_); if (nseqdiff > 0) nseqdiff-= (USHRT_MAX + 1); else nseqdiff+= (USHRT_MAX + 1); } */ if (abs(tsdiff) > MAX_DIFF_TS || abs(nseqdiff) > MAX_DIFF ) { // new flow, process and clean queue ELOG_DEBUG("Max diff reached, new Flow? nsqediff %d , tsdiff %d", nseqdiff, tsdiff); ELOG_DEBUG("PT %d", header->getPayloadType()); lastNseq_ = nseq; lastTs_ = ts; cleanQueue(); enqueuePacket(data, length, nseq); } else if (nseqdiff > 1) { // Jump in nseq, enqueue ELOG_DEBUG("Jump in nseq"); enqueuePacket(data, length, nseq); } else if (nseqdiff == 1) { // next packet, process lastNseq_ = nseq; lastTs_ = ts; enqueuePacket(data, length, nseq); } else if (nseqdiff < 0) { ELOG_DEBUG("Old Packet Received"); // old packet, discard? // stats? } else if (nseqdiff == 0) { ELOG_DEBUG("Duplicate Packet received"); //duplicate packet, process (for stats)? } }
// ----------------------------------------------------------------------------- // PacketQueue::packetReceived // // ----------------------------------------------------------------------------- // void PacketQueue::packetReceived(const unsigned char *data, int length) { //channel->packetReceived2(data, length); //return; const RTPHeader *header = reinterpret_cast<const RTPHeader*>(data); u16 nseq = header->GetSeqNumber(); u32 ts = header->GetTimestamp(); long long int ltsdiff = (long long int)ts - (long long int)lastTs; int tsdiff = (int)ltsdiff; int nseqdiff = nseq - lastNseq; /* // nseq sequence cicle test if ( abs(nseqdiff) > ( USHRT_MAX - MAX_DIFF ) ) { NOTIFY("Vuelta del NSeq ns=%d last=%d\n", nseq, lastNseq); if (nseqdiff > 0) nseqdiff-= (USHRT_MAX + 1); else nseqdiff+= (USHRT_MAX + 1); } */ if (abs(tsdiff) > MAX_DIFF_TS || abs(nseqdiff) > MAX_DIFF ) { // new flow, process and clean queue channel->packetReceived2(data, length); lastNseq = nseq; lastTs = ts; cleanQueue(); } else if (nseqdiff > 1) { // Jump in nseq, enqueue enqueuePacket(data, length, nseq); checkQueue(); } else if (nseqdiff == 1) { // next packet, process channel->packetReceived2(data, length); lastNseq = nseq; lastTs = ts; checkQueue(); } else if (nseqdiff < 0) { // old packet, discard? // stats? } else if (nseqdiff == 0) { //duplicate packet, process (for stats)? //channel->packetReceived2(data, length); } }
void RtpPacketQueue::enqueuePacket(const char *data, int length, uint16_t nseq) { if (queue_.size() > MAX_SIZE) { // if queue is growing too much, we start again cleanQueue(); } boost::shared_ptr<dataPacket> packet(new dataPacket()); memcpy(packet->data, data, length); packet->length = length; queue_.insert(std::map< int, boost::shared_ptr<dataPacket>>::value_type(nseq,packet)); }
// Updates the dispatcher // @par: int current time (quantum) // @ret: int 1 for process put into real time queue // @ret: int 0 otherwise int updateDispatcher(int time) { // Create a pointer to the dispatcher so we don't modify dispatcher directly unless we need to Queue *queuePtr = dispatcher; // Create a new queue for elements that weren't able to be added Queue *newDispatcher = initializeQueue(); int rtQUpdated = 0; // Checks if dispatcher is empty if (!(queuePtr)) { printf("The queue is empty!\n\n"); return 0; } // Iterate through each element in the queue int i = 0; int count = numElems(queuePtr); // If the first process is NULL, we don't want to iterate through them // Double check that there are elements in queue if (queuePtr->process == NULL) { i = count; } // Keep an indicator to see if anything breaks int broken = 0; // Iterate through each element in the dispatcher while (i < count) { // Dequeue the next process from the queue PCB *currentProcess = dequeueProcess(&queuePtr)->process; // Queue is empty // Triple check if (currentProcess == NULL) { printf("BROKEN!\n"); broken = 1; break; } // If the process has "arrived", attempt to allocate resources to it if (time >= currentProcess->arrivalTime) { // Attempt to allocate resources to the process. int allocResult = allocateResources(currentProcess); if (allocResult) { // Resources were allocated successfully printf("* INITIALIZED pid: %d", currentProcess->pid); if (currentProcess->priority == 0) { rtQUpdated = 1; printf(", a real time process"); } printf("\n\n"); // Send the process to join the appropriate priority queue enqueueToPriority(currentProcess); } else { // Resources could not be allocated, move the process back on the dispatcher queue enqueueProcess(newDispatcher, currentProcess); } } else { // The time has not come for this process, add it to the new dispatcher enqueueProcess(newDispatcher, currentProcess); } i++; } // If the queue wasn't broken if (!broken) { if (dispatcher == NULL) { cleanQueue(dispatcher); } dispatcher = newDispatcher; } return rtQUpdated; }
RtpPacketQueue::~RtpPacketQueue(void) { cleanQueue(); }
/* Parametre (facultatif) : nombre de pilotes souhaités nombre d'agents souhaités (indisponible) */ int main(int argc, char* argv[]){ struct sigaction action; if(argc == 1){ NBR_PILOTES = NBR_DEFAULT; NBR_AGENTS = NBR_PILOTES; } else if(argc == 2 && atoi(argv[1]) > 1){ NBR_PILOTES = atoi(argv[1]); NBR_AGENTS = NBR_PILOTES; } /*else if(argc == 3 && atoi(argv[1]) > 1 && atoi(argv[2]) > 1 && atoi(argv[1]) <= atoi(argv[2])){ NBR_PILOTES = atoi(argv[1]); NBR_AGENTS = atoi(argv[2]); }*/ else{ printf("Utilisation : \nArgument 1 (optionnel) : Nombre de pilote ( > 1 )\n"); /* printf("Argument 2 (optionnel) : Nombre d'agents ( > 1 )\n"); //INDISPO*/ fprintf(stderr, "Impossible de lancer le main\n"); return EXIT_FAILURE; } srand(time(NULL)); int MemoirePID = shmget(ftok("main",0), TAILLE_SHM, 0644 | IPC_CREAT); if(MemoirePID == -1){ perror("Erreur Création Mémoire partagée"); exit(1); } /* On partage la file d'attente */ pid = shmat(MemoirePID, NULL, 0); FilesAttentes = malloc(NBR_PILOTES * sizeof(int)); if(FilesAttentes == NULL){ perror("Echec lors l'allocation memoire file d'attente"); exit(1); } /* Tubes pour recuperer le PID des execl */ int pilotesTube[2]; int groupesTube[2]; /* Variables pour les parametres de l'execl */ char Memoire[255]; char NbrPilotes[255]; char NbrAgents[255]; char TPilote[255]; char TGroupe[255]; /* On créé les tubes */ if (pipe(pilotesTube) == -1){ perror("Erreur création pipe pilote"); exit(1); } if (pipe(groupesTube) == -1){ perror("Erreur création pipe groupe"); exit(1); } /* Création Mémoire Partagée */ MemoirePartagee = shmget(ftok("main.c",1), TAILLE_SHM, 0644 | IPC_CREAT); if(MemoirePartagee == -1){ perror("Erreur Création Mémoire partagée"); exit(1); } /* On partage la file d'attente */ FilesAttentes = shmat(MemoirePartagee, NULL, 0); /* On verifie que la file d'attente est bien partagée */ if (FilesAttentes == (int *)(0)) { perror("Memoire partagee files attente"); exit(1); } /* On formate le nombre de pilotes et la memoire partage dans un char* */ sprintf(Memoire,"%d",MemoirePartagee); sprintf(NbrPilotes,"%d",NBR_PILOTES); sprintf(TGroupe,"%d",groupesTube[1]); sprintf(TPilote,"%d",pilotesTube[1]); sprintf(NbrAgents,"%d",NBR_AGENTS); if (createQueue(FilesAttentes, NBR_PILOTES) == -1){ perror("Errer creation"); exit(1); } /*On fork */ switch(fork()){ case -1 : { perror("Erreur Création fork()"); exit(1); break; } /* Fils : Création des groupes */ case 0 : { /* On fork a nouveau (a cause du recouvrement) */ switch(fork()){ case -1 : { perror("Erreur Création fork()"); break; } case 0 : { close(groupesTube[0]); /* On lance les groupes et on envoie en parametre : le nombre de file d'attente le segment de memoire partagee le tube pour recuperer le pid le nombre d'agents souhaités */ if (execl("./groupes","groupes", NbrPilotes, Memoire, TGroupe, NbrAgents, NULL) == -1){ perror("L'ouverture des groupes a échoué"); exit(1); } printf("Recouvrement groupe\n"); break; } default : { /* On reucpere le pid du fils */ close(groupesTube[1]); read(groupesTube[0], &(pid->pidGroupes), sizeof(pid_t)); close(groupesTube[0]); exit(1); break; } wait(NULL); } break; } /* Pere : Création des pilotes */ default : { /* On fork a nouveau (a cause du recouvrement) */ switch(fork()){ case -1 : { perror("Erreur Création fork()"); break; } case 0 : { close(pilotesTube[0]); /* On lance les groupes et on envoie en parametre : le nombre de pilote le segment de memoire partagee le tube pour recuperer le pid */ if (execl("./pilotes","pilotes", NbrPilotes, Memoire, TPilote, NULL) == -1){ perror("L'ouverture des pilotes a échoué"); } printf("Recouvrement pilote\n"); break; } default : { /* On recupere le pid du fils */ close(pilotesTube[1]); read(pilotesTube[0], &(pid->pidPilotes), sizeof(pid_t)); close(pilotesTube[0]); break; } } wait(NULL); } } /* On ajoute le signal pour l'arret */ action.sa_handler=SignalArret; sigemptyset(&action.sa_mask); sigaction(SIGINT,&action,NULL); /* On attend la fin des fils pour terminer */ waitpid(pid->pidPilotes,NULL,0); waitpid(pid->pidGroupes,NULL,0); /* On a recuperé les PID, plus besoin de la memoire partagée */ shmctl(MemoirePID, IPC_RMID, NULL); /* On detache la memoire partage */ if(shmctl(MemoirePartagee, IPC_RMID, NULL) == -1) perror("Erreur lors du detachement de la memoire partagee\n"); cleanQueue(FilesAttentes,NBR_PILOTES); /* On libere la memoire */ /*if(FilesAttentes != NULL){ free(FilesAttentes); FilesAttentes = NULL; }*/ /*if(pid != NULL){ free(pid); pid = NULL; }*/ printf("Fin du processus centre d'appel\n"); return EXIT_SUCCESS; }