KSG_Task_Queue* KSG_Queue_Task_Scheduler_Impl::peek_queue(long time_out) { KSG_Task_Queue *queue; // 从 running 中查找队列 // TODO must be test if(_head_of_running->_head->next() != _head_of_running->_head) { queue = _head_of_running->_head->next(); remove_queue(_head_of_running,queue); return queue; } // 加上锁 { ACE_GUARD_RETURN(ACE_Thread_Mutex,mon1,_head_of_running->_mutex,NULL); ACE_GUARD_RETURN(ACE_Thread_Mutex,mon2,_head_of_waiting->_mutex,NULL); // 交换 running & waiting std::swap(_head_of_running,_head_of_waiting); } // 从 waiting 中查找队列 if(_head_of_running->_head->next() != _head_of_running->_head) { queue = _head_of_running->_head->next(); remove_queue(_head_of_running,queue); return queue; } return NULL; }
int main(void){ char buf[128]; append_queue("aaa1"); append_queue("aaa2"); remove_queue(buf); printf("%s\n",buf); remove_queue(buf); printf("%s\n",buf); return (0); }
int KSG_Queue_Task_Scheduler_Impl::notify_new_task() { int count; // reload sleeping queue { // //ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex,mon,_head_of_waiting->_mutex,-1)); //ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex,mon1,_head_of_sleeping->_mutex,-1)); KSG_Task_Queue *queue,*pre; count = 0; for(queue = _head_of_sleeping->_head->next(); queue != _head_of_sleeping->_head;) { if(queue->count_of_tasks() > 0) { pre = remove_queue(_head_of_sleeping,queue); //ACE_DEBUG((LM_DEBUG,"push queue to waiting queue!")); push_back_queue(_head_of_waiting,queue); count++; } else pre = queue; // 应该不会出现这种情况 if(!pre) goto L_END; queue = pre->next(); } } L_END: if(count > 0) return 0; return -1; }
/* * === FUNCTION ====================================================================== * Name: clean_up_procs * Description: Handles terminating children, destroys message queues, and * releases dynamically-allocated global arrays. * ===================================================================================== */ static void clean_up_procs(int *queuep, pid_t *pidp, int num_queuep) { struct msqid_ds ds_buf; int i; if(child_pid == -1) { for(i = 1; i < num_queuep; i++) kill(pidp[i], SIGTERM); for(i = 0; i < num_queuep; i++) { /* Workaround for checking whether queue exists; * I would use msgget, but since the queues were * created with IPC_PRIVATE, it seems that that * method won't work. */ if(msgctl(queuep[i], IPC_STAT, &ds_buf) == 0) { if(remove_queue(queuep[i]) == -1 && errno != EIDRM) { fprintf(stderr, "Error removing queue %d, process %d:\n", queuep[i], i); perror("msgctl"); } } } } free(keys); free(queues); free(pids); }
static void send_messages(int fd, char * version) { char buf[MAX_BUF]; char msg[MAX_LENGTH]; int message_size = 0; QNode * qnode; string_node * snode; pthread_mutex_lock(&mutex); while(!is_empty(&q)) { qnode = remove_queue(&q); snode = QUEUE_ENTRY(qnode, string_node, node); strncat(msg, snode->str, snode->str_length); message_size += snode->str_length; free_string_node(snode); } // Send response headers to client sprintf(buf, "%s 200 OK\r\n", version); sprintf(buf, "%sServer: Pi Web Server\r\n", buf); sprintf(buf, "%sContent-length: %d\r\n", buf, message_size); sprintf(buf, "%sContent-type: text/html\r\n\r\n", buf); write(fd, buf, sizeof(buf)); write(fd, msg, sizeof(msg)); pthread_mutex_unlock(&mutex); }
void *remove_some_recycle_queues( void *vp) { all_queues_iterator *iter = NULL; pbs_queue *pq; q_recycler.queues.lock(); iter = q_recycler.queues.get_iterator(); q_recycler.queues.unlock(); mutex_mgr q_recycler_mutex = mutex_mgr(q_recycler.mutex, false); pq = next_queue_from_recycler(&q_recycler.queues,iter); delete iter; if (pq == NULL) return NULL; remove_queue(&q_recycler.queues,pq); unlock_queue(pq, __func__, NULL, LOGLEVEL); free(pq->qu_mutex); delete pq->qu_jobs; delete pq->qu_jobs_array_sum; memset(pq, 254, sizeof(pbs_queue)); free(pq); return(NULL); } /* END remove_some_recycle_queues() */
static void retry_erase(erase_busy_t *busy, u_int cause) { eraseq_entry_t *erase = busy->erase; mtd_request_t req; client_t *mtd; socket_info_t *s; int ret; DEBUG(2, "cs: trying erase request 0x%p...\n", busy); if (busy->next) remove_queue(busy); req.Function = MTD_REQ_ERASE | cause; req.TransferLength = erase->Size; req.DestCardOffset = erase->Offset + erase->Handle->info.CardOffset; req.MediaID = erase->Handle->MediaID; mtd = erase->Handle->mtd; s = SOCKET(mtd); mtd->event_callback_args.mtdrequest = &req; wacquire(&mtd->mtd_req); ret = EVENT(mtd, CS_EVENT_MTD_REQUEST, CS_EVENT_PRI_LOW); wrelease(&mtd->mtd_req); if (ret == CS_BUSY) { DEBUG(2, " Status = %d, requeueing.\n", req.Status); switch (req.Status) { case MTD_WAITREQ: case MTD_WAITPOWER: insert_queue(&mtd->erase_busy, busy); break; case MTD_WAITTIMER: case MTD_WAITRDY: if (req.Status == MTD_WAITRDY) insert_queue(&s->erase_busy, busy); mod_timer(&busy->timeout, jiffies + req.Timeout*HZ/1000); break; } } else { /* update erase queue status */ DEBUG(2, " Ret = %d\n", ret); switch (ret) { case CS_SUCCESS: erase->State = ERASE_PASSED; break; case CS_WRITE_PROTECTED: erase->State = ERASE_MEDIA_WRPROT; break; case CS_BAD_OFFSET: erase->State = ERASE_BAD_OFFSET; break; case CS_BAD_SIZE: erase->State = ERASE_BAD_SIZE; break; case CS_NO_CARD: erase->State = ERASE_BAD_SOCKET; break; default: erase->State = ERASE_FAILED; break; } busy->client->event_callback_args.info = erase; EVENT(busy->client, CS_EVENT_ERASE_COMPLETE, CS_EVENT_PRI_LOW); kfree(busy); /* Resubmit anything waiting for a request to finish */ wakeup(&mtd->mtd_req); retry_erase_list(&mtd->erase_busy, 0); } } /* retry_erase */
void thread_destroy(thread_t *t) { DPRINTF("t:%p\n", t); remove_queue(t); free(t); }
int main(int argc, char** argv) { Car car; Queue check_car; int i; init_queue(&check_car); for(i=0;i<7;i++) { printf("Enter a car:\n"); printf("%17s", "mark: "); scanf("%s", car.mark); printf("%17s"," number: "); scanf("%s", car.number); //snprintf(car.number,9,"%d",i+1); printf("%17s", "production year: "); scanf("%hu", &car.year); if(insert_queue(&check_car, car) == QUEUE_FULL) { fprintf(stderr, "Queue overflow\n"); exit(1); } printf("\n"); } printf("\n"); while(remove_queue(&check_car, &car) != QUEUE_EMPTY) printf("%10s %7s %4hu\n", car.mark, car.number, car.year); queue_free(&check_car); return 0; }
int main (int argc, char **argv) { execname = basename (argv[0]); queue_ref queue = new_queue(); if (argc < 2) { putinqueue (queue, stdin, "-"); }else { for (int argi = 1; argi < argc; ++argi) { if (strcmp (argv[argi], "-") == 0) { putinqueue (queue, stdin, "-"); }else { putfileinqueue (queue, argv[argi]); } } } while (! isempty_queue (queue)) { char *oldstring = remove_queue(queue); printf ("%s\n", oldstring); free (oldstring); } free_queue(queue); return exit_status; }
void topological_sort(int **graph, int *indegree, int nodes) { int i, j, cnode; int *ts; ts = malloc(nodes * sizeof(int)); for (i = 0; i < nodes; i++) { if (indegree[i] == 0) { insert_queue(i); indegree[i] = -1; } } j = 0; while ((cnode = remove_queue()) != -1) { for (i = 0; i < nodes; i++) { indegree[i] -= graph[cnode][i]; if (indegree[i] == 0) { insert_queue(i); indegree[i] = -1; } } ts[j++] = cnode; printf("%d\n", cnode); } }
int main(int argc, char *argv[]) { struct mymsgbuf qbuf; char key_id[16]; key_t key; int msgid, type; unsigned short opperm; char cmd[MAX_SIZE] = { 0 }; printf ( "Message queues present in the system\n" ); system("ipcs -q"); printf( "\nEnter the desired key in hex (form: 0x0807633d, 0x0 for IPC_PRIVATE)\n or queue's id in decimal: "); scanf( "%15s", key_id); if ( sscanf( key_id, "0x%x", &key ) == 0 ) { // key_id represents an ID sscanf( key_id, "%d", &msgid ); printf( "\nmsgid = %d", msgid ); } else { // key_id is a key, otherwise msgid = msgget_wrapper( key ); if ( msgid == -1 ) syserr("msgget"); } printf( "\nmsgid = %d\n", msgid ); while (1) { fprintf(stderr, "\nChoose an action:\n"); fprintf(stderr, " (s)end <type> <messagetext>\n"); fprintf(stderr, " (r)ecv <type>\n"); fprintf(stderr, " (d)elete\n"); fprintf(stderr, " (m)ode <octal mode>\n"); fprintf(stderr, " (q)uit the application\n"); scanf("%s", cmd); switch(tolower(cmd[0])) { case 's': scanf("%d", &type); fgets(cmd, MAX_SIZE-1, stdin); send_message(msgid, &qbuf, type, cmd); break; case 'r': scanf("%d", &type); read_message(msgid, &qbuf, type); break; case 'd': remove_queue(msgid); break; case 'm': scanf("%ho", &opperm); change_queue_mode(msgid, opperm); break; case 'q': return 0; } } return 0 ; }
KSG_Task_Queue* KSG_Queue_Task_Scheduler_Impl::peek_queue(long time_out) { KSG_Task_Queue *queue; // 从 running 中查找队列 // TODO must be test //ACE_GUARD_RETURN(ACE_Thread_Mutex,mon,_head_of_running->_mutex,NULL); if(_head_of_running->_head->next() != _head_of_running->_head) { queue = _head_of_running->_head->next(); if(remove_queue(_head_of_running,queue) == NULL) ACE_DEBUG((LM_ERROR,"从链表中取出队列失败")); return queue; } // 加上锁 { //ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex,mon2,_head_of_waiting->_mutex,NULL)); //if(_head_of_waiting->_head->next() == _head_of_waiting->_head) // return NULL; //ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex,mon1,_head_of_running->_mutex,NULL)); // 交换 running & waiting std::swap(_head_of_running,_head_of_waiting); } // 从 waiting 中查找队列 if(_head_of_running->_head->next() != _head_of_running->_head) { queue = _head_of_running->_head->next(); if(remove_queue(_head_of_running,queue) == NULL) ACE_DEBUG((LM_ERROR,"从链表中取出队列失败")); return queue; } // 激活 sleeping 队列中的任务 notify_new_task(); //do_dump_task_queue(_head_of_running->_head,"running"); //do_dump_task_queue(_head_of_sleeping->_head,"sleeping"); return NULL; }
int clear_queue(int type) { int i = 0; queue *qp, *next; for (qp = botqueue; qp; qp = next) { next = qp->next; if (qp->type & type) { i++; remove_queue(qp); } } return i; }
int main(int argc, char **argv) { struct Queue *queue = create_queue(); push(1, queue); push(2, queue); push(3, queue); assert(pop(queue) == 1); assert(pop(queue) == 2); push(1, queue); assert(pop(queue) == 3); assert(pop(queue) == 1); assert(remove_queue(queue) == NULL); printf("All tests passed.\n"); return 0; }
void que_free( pbs_queue *pq, int sv_qs_mutex_held) { int i; pbs_attribute *pattr; attribute_def *pdef; /* remove any calloc working pbs_attribute space */ for (i = 0;i < QA_ATR_LAST;i++) { pdef = &que_attr_def[i]; pattr = &pq->qu_attr[i]; pdef->at_free(pattr); /* remove any acl lists associated with the queue */ if (pdef->at_type == ATR_TYPE_ACL) { pattr->at_flags |= ATR_VFLAG_MODIFY; save_acl(pattr, pdef, pdef->at_name, pq->qu_qs.qu_name); } } /* now free the main structure */ if (sv_qs_mutex_held == FALSE) lock_sv_qs_mutex(server.sv_qs_mutex, __func__); server.sv_qs.sv_numque--; if (sv_qs_mutex_held == FALSE) unlock_sv_qs_mutex(server.sv_qs_mutex, __func__); free_user_info_holder(pq->qu_uih); remove_queue(&svr_queues, pq); pq->q_being_recycled = TRUE; insert_into_queue_recycler(pq); unlock_queue(pq, "que_free", NULL, LOGLEVEL); return; } /* END que_free() */
int main(int argc, char *argv[]) { key_t key; int msgqueue_id; struct mymsgbuf qbuf; if(argc == 1) usage(); /* Create unique key via call to ftok() */ key = ftok(".", 'm'); /* Open the queue - create if necessary */ if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1) { perror("msgget"); exit(1); } switch(tolower(argv[1][0])) { case 's': send_message(msgqueue_id, (struct mymsgbuf *)&qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgqueue_id, &qbuf, atol(argv[2])); break; case 'd': remove_queue(msgqueue_id); break; case 'm': change_queue_mode(msgqueue_id, argv[2]); break; default: usage(); } return(0); }
int main (int argc, char **argv) { execname = basename (argv[0]); queue *the_queue = new_queue(); if (argc < 2) { putinqueue (the_queue, stdin, "-"); }else { for (int argi = 1; argi < argc; ++argi) { if (strcmp (argv[argi], "-") == 0) { putinqueue (the_queue, stdin, "-"); }else { putfileinqueue (the_queue, argv[argi]); } } } while (! isempty_queue (the_queue)) { printf ("%s\n", remove_queue (the_queue)); } return exit_status; }
/* Selects process to run and returns its SP value */ unsigned int process_select (unsigned int cursp) { queue_t *temp; if (cursp == 0) { //No process was running if (current_process == NULL) { //first process if (queue_head != NULL) { //Queue is non-empty current_process = queue_head->p; return current_process->sp; } return 0; //Queue is empty } //Current Process terminated if (queue_head->next != NULL) { //Select next process and update current process current_process = queue_head->next->p; queue_head = queue_head->next; return current_process->sp; } //No more processes to run queue_head = NULL; current_process = NULL; return 0; } else if (queue_head->next == NULL) { //Current Process is only process (and not terminated), update SP to cursp current_process->sp = cursp; return queue_head->p->sp; } else { //Current Process is not terminated but there is a ready process in queue //Update and Must switch to give other process a chance current_process->sp = cursp; temp = queue_head; remove_queue(); //Switch to next process (at head) add_queue(temp); //Add prev process back to queue since it did not terminate yet return queue_head->p->sp; } }
int main(int argc, char *argv[]) { key_t key; int msgqueue_id; struct minhastruct msgponteiro; if(argc ==1) { ajuda(); } key = ftok(".", 'm'); if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1) { perror("msgget"); exit(1); } switch(tolower(argv[1][0])) { case 'e': enviar_mensagem(msgqueue_id, (struct minhastruct*)&msgponteiro, atol(argv[2]), argv[3]); break;; case 'r': ler_mensagem(msgqueue_id, &msgponteiro, atol(argv[2])); break; case 'a': remove_queue(msgqueue_id); break; case 'm': mudar_permissoes(msgqueue_id, argv[2]); break; default: ajuda(); } return(0); }
int main(int argc, char *argv[]) { key_t key; int msgqueue_id; //消息队列标识符 struct mymsgbuf qbuf; if (argc == 1) usage(); /*create unique key via call to ftok()*/ key = ftok(".", 'm'); /*open the queue - create if necessary*/ if ((msgqueue_id = msgget(key, IPC_CREAT | 0660)) == -1) { perror("msgget"); exit(1); } /*关于argv[1][0]的解释来自:stackoverflow.com/questions/11757951/what-is-the-meaning-of-argv10(foreign Web) * as others have pointed out, argv[1] is the second string in the string array argv, * and strings are character arrays so argv[1][0] is the first character in the second * string. * that is(也就是说):it means the first character of the second string of argv. * */ switch (tolower(argv[1][0])) { case 's': send_message(msgqueue_id, (struct mymsgbuf *)&qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgqueue_id, &qbuf, atol(argv[2])); //atol:将字符串转换成长整型数 break; case 'd': remove_queue(msgqueue_id); break; case 'm': change_queue_mode(msgqueue_id, argv[2]); break; default: usage(); } return 0; }
void calculator(int msg_size) { int queue_id_rc; key_t key_rc = MESSAGE_QUEUE_ID_RC; msgbuf_t values_buffer; values_t *values_ptr = (values_t *)(values_buffer.mtext); fprintf(stderr, "#%d# Calculator - Inicialized...\n", getpid()); create_queue(&queue_id_rc, &key_rc); receive_queue_message(&queue_id_rc, &values_buffer, msg_size); fprintf(stderr, "#%d# Calculator - Minimum time for transfering: %.10f\n", getpid(), values_ptr->min); fprintf(stderr, "#%d# Calculator - Maximum time for transfering: %.10f\n", getpid(), values_ptr->max); fprintf(stderr, "#%d# Calculator - Total time for transfering: %.10f\n", getpid(), values_ptr->total); fprintf(stderr, "#%d# Calculator - Average time for transfering: %.10f\n", getpid(), values_ptr->average); remove_queue(&queue_id_rc); exit(EXIT_SUCCESS); }
int KSG_Queue_Task_Scheduler_Impl::wait_for_wake_up(long time_out) { int ret = Task_Queue_Pool::instance()->wait_for_queue(_queue_key,time_out); if(!ret) return ret; int count; // reload sleeping queue { // ACE_GUARD_RETURN(ACE_Thread_Mutex,mon,_head_of_waiting->_mutex,-1); ACE_GUARD_RETURN(ACE_Thread_Mutex,mon1,_head_of_sleeping->_mutex,-1); KSG_Task_Queue *queue,*pre; count = 0; for(queue = _head_of_sleeping->_head->next(); queue != _head_of_sleeping->_head;) { if(queue->count_of_tasks() > 0) { pre = remove_queue(_head_of_sleeping,queue); push_back_queue(_head_of_waiting,queue); count++; } else pre = queue; // 应该不会出现这种情况 if(!pre) goto L_END; queue = pre->next(); } } L_END: if(count > 0) return 0; // 处理失败 return -1; }
void thread_sleep(thread_t *t) { DPRINTF("t:%p\n", t); remove_queue(t); }
//--------- Begin of function FirmHarbor::detect_build_menu ---------// // void FirmHarbor::detect_build_menu() { int unitId, x=INFO_X1+2, y=INFO_Y1, rc, quitFlag; UnitInfo* unitInfo; for(int b=0; b<added_count; ++b) { // ###### begin Gilbert 20/9 #########// unitId = button_ship[b].custom_para.value; // ###### end Gilbert 20/9 #########// unitInfo = unit_res[unitId]; //------ detect pressing on the small queue count button -------// // ####### begin Gilbert 20/9 ########// rc = 0; if( (rc = button_queue_ship[b].detect(0,0,2)) != 0 ) // both button { quitFlag = 0; // don't quit the menu right after pressing the button } //------ detect pressing on the big button -------// else if( (rc = button_ship[b].detect(0,0,2)) != 0 ) { quitFlag = 1; // quit the menu right after pressing the button } // ####### end Gilbert 20/9 ########// //------- process the action --------// if( rc > 0 ) { if( rc==1 ) // left button { if( remote.is_enable() ) { // packet structure : <firm recno> <unit Id> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 2*sizeof(short) ); shortPtr[0] = firm_recno; shortPtr[1] = unitId; } else add_queue(unitId); // ##### begin Gilbert 25/9 ######// se_ctrl.immediate_sound("TURN_ON"); // ##### end Gilbert 25/9 ######// } else // right button - remove queue { if( remote.is_enable() ) { // packet structure : <firm recno> <unit Id> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 2*sizeof(short) ); shortPtr[0] = firm_recno; shortPtr[1] = -unitId; } else remove_queue(unitId); // ##### begin Gilbert 25/9 ######// se_ctrl.immediate_sound("TURN_OFF"); // ##### end Gilbert 25/9 ######// } if( quitFlag ) info.disp(); // info.disp() will call put_info() which will switch mode back to the main menu mode else // ######## begin Gilbert 20/9 ########// // disp_queue_button(y+COUNT_BUTTON_OFFSET_Y, unitId, 1); info.update(); // ######## end Gilbert 20/9 ########// return; } y += BUILD_BUTTON_HEIGHT; } //------ detect the cancel button --------// if( button_cancel.detect() || mouse.any_click(1) ) // press the cancel button or right click { harbor_menu_mode = HARBOR_MENU_MAIN; info.disp(); // ###### begin Gilbert 26/9 #######// se_ctrl.immediate_sound("TURN_OFF"); // ###### end Gilbert 26/9 #######// } }
void FirmIncubator::detect_build_menu() { int unitId, rc, quitFlag; UnitInfo* unitInfo; for( int b = 0; b < added_count; ++b) { unitId = button_weapon[b].custom_para.value; unitInfo = unit_res[unitId]; //------ detect pressing on the small queue count button -------// rc = 0; quitFlag = 0; if( (rc = button_queue_weapon[b].detect(0,0,2)) != 0 ) // both button { quitFlag = 0; // don't quit the menu right after pressing the button } //------ detect pressing on the big button -------// else if( (rc = button_weapon[b].detect(0,0,2)) != 0 ) { quitFlag = 1; // quit the menu right after pressing the button } //------- process the action --------// if( rc > 0 ) { if( rc==1 ) // left button { if( remote.is_enable() ) { // packet structure : <firm recno> <unit Id> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_WAR_BUILD_WEAPON, 2*sizeof(short) ); shortPtr[0] = firm_recno; shortPtr[1] = unitId; } else add_queue(unitId); se_ctrl.immediate_sound("TURN_ON"); } else // right button - remove queue { if( remote.is_enable() ) { // packet structure : <firm recno> <unit Id> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_WAR_CANCEL_WEAPON, 2*sizeof(short) ); shortPtr[0] = firm_recno; shortPtr[1] = unitId; } else remove_queue(unitId); se_ctrl.immediate_sound("TURN_OFF"); } if( quitFlag ) war_menu_mode = WAR_MENU_MAIN; return; } } //------ detect the cancel button --------// if( button_cancel.detect() ) { se_ctrl.immediate_sound("TURN_OFF"); war_menu_mode = WAR_MENU_MAIN; } }
int main(int argc, char *argv[]) { pid_t pid; int i; int users_number; int service_probability; int text_message_probability; int status; int deadproc = 0; /* A counter of the already terminated user processes */ int qid; int sw; /* Qid of the switch */ int dest; /* Destination of the message */ int olddest; /* Destination of the previous message */ int queues[MAXCHILDS + 1]; /* Queue identifiers - 0 is the qid of the switch */ int msg_sender; int msg_recipient; char msg_text[160]; int msg_service; int msg_service_data; int t; int timing[MAXCHILDS + 1][2]; int unreachable_destinations[MAXCHILDS + 1]; char *padding = " "; char text[160]; messagebuf_t msg, in; /* Command line argument parsing */ if(argc != 4){ usage(argv); exit(0); } users_number = strtol(argv[1], NULL, 10); service_probability = strtol(argv[2], NULL, 10); text_message_probability = strtol(argv[3], NULL, 10); if((users_number < MINCHILDS) || (users_number > MAXCHILDS)){ usage(argv); exit(1); } if((service_probability < 0) || (service_probability > 100)){ usage(argv); exit(0); } if((text_message_probability < 0) || (text_message_probability > 100)){ usage(argv); exit(0); } printf("Number of users: %d\n", users_number); printf("Probability of a service request: %d%%\n", service_probability); printf("Probability of a text message: %d%%\n", text_message_probability); printf("\n"); /* Initialize the random number generator */ srandom(time(NULL)); /* Switch queue initialization */ sw = init_queue(255); /* Read the last messages we have in the queue */ while(receive_message(sw, TYPE_TEXT, &in)){ printf("%d -- S -- Receiving old text messages\n", (int) time(NULL), i); } /* Read the last messages we have in the queue */ while(receive_message(sw, TYPE_SERVICE, &in)){ printf("%d -- S -- Receiving old service messge\n", (int) time(NULL), i); } /* All queues are "uninitialized" (set equal to switch queue) */ for(i = 0; i <= users_number; i++){ queues[i] = sw; unreachable_destinations[i] = 0; } /* Create users */ for(i = 1; i <= users_number; i++){ pid = fork(); if (pid == 0){ srandom(time(NULL) + 1000*i); /* Initialize queue */ qid = init_queue(i); /* Read the last messages we have in the queue */ while(receive_message(qid, TYPE_TEXT, &in)){ printf("%s%d -- U %02d -- Receiving old text messages\n", padding, (int) time(NULL), i); } /* Read the last messages we have in the queue */ while(receive_message(qid, TYPE_SERVICE, &in)){ printf("%s%d -- U %02d -- Receiving old service messge\n", padding, (int) time(NULL), i); } /* Let the switch know we are alive */ user_send_connect(i, sw); /* Let the switch know how to reach us */ user_send_qid(i, qid, sw); /* Enter the main loop */ while(1){ sleep(rand()%MAX_SLEEP); /* Check if the switch requested a service */ if(receive_message(qid, TYPE_SERVICE, &in)){ msg_service = get_service(&in); switch(msg_service){ case SERVICE_TERMINATE: /* Send an acknowledgement to the switch */ user_send_disconnect(i, getpid(), sw); /* Read the last messages we have in the queue */ while(receive_message(qid, TYPE_TEXT, &in)){ msg_sender = get_sender(&in); get_text(&in, msg_text); printf("%s%d -- U %02d -- Message received\n", padding, (int) time(NULL), i); printf("%s Sender: %d\n", padding, msg_sender); printf("%s Text: %s\n", padding, msg_text); } /* Remove the queue */ close_queue(qid); printf("%s%d -- U %02d -- Termination\n", padding, (int) time(NULL), i); exit(0); break; case SERVICE_TIME: user_send_time(i, sw); printf("%s%d -- U %02d -- Timing\n", padding, (int) time(NULL), i); break; } } /* Send a message */ if(random_number(100) < text_message_probability){ dest = random_number(users_number + 1); /* Do not send a message to the switch, to yourself and to the previous recipient */ while((dest == 0) || (dest == i) || (dest == olddest)){ dest = random_number(users_number + 1); } olddest = dest; printf("%s%d -- U %02d -- Message to user %d\n", padding, (int) time(NULL), i, dest); sprintf(text, "A message from me (%d) to you (%d)", i, dest); user_send_text_message(i, dest, text, sw); } /* Check the incoming box for simple messages */ if(receive_message(qid, TYPE_TEXT, &in)){ msg_sender = get_sender(&in); get_text(&in, msg_text); printf("%s%d -- U %02d -- Message received\n", padding, (int) time(NULL), i); printf("%s Sender: %d\n", padding, msg_sender); printf("%s Text: %s\n", padding, msg_text); } } } } /* Switch (parent process) */ while(1){ /* Check if some user is answering to service messages */ if(receive_message(sw, TYPE_SERVICE, &in)){ msg_service = get_service(&in); msg_sender = get_sender(&in); switch(msg_service){ case SERVICE_CONNECT: /* A new user has connected */ printf("%d -- S -- Service: connection\n", (int) time(NULL)); printf(" User: %d\n", msg_sender); break; case SERVICE_DISCONNECT: /* The user is terminating */ printf("%d -- S -- Service: disconnection\n", (int) time(NULL)); printf(" User: %d\n", msg_sender); deadproc++; break; case SERVICE_QID: /* The user is sending us its queue id */ msg_service_data = get_service_data(&in); printf("%d -- S -- Service: queue\n", (int) time(NULL)); printf(" User: %d\n", msg_sender); printf(" Qid: %d\n", msg_service_data); queues[msg_sender] = msg_service_data; break; case SERVICE_TIME: msg_service_data = get_service_data(&in); /* Timing informations */ timing[msg_sender][1] = msg_service_data - timing[msg_sender][1]; printf("%d -- S -- Service: timing\n", (int) time(NULL)); printf(" User: %d\n", msg_sender); printf(" Timing: %d\n", timing[msg_sender][1]); /* The user is no more blocked by a timing operation */ timing[msg_sender][0] = 0; break; } } /* Check if some user has connected */ if(receive_message(sw, TYPE_TEXT, &in)){ msg_recipient = get_recipient(&in); msg_sender = get_sender(&in); get_text(&in, msg_text); /* If the destination is connected */ if(queues[msg_recipient] != sw){ /* Send the message (forward it) */ switch_send_text_message(msg_sender, msg_text, queues[msg_recipient]); printf("%d -- S -- Routing message\n", (int) time(NULL)); printf(" Sender: %d -- Destination: %d\n", msg_sender, msg_recipient); printf(" Text: %s\n", msg_text); } else{ unreachable_destinations[msg_sender] += 1; if (unreachable_destinations[msg_sender] > MAXFAILS) { continue; } printf("%d -- S -- Unreachable destination\n", (int) time(NULL)); printf(" Sender: %d -- Destination: %d\n", msg_sender, msg_recipient); printf(" Text: %s\n", msg_text); printf(" Threshold: %d/%d\n", unreachable_destinations[msg_sender], MAXFAILS); if (unreachable_destinations[msg_sender] == MAXFAILS) { printf("%d -- S -- User %d reached max unreachable destinations\n", (int) time(NULL), msg_sender); switch_send_terminate(queues[msg_sender]); /* Remove its queue from the list */ queues[msg_sender] = sw; } } /* Randomly request a service to the sender of the last message */ if((random_number(100) < service_probability) && (queues[msg_sender] != sw)){ if (random_number(100) < 40){ /* The user must terminate */ printf("%d -- S -- User %d chosen for termination\n", (int) time(NULL), msg_sender); switch_send_terminate(queues[msg_sender]); /* Remove its queue from the list */ queues[msg_sender] = sw; } else { /* Check if we are already timing that user */ if(!timing[msg_sender][0]){ timing[msg_sender][0] = 1; timing[msg_sender][1] = (int) time(NULL); printf("%d -- S -- User %d chosen for timing...\n", timing[msg_sender][1], msg_sender); switch_send_time(queues[msg_sender]); } } } } else{ if(deadproc == users_number){ /* All childs have been terminated, just wait for the last to complete its jobs */ waitpid(pid, &status, 0); /* Remove the switch queue */ remove_queue(sw); printf("\n"); printf("No more active users. Switch turns off.\n"); /* Terminate the program */ exit(0); } } } }