示例#1
0
void DD::ThreadFunction()
{
	int status;
	char msg[64];

	channel_id = ChannelCreate(_NTO_CHF_FIXED_PRIORITY);

	chrono->PrintEvent((char*) "DD Thread Started");

	while (1)
	{
		status = MsgReceive(channel_id, &msg, sizeof(msg), NULL);

		if (status != 0)
			continue;

		chrono->PrintEvent((char*) "DD Pulse Signal");

		Execute();
	}
}
示例#2
0
文件: Working.c 项目: ejoonie/mutex
void *server(int server_priority)
{
	int rcvid, status;

	char myRMessage[BUFSIZE];
	struct _msg_info my_msg_info;

	pid = getpid();
	chid = ChannelCreate(NULL);
	if (chid == -1) {
		perror("error creating a channel\n");
		exit(EXIT_FAILURE);
	}

	printf("the server started with pid: %d, chid: %d, priority: %d"
			, pid, chid, server_priority);

	while(1)
	{
		rcvid = MsgReceive(chid, myRMessage, BUFSIZE, &my_msg_info);

		printf("the server received message from %d with priority %d\n",my_msg_info.tid, my_msg_info.priority);

		printf("before server working for %d", my_msg_info.tid);
		working(my_msg_info.tid);
		printf("after server working for %d", my_msg_info.tid);

		status = MsgReply(rcvid, 0, NULL, 0);
		if (status == -1)
		{
			perror("error in reply\n");
			exit(EXIT_FAILURE);
		}

		printf("the server replied to %d.\n", my_msg_info);
	}


	return;
}
void *time_update( void *ptr )
{
	 struct sigevent         event;
	 struct itimerspec       itime;
	 timer_t                 timer_id;
	 int                     chid, rcvid;
	 my_message_t            msg;

	 chid = ChannelCreate(0);

	 event.sigev_notify = SIGEV_PULSE;
	 event.sigev_coid = ConnectAttach(ND_LOCAL_NODE, 0,
	                                    chid,
	                                    _NTO_SIDE_CHANNEL, 0);
	 event.sigev_priority = getprio(0);
	 event.sigev_code = MY_PULSE_CODE;
	 timer_create(CLOCK_REALTIME, &event, &timer_id);

	 itime.it_value.tv_sec = 0;
	 /* 100 ms = .1 secs */
	 itime.it_value.tv_nsec = 100000000;
	 itime.it_interval.tv_sec = 0;
	 /* 100 ms = .1 secs */
	 itime.it_interval.tv_nsec = 100000000;
	 timer_settime(timer_id, 0, &itime, NULL);
	 // This for loop will update the global_time for every 100 ms which is 1 minute in simulation time.
	 for (;;) {
	     rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
	     if (rcvid == 0) { /* we got a pulse */
	          if (msg.pulse.code == MY_PULSE_CODE) {
	          	if (global_time > 0)
	        	  global_time--;
	          	else
	          		break;
	            //printf("we got a pulse from our timer and time = %d\n", global_time);
	          } /* else other pulses ... */
	     } /* else other messages ... */
    }
}
示例#4
0
void send_timed_msg(char *sendmsg) {
	int rcvid;
	MessageT msg;

	chid = ChannelCreate(0);
	if( chid  == -1 ) {
		fprintf(stderr, "%s: couldn't create channel!\n", progname);
		perror(NULL);
		exit(EXIT_FAILURE);
	}
	init_pulse_and_timer();

	// constant checking for a pulse or message
	while(1) {
		rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
		if(rcvid == 0) {
			got_pulse(); 				// received a pulse
		} else {
			got_msg(rcvid, &msg.msg);	// received a message
		}
	}
}
示例#5
0
int 
main(void) {
	int rcvid;
	msg_buf_t msg; 
	int status;
	int checksum;
	name_attach_t* attach;
	
    setvbuf (stdout, NULL, _IOLBF, 0);   //set IO to stdout to be line buffered	
	
	attach = name_attach(NULL, SERVER_NAME, 0);//PUT CODE HERE to attach a name
	if(NULL == attach) {                //was there an error creating the channel?
		perror("name_attach()");  //look up the errno code and print
		exit(EXIT_FAILURE);            
	}
	
	while(1) {
		rcvid = MsgReceive(attach->chid, &msg, sizeof msg, NULL);//PUT CODE HERE to receive msg from client, store the receive id in rcvid
		if(rcvid == -1) {            //was there an error receiving msg?
			perror("MsgReceive");     //look up errno code and print
			continue;                    //try receiving another msg
		}
		else if(rcvid == 0) {
			printf("received pulse, code = %d\n", msg.pulse.code);
			continue;
		}
		
		printf("received msg: %s\n", msg.cksum.string_to_cksum);
		checksum = calculate_checksum(msg.cksum.string_to_cksum);
		
		status = MsgReply(rcvid, EOK, &checksum, sizeof checksum);//PUT CODE HERE TO reply to client with checksum, store the return status in status
		if(-1 == status) {
			perror("MsgReply");
		}
	}  
	return 0;		 
}
示例#6
0
int main(int argc, char *argv[]) {
	uint32_t l;
	int id, id2;
	my_data_t msg;
	int rcvid;

	name_attach_t *name;

	printf("Welcome Onda\n");

	if (ThreadCtl(_NTO_TCTL_IO, 0) < 0) {
		perror(NULL);
		return -1;
	}

	name = name_attach(NULL, "onda", NAME_FLAG_ATTACH_GLOBAL);
	if (name == NULL) {
		perror("Error0\n");
		return -1;
	}

	/* attach GPIO interrupt */
	id = InterruptAttach (33, gpio_isr_handler, NULL, 0, _NTO_INTR_FLAGS_PROCESS);

	/* attach timer interrupt */
	id2 = InterruptAttach (45, timer_isr_handler, NULL, 0,  _NTO_INTR_FLAGS_PROCESS);

	gpio5 = mmap_device_io(OMAP3530_GPIO_SIZE, OMAP3530_GPIO5_BASE);
	if (gpio5 == MAP_DEVICE_FAILED) {
		perror(NULL);
		return -1;
	}

	//gpt3 = mmap_device_io(OMAP3530_GPT_SIZE, OMAP3530_GPT3_BASE);
	gpt9 = mmap_device_io(OMAP3530_GPT_SIZE, OMAP3530_GPT9_BASE);
	if (gpt9 == MAP_DEVICE_FAILED) {
		perror(NULL);
		return -1;
	}

	sys = mmap_device_io(OMAP3530_SYSCTL_SIZE, OMAP3530_SYSCTL_BASE);
	if (sys == MAP_DEVICE_FAILED) {
		perror(NULL);
		return -1;
	}

	/* selecting mode 4 function - GPIO 139
	 * selecting pullup and mode 4 function - GPIO 138 */
#define SYS_CONF	((4 << 16) | ((1 << 8) | (1<<3) | 4))
#define SYS_MASK	~(0x10F010F)
	l = (in32(sys + 0x168) &  SYS_MASK) | SYS_CONF;
	//l = (in32(sys + 0x168) & ~(7<<16) ) | (4 << 16);
	//out32(sys + 0x168, ((1<<3 | 4) << 16) | (1<<3) | 4);
	out32(sys + 0x168, l);

	/* setting mode 2 - PWM */
	l = (in32(sys + 0x174) & ~7 ) | 2;
	out32(sys + 0x174, l);

	/* setting the PIN 138 to input
	 * setting the PIN 139 to output */
	l = (in32(gpio5 + OMAP2420_GPIO_OE) & ~(1 << 11)) | 1 << 10;
	out32(gpio5 + OMAP2420_GPIO_OE, l);

	/* enabling interrupt on both levels on GPIO 139 */
	out32(gpio5 + OMAP2420_GPIO_RISINGDETECT, l << 10);
	out32(gpio5 + OMAP2420_GPIO_FALLINGDETECT, l << 10);
	out32(gpio5 + OMAP2420_GPIO_SETIRQENABLE1, l << 10);

	/* make sure timer has stop */
	out32(gpt9 + OMAP3530_GPT_TCLR, 0);

	/* enabling the interrupt */
	out32(gpt9 + OMAP3530_GPT_TIER, 2); //comentar se PWM

	/* configuring PWM */
	out32(gpt9 + OMAP3530_GPT_TCLR, (1<<12) | (1<<10) | (1<<7)); //-- PWM

	out32(gpio5 + OMAP2420_GPIO_SETDATAOUT, (1 << 11));

	printf("Esperando requisições\n");

	while (1) {
		rcvid = MsgReceive(name->chid, &msg, sizeof(msg), NULL);

		if (rcvid == -1) {/* Error condition, exit */
			break;
		}
		/* name_open() sends a connect message, must EOK this */
		if (msg.hdr.type == _IO_CONNECT) {
			MsgReply(rcvid, EOK, NULL, 0);
			continue;
		}

		/* Some other QNX IO message was received; reject it */
		if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX) {
			MsgError(rcvid, ENOSYS);
			continue;
		}
		switch (msg.hdr.subtype) {
		case 0x55:
			MsgReply(rcvid, EOK, &pincount, sizeof(pincount));
			break;

		case 0x65:
			MsgReply(rcvid, EOK, &interval, sizeof(interval));
			break;

		case 0x66:
			interval = msg.data;
			MsgReply(rcvid, EOK, &interval, sizeof(interval));
			break;

		default:
			MsgReply(rcvid, EOK, NULL, 0);
		}
	}
	out32(gpt9 + OMAP3530_GPT_TCLR, 0);
	out32(gpt9 + OMAP3530_GPT_TIER, 0);
	InterruptDetach (id);
	InterruptDetach (id2);
	printf("Fim\n");

	return EXIT_SUCCESS;
}
示例#7
0
int server() {
   name_attach_t *attach;
   mss_t msg;
   mss_t rmsg;

   //my_data_t msg;
   int rcvid;

   /* Create a local name (/dev/name/local/...) */
   if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL) {

       return EXIT_FAILURE;
   }

   /* Do your MsgReceive's here now with the chid */
   while (1) {
       rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);

       if (rcvid == -1) {/* Error condition, exit */
           break;
       }

      // if (rcvid == 0) {/* Pulse received */
       //    switch (msg.hdr.code) {
       //    case _PULSE_CODE_DISCONNECT:
               /*
                * A client disconnected all its connections (called
                * name_close() for each name_open() of our name) or
                * terminated
                */

       //        ConnectDetach(msg.hdr.scoid);
      //         break;
      //     case _PULSE_CODE_UNBLOCK:
               /*
                * REPLY blocked client wants to unblock (was hit by
                * a signal or timed out).  It's up to you if you
                * reply now or later.
       //         */
      //         break;
       //    default:
               /*
                * A pulse sent by one of your processes or a
                * _PULSE_CODE_COIDDEATH or _PULSE_CODE_THREADDEATH
                * from the kernel?
                */
         //      break;
        //   }
       //    continue;
     //  }

       /* name_open() sends a connect message, must EOK this */
 //      if (msg.hdr.type == _IO_CONNECT ) {
    //       MsgReply( rcvid, EOK, NULL, 0 );
    //       continue;
    //   }

       /* Some other QNX IO message was received; reject it */
      // if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX ) {
     //      MsgError( rcvid, ENOSYS );
     //      continue;
     //  }

       /* A message (presumable ours) received, handle */
       printf("Server receive text :%s \n", msg.text);

       //czyszcze rmsg.text przed ponownym urzyciem
       memset(&rmsg.text[0], 0, sizeof(rmsg.text));

       rmsg.from = getpid();
       rmsg.typ = 1;
       rmsg.ile = 0;//tu modyf


       int i = 0;
      // for(i = 0; i < strlen(msg.text); i++)
      //       	rmsg.text[i] = msg.text[i];



       char letter ;
       for(i = 0; i < strlen(msg.text); i++){
       		//if(islower(msg.text[i]) ){
             letter = toupper(msg.text[i]);
           //  rmsg.text[i] = letter;//844
    	   rmsg.text[i]  = letter;
    			   //msg.text[i];
       		//}
       		//}
	}

       printf("server will send text : %s\n", rmsg.text);


       //rmsg.text[1] = 's';
       MsgReply(rcvid, EOK, &rmsg, sizeof(rmsg));

   }

   /* Remove the name from the space */
   name_detach(attach, 0);

   return EXIT_SUCCESS;
}
示例#8
0
/*
 * Function     - operation_thread()
 *
 * Arguments    - <args> Pointer to this thread's arguments
 *
 * Return Value - Pointer to the return value
 */
void * operation_thread(void * args)
{
   uint8_t port_val = 0;
   uint32_t total_time = 0;
   uint32_t count = 0, sec = 0;
   sint32_t rcv_id;

#if defined (__ARM__)
   sint32_t temp_high = 0, temp_low = 0;
#endif   // #if defined (__ARM__)

   // Setup the timer for PWM
   __pwm_setup();

   // Wait for timer pulse
   for (;;)
   {
      rcv_id = MsgReceive(channel_id, &timer_msg, sizeof(timer_msg), NULL);
      if(rcv_id == 0)
      {
         if(timer_msg.pulse.code == __TIMER_PULSE_CODE)
         {
            if(__OP_IDLE == state)
            {
               sec = 0;
               count = 0;
               total_time = 0;
            }
            else
            {
               if(0 == local_vol)
               {
                  state = __OP_IDLE;

                  if(0 == pthread_mutex_lock(&operation_mutex))
                  {
                     operation = __OP_COMPLETE;
                     pthread_mutex_unlock(&operation_mutex);
                  }
               }

               if(1000 == ++count)
               {
                  count = 0;
                  sec++;
               }

               if(60 == sec)
               {
                  sec = 0;
                  total_time++;

                  if(local_vol >= local_flowrate)
                     local_vol -= local_flowrate;
                  else
                     local_vol = 0;

                  if(0 == pthread_mutex_lock(&operation_mutex))
                  {
                     op_percentage = 100 - ((local_vol * 100) / start_vol);
                     pthread_mutex_unlock(&operation_mutex);
                  }
               }
            }

#if defined (__ARM__)
            // PWM pulse
            if(0 < --temp_high)
            {
               port_val = in8(gpio_base + 0);
               port_val |= GPIO_SERVO_PIN;
               out8(gpio_base + 0, port_val);
            }
            else if(0 < --temp_low)
            {
               port_val = in8(gpio_base + 0);
               port_val &= (uint8_t)(~(GPIO_SERVO_PIN));
               out8(gpio_base + 0, port_val);
            }
            else if(__OP_IDLE == state)
            {
               temp_high = __DEFALT_DUTY_CYCLE;
               temp_low = __DEFALT_DUTY_CYCLE;
            }
            else
            {
               temp_high = steps_high;
               temp_low = steps_low;
            }
#endif   // #if defined (__ARM__)
         }
      }
   }

   return ((void *)NULL);
}
示例#9
0
/****************************************************************************
*
*						Subroutine main
*
*****************************************************************************/
int main(int argc, char *argv[])
{
	int tlkilled,tlpid, rc,status;  /*tlpid=trace logger pid */
	struct traceparser_state * tp_state;
	char message[200];
	pthread_t cur_thread;

	/*
	 * Start the tests.
	 */
	teststart(argv[0]);
	/* Get rid of tracelogger if it is running  */
	tlkilled=kill_tl();

	/* Setup a channel for the MsgSend Events */
	chid=ChannelCreate(0);
	assert(chid!=-1);
	
	/* Setup the barrier used to syncronize */
	rc=pthread_barrier_init(&global_barrier, NULL, 2);
	assert(rc==EOK);

	/* Setup the mutex for the mutex/condvar state test */
	rc=pthread_mutex_init(&mymutex,NULL);	
	assert(rc==EOK);

	/* Setup the condvar for the condvar state test */
	rc=pthread_cond_init(&mycondvar,NULL);	
	assert(rc==EOK);

	/* setup the sem tfor the sem state test */
	rc=sem_init(&mysem, 0,0);
	assert(rc==0);

	/* Setup the needed child */
	child_pid=fork();
	assert(child_pid!=-1);
	if (child_pid==0) {
		/* This child is used only in the stopped state test.
 		 * it will just sit and loop
		 */
		while (1) {
			delay(10);
		}
		exit(0);
	}

	/* and create a thread to go into various states */
	rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
	assert(rc==EOK);
	for (cur_state=STATE_DEAD;cur_state<=STATE_SEM;cur_state++) {
		/* these states can not be reliably and or safely triggered. */
		if ((cur_state==STATE_STACK) || (cur_state==STATE_WAITPAGE) || cur_state==STATE_INTR)
			continue;
	
	
		/***********************************************************************/
	
		/***********************************************************************/
		/*
		 * Make sure that if we trigger a thread state, that it gets logged
		 * properly (all the information in the tracelogger is correct)
		 * This tests the information provided in wide mode.
		 */
		snprintf(message, sizeof(message),"%s in wide mode", state_str[cur_state]);
	 	testpntbegin(message);

		exp_thread=cur_thread;
			
		/* We need to start up the tracelogger in daemon mode, 1 itteration.
		 * we will filter out everything other then thread states, then 
		 * start logging. 
		 * We then will trigger a thread state change, and flush the trace buffer. 
		 * This  should create a VERY minimal trace buffer that will be easily parsed
		 */
		tlpid=start_logger();
		sleep(1);
		/* Set the logger to wide emmiting mode */
		rc=TraceEvent(_NTO_TRACE_SETALLCLASSESWIDE);
		assert(rc!=-1);
		fast_mode=WIDE;
		/* Add the given thread event in the thread class back in */
		rc=TraceEvent(_NTO_TRACE_ADDEVENT, _NTO_TRACE_THREAD,(1<<cur_state));
		assert(rc!=-1);
		/* Filter out all tids other then the state_thread */
		if  (cur_state==STATE_STOPPED) {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, child_pid, 1);
		} else {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, getpid(),cur_thread);
		}
		assert(rc!=-1);

		/* then trigger an event.  Logging is started inside the state thread
		 * right before it tries to trigger the given state.
		 * the two barrier waits are to 
		 * 1) Tell the state thread that everything is setup so it should trigger the event
		 * 2) Wait for the state thread to tell us it has finished.
		 */
		pthread_barrier_wait(&global_barrier);

		if ((cur_state==STATE_SEND)|| (cur_state==STATE_REPLY)) {
			/* If the thread is going into the send state, we should receive and reply */
			sleep(1);
			status=MsgReceive(chid, message, sizeof(message), NULL);
			MsgReply(status, EOK, "ok", 3);
		} else if (cur_state==STATE_RECEIVE) {
			/* If the thread is going to call reveive, we should send it a message */
			sleep(1);
			status=ConnectAttach(0, getpid(), chid, _NTO_SIDE_CHANNEL, 0);
			MsgSend(status, message, 10, message,10);
		} else if (cur_state==STATE_MUTEX) {
			pthread_mutex_lock(&mymutex);
			sleep(2);
			pthread_mutex_unlock(&mymutex);
		} else if (cur_state==STATE_CONDVAR) {
			sleep(2);
			pthread_cond_signal(&mycondvar);
		} else if (cur_state==STATE_SEM) {
			sleep(2);
			sem_post(&mysem);
		}
		
		/* If the state thread is going to try to trigger the dead state, it will have to
		 * exit, so we can not expect it to call barrier_wait to tell us it's done. 
		 */
		if ((1<<cur_state)!=_NTO_TRACE_THDEAD) {
			pthread_barrier_wait(&global_barrier);
		} else {
			/* If the state thread is going to exit, then we should just
 			 * give it time to exit, then restart it.
			 */
			sleep(2); 
			rc=pthread_join(cur_thread, (void **)&status);
			assert(rc==EOK);
			rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
		}
		delay(100);
		
		/* flush the trace buffer and wait for the tracelogger to exit*/
		rc=TraceEvent(_NTO_TRACE_FLUSHBUFFER);	
		assert(rc!=-1);
		rc=waitpid(tlpid, &status, 0);
		assert(tlpid==rc);
	
		/* Now, setup the traceparser lib to pull out the thread state events, 
		 * and make sure our event shows up 
		 */
		tp_state=traceparser_init(NULL);
		assert(tp_state!=NULL);
		traceparser_cs(tp_state, NULL, parse_cb, _NTO_TRACE_THREAD, (1<<cur_state));
	
		/* Since we don't want a bunch of output being displayed in the 
		 * middle of the tests, turn off verbose output.
		 */
		traceparser_debug(tp_state, stdout, _TRACEPARSER_DEBUG_NONE);
		/* Set correct_values to 0, so we can see if the callback actually
		 * got called. 
		 */
		correct_values=0;
		/* And parse the tracebuffer */
		traceparser(tp_state, NULL, "/dev/shmem/tracebuffer");
		
		if (correct_values==0) 
			testpntfail("Our callback never got called, no events?");
		else if (correct_values==-1)
			testpntfail("Got the wrong thread state");
		else if (correct_values==-2) 
			testpntfail("Got the wrong pid");
		else if (correct_values==-3)
			testpntfail("Got the wrong tid");
		else if (correct_values==1)
			testpntpass("Got the correct values");
		else 
			testpntfail("This should not happen");

		traceparser_destroy(&tp_state);
	 	testpntend();
		/***********************************************************************/
	
		/***********************************************************************/
		/*
		 * Make sure that if we trigger a thread state, that it gets logged
		 * properly (all the information in the tracelogger is correct)
		 * This tests the information provided in fast mode.
		 */
		snprintf(message, sizeof(message),"%s in fast mode", state_str[cur_state]);
	 	testpntbegin(message);

		exp_thread=cur_thread;
			
		/* We need to start up the tracelogger in daemon mode, 1 itteration.
		 * we will filter out everything other then thread states, then 
		 * start logging. 
		 * We then will trigger a thread state change, and flush the trace buffer. 
		 * This  should create a VERY minimal trace buffer that will be easily parsed
		 */
		tlpid=start_logger();
		sleep(1);
		/* Set the logger to fast emmiting mode */
		rc=TraceEvent(_NTO_TRACE_SETALLCLASSESFAST);
		assert(rc!=-1);
		fast_mode=FAST;
		/* Add the given thread event in the thread class back in */
		rc=TraceEvent(_NTO_TRACE_ADDEVENT, _NTO_TRACE_THREAD,(1<<cur_state));
		assert(rc!=-1);
		/* Filter out all tids other then the state_thread */
		if  (cur_state==STATE_STOPPED) {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, child_pid, 1);
		} else {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, getpid(),cur_thread);
		}
		assert(rc!=-1);

		/* then trigger an event.  Logging is started inside the state thread
		 * right before it tries to trigger the given state.
		 * the two barrier waits are to 
		 * 1) Tell the state thread that everything is setup so it should trigger the event
		 * 2) Wait for the state thread to tell us it has finished.
		 */
		pthread_barrier_wait(&global_barrier);

		if ((cur_state==STATE_SEND)|| (cur_state==STATE_REPLY)) {
			/* If the thread is going into the send state, we should receive and reply */
			sleep(1);
			status=MsgReceive(chid, message, sizeof(message), NULL);
			MsgReply(status, EOK, "ok", 3);
		} else if (cur_state==STATE_RECEIVE) {
			/* If the thread is going to call reveive, we should send it a message */
			sleep(1);
			status=ConnectAttach(0, getpid(), chid, _NTO_SIDE_CHANNEL, 0);
			MsgSend(status, message, 10, message,10);
		} else if (cur_state==STATE_MUTEX) {
			pthread_mutex_lock(&mymutex);
			sleep(2);
			pthread_mutex_unlock(&mymutex);
		} else if (cur_state==STATE_CONDVAR) {
			sleep(2);
			pthread_cond_signal(&mycondvar);
		} else if (cur_state==STATE_SEM) {
			sleep(2);
			sem_post(&mysem);
		}
		
		/* If the state thread is going to try to trigger the dead state, it will have to
		 * exit, so we can not expect it to call barrier_wait to tell us it's done. 
		 */
		if ((1<<cur_state)!=_NTO_TRACE_THDEAD) {
			pthread_barrier_wait(&global_barrier);
		} else {
			/* If the state thread is going to exit, then we should just
 			 * give it time to exit, then restart it.
			 */
			sleep(2); 
			rc=pthread_join(cur_thread, (void **)&status);
			assert(rc==EOK);
			rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
		}
		delay(100);
		
		/* flush the trace buffer and wait for the tracelogger to exit*/
		rc=TraceEvent(_NTO_TRACE_FLUSHBUFFER);	
		assert(rc!=-1);
		rc=waitpid(tlpid, &status, 0);
		assert(tlpid==rc);
	
		/* Now, setup the traceparser lib to pull out the thread state events, 
		 * and make sure our event shows up 
		 */
		tp_state=traceparser_init(NULL);
		assert(tp_state!=NULL);
		traceparser_cs(tp_state, NULL, parse_cb, _NTO_TRACE_THREAD, (1<<cur_state));
	
		/* Since we don't want a bunch of output being displayed in the 
		 * middle of the tests, turn off verbose output.
		 */
		traceparser_debug(tp_state, stdout, _TRACEPARSER_DEBUG_NONE);
		/* Set correct_values to 0, so we can see if the callback actually
		 * got called. 
		 */
		correct_values=0;
		/* And parse the tracebuffer */
		traceparser(tp_state, NULL, "/dev/shmem/tracebuffer");
		
		if (correct_values==0) 
			testpntfail("Our callback never got called, no events?");
		else if (correct_values==-1)
			testpntfail("Got the wrong thread state");
		else if (correct_values==-2) 
			testpntfail("Got the wrong pid");
		else if (correct_values==-3)
			testpntfail("Got the wrong tid");
		else if (correct_values==1)
			testpntpass("Got the correct values");
		else 
			testpntfail("This should not happen");

		traceparser_destroy(&tp_state);
	 	testpntend();
		/***********************************************************************/

	}
	/* If the tracelogger was running when we started, we should restart it again */
	if (tlkilled==1) 
		system("reopen /dev/null ; tracelogger -n 0 -f /dev/null &");
	/* Kill off the child we had forked earler */
	kill (child_pid, SIGKILL);
	teststop(argv[0]);
	return 0;
}
示例#10
0
/****************************************************************************
*
*						Subroutine state_thread
*
*	Purpose: 	This is a thread that is used to trigger the various thread
*				states
*
*	Parameters:	None
*
*	Returns:	Nothing
*			
*
*****************************************************************************/
void * state_thread(void * arg)
{
	int rc,x,coid;
	sigset_t myset;
	uint64_t timeout;
	struct sigevent myevent;
	pthread_t mythread;
	char buf[100];
	while(1) {
		/* Syncronize with the main thread. */
		pthread_barrier_wait(&global_barrier);
		switch (cur_state) {
			case STATE_DEAD: 
				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				/* Trigger the dead state by calling pthread_exit */
				pthread_exit(NULL);
				/* Should never get here */
				abort();
			case STATE_READY: 
				exit_now=0;
				for (x=0;x<_syspage_ptr->num_cpu;x++)
					pthread_create(NULL, NULL, ready_thread, NULL);
				/*  Let the new threads get started */
				sleep(1);
			case STATE_RUNNING: 
				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				/* Trigger the running state by just doing some work. 
				 * this should also trigger a ready state before
				 * we are running
				 */
				x=0;
				while(x<10)
					x++;
				exit_now=1;
				while(x<1000)
					x++;
				exit_now=1;
				/* and unblock the parent */
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_STOPPED: 

				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(100);
				kill (child_pid, SIGSTOP);
				delay(10);
				kill (child_pid, SIGCONT);
				delay(100);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_SEND: 
			case STATE_REPLY: 
				coid=ConnectAttach(0, getpid(), chid, _NTO_SIDE_CHANNEL, 0);
				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				/* Trigger the SEND/REPLY blocked states */
				MsgSend(coid, buf, 10, buf,10);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_RECEIVE: 
				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				/* Trigger a receive state  */
				rc=MsgReceive(chid, buf, sizeof(buf), NULL);
				MsgReply(rc, EOK, "ok", 3);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_WAITTHREAD: 
				/* Start the logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				/* Trigger a waitthread state  */
				pthread_create(NULL, NULL, nothing_thread, NULL);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_SIGSUSPEND: 
				memset(&myevent, 0, sizeof(myevent));
				myevent.sigev_notify = SIGEV_UNBLOCK;
				timeout = 1*1000000000L;
	
				sigemptyset(&myset);
				sigaddset(&myset, SIGHUP);
				sigaddset(&myset, SIGBUS);
				sigaddset(&myset, SIGSEGV);
				sigaddset(&myset, SIGXCPU);
				sigaddset(&myset, SIGRTMIN);
				sigaddset(&myset, SIGRTMAX);
		
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				TimerTimeout( CLOCK_REALTIME, _NTO_TIMEOUT_SIGSUSPEND,&myevent, &timeout, NULL );
				SignalSuspend(&myset);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_SIGWAITINFO: 
				memset(&myevent, 0, sizeof(myevent));
				myevent.sigev_notify = SIGEV_UNBLOCK;
				timeout = 1*1000000000L;
	
				sigemptyset(&myset);
				sigaddset(&myset, SIGHUP);
				sigaddset(&myset, SIGBUS);
				sigaddset(&myset, SIGSEGV);
				sigaddset(&myset, SIGXCPU);
				sigaddset(&myset, SIGRTMIN);
				sigaddset(&myset, SIGRTMAX);
		
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				TimerTimeout( CLOCK_REALTIME, _NTO_TIMEOUT_SIGWAITINFO,&myevent, &timeout, NULL );
				SignalWaitinfo(&myset,NULL);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_NANOSLEEP:
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				sleep(1);
				sleep(1);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_MUTEX:
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				sleep(1);
				pthread_mutex_lock(&mymutex);
				pthread_mutex_unlock(&mymutex);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_CONDVAR:
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				sleep(1);
				pthread_mutex_lock(&mymutex);
				pthread_cond_wait(&mycondvar, &mymutex);
				pthread_mutex_unlock(&mymutex);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_JOIN:
				pthread_create(&mythread, NULL, nothing_thread, NULL);
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				delay(10);
				pthread_join(mythread, NULL);
				pthread_barrier_wait(&global_barrier);
				break;
			case STATE_SEM:
				/* Start logging */
				rc=TraceEvent(_NTO_TRACE_STARTNOSTATE);
				assert(rc!=-1);
				sleep(1);
				sem_wait(&mysem);
				pthread_barrier_wait(&global_barrier);
				break;
			
		}
	}
	
}
示例#11
0
int main(int argc, char *argv[]) {
    int server_coid, self_coid, chid, rcvid;
    struct reg_msg msg;

    setvbuf (stdout, NULL, _IOLBF, 0);

    /* look for server */
    server_coid = name_open( RECV_NAME, 0 );
    while( server_coid == -1 )
    {  
      sleep(1);
      server_coid = name_open( RECV_NAME, 0 );
    }

    chid = ChannelCreate(0);
    if( -1 == chid)
    {
        perror( PROGNAME "ChannelCreate");
        exit( EXIT_FAILURE );
    }
    self_coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );
    if( -1 == self_coid )
    {
        perror( PROGNAME "ConnectAttach");
        exit( EXIT_FAILURE );
    }
    
    msg.type = REG_MSG;
    
    /* class: Initialize the sigevent structure (msg.ev) in the message 
     * to be sent to the server.
     */
    SIGEV_PULSE_INIT( &msg.ev, self_coid, getprio(0), MY_PULSE_CODE, 0 );

    if (MsgSend( server_coid, &msg, sizeof( msg ), NULL, 0 ))
    {
        perror(PROGNAME "MsgSend");
        exit( EXIT_FAILURE );
    }
    
    while( 1 )
    {
        rcvid = MsgReceive( chid, &recv_buf, sizeof(recv_buf), NULL );
        if( -1 == rcvid )
        {
            perror(PROGNAME "MsgReceive");
            continue;
        }
        if ( 0 == rcvid )
        {
            if (MY_PULSE_CODE == recv_buf.pulse.code )
            {
                printf(PROGNAME "got my pulse, value is %d\n", recv_buf.pulse.value.sival_int);
            } else
            {
                printf(PROGNAME "got unexpected pulse with code %d, value %d\n", 
                        recv_buf.pulse.code, recv_buf.pulse.value.sival_int );
            }
            continue;
        }
        printf(PROGNAME "got unexpected message, type: %d\n", recv_buf.type );
        MsgError( rcvid, ENOSYS );
    }
 }
示例#12
0
int main(int argc, char *argv[])
{
    name_attach_t *att;
    int rcvid;
    struct _msg_info msg_info;
    struct sigevent sigev;
    int self_coid;
    int achid;
    struct _asyncmsg_get_header *agh, *agh1;

    /* register my name so client can find me */
    att = name_attach(NULL,RECV_NAME, 0 );
    if (NULL == att )
    {
        perror(PROGNAME "name_attach()");
        exit(EXIT_FAILURE);
    }

    /* create a connection to the synchronous channel created by the
     * name_attach() call.  Will use this to specify where the pulses
     * flagging async data available should be delivered.
     */
    
    self_coid = ConnectAttach( 0, 0, att->chid, _NTO_SIDE_CHANNEL, 0 );
    if( -1 == self_coid )
    {
        perror(PROGNAME "ConnectAttach");
        exit( EXIT_FAILURE );
    }
    /* and fill in the event structure to describe a priority 10 pulse
     * to be delivered to my synchronous channel */
     
    SIGEV_PULSE_INIT( &sigev, self_coid, 10, PULSE_ASYNCH_EVENT, 0 );

    /* create an asynchrounous channel with automatic buffering
     *   it will not block an asyncmsg_get() call if there are no messages available
     *   it will receive up to 10 messages of up to 1024 bytes each at once
     *   It will get a pulse notification when the queue of available messages goes
     *     from empty to non-empty
     */
     
    achid = asyncmsg_channel_create( _NTO_CHF_ASYNC_NONBLOCK, 0666, 1024, 10, &sigev, NULL );
    
    if( -1 == achid )
    {
        perror( "asyncmsg_channel_create");
        exit( EXIT_FAILURE );
    }
    
    while(1)
    {
        rcvid = MsgReceive( att->chid, &recv_buf, sizeof (recv_buf), &msg_info );
        
		if( -1 == rcvid )
        {
            perror(PROGNAME "MsgReceive failed");
            continue;
        }
        if ( 0 == rcvid )
        {
            /* we received a pulse */
            printf("got a pulse\n");
            switch( recv_buf.pulse.code )
            {
                /* system disconnect pulse */
                
                case _PULSE_CODE_DISCONNECT:
                    ConnectDetach( recv_buf.pulse.scoid );
                    printf(PROGNAME "disconnect from a client %X\n", recv_buf.pulse.scoid);
                    break;
                /* our pulse - we've got one or more messages */
                
                case PULSE_ASYNCH_EVENT:
                    /* get one or more messages from our channel */
                    agh = asyncmsg_get( achid );
                    if (NULL == agh )
                    {
                        perror("went to get a message, but nothing was there");
                    } else
                    {
                       /* the async receive header is, actually, a linked list of headers
                        * if multiple messages have been received at once, so we need to
                        * walk the list, looking at each header and message in turn */
			
                       while( agh )
                       {
                           printf("the message came from %d in %d parts\n", agh->info.pid, agh->parts);
                           printf("the data is '%s'\n", (char *)(agh->iov->iov_base));
                           agh1 = agh;
                           agh = agh1->next;
                           /* free this message */
                           asyncmsg_free( agh1 );
                        }
                     }

                break;
                default:
                   printf(PROGNAME "unexpect pulse code: %d\n", recv_buf.pulse.code );
                   break;
            }
            continue;
        }
        /* not an error, not a pulse, therefor a message */
        
	if ( recv_buf.type == _IO_CONNECT )
        {
            /* _IO_CONNECT because someone did a name_open() to us, must EOK it.*/
            MsgReply( rcvid, EOK, NULL, 0 );
            continue;
        }
        
	if ( recv_buf.type > _IO_BASE && recv_buf.type <= _IO_MAX )
        {
            /* unexpected system message,probably qconn, error it */
            MsgError( rcvid, ENOSYS );
            continue;
        }
	
        switch( recv_buf.type )
        {
           /* here our client asked for our asynchronous channel id
           * reply with it */
	    
           case GET_ACHID:
              printf("got request for my achid\n");
              MsgReply(rcvid, 0, &achid, sizeof(achid ));

              break;
           default:
              /* some other unexpect message */
              printf(PROGNAME "unexpect message type: %d\n", recv_buf.type);
              MsgError(rcvid, ENOSYS );
              break;
        }
    }
}
示例#13
0
int 
main(void) {
	int rcvid;
	name_attach_t* attach;
	msg_buf_t msg;
	int status;
	int checksum;
	struct _msg_info msg_info;
	listNode_t* list_ptr = NULL;

	
    setvbuf (stdout, NULL, _IOLBF, 0);	
	
	attach = name_attach(NULL, "cksum", 0);
	if(attach == NULL) {                //was there an error creating the channel?
		perror("name_attach");  //look up the errno code and print
		exit(EXIT_FAILURE);            
	}
	
	while(1) {
		printf("Waiting for a message...\n");
		rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), &msg_info); 	//PUT CODE HERE to receive msg from client
		if(rcvid == -1) {            //was there an error receiving msg?
			perror("MsgReceive");     //look up errno code and print
			break;                    //try receiving another msg
		}
		else if(rcvid > 0) {  //msg
			switch(msg.cksum.msg_type) {
				case _IO_CONNECT:    //name_open() within the client may send this 
					MsgReply(rcvid, EOK, NULL, 0); 
					break;
				case CKSUM_MSG_TYPE:
					printf("Message received, client scoid = %d\n", msg_info.scoid);
					list_ptr = add_client_to_list(list_ptr, msg_info.scoid);
					print_list(list_ptr);
	
					checksum = calculate_checksum(msg.cksum.string_to_cksum);
			
					status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum) );
					if(-1 == status) {
						perror("MsgReply");
					}
					break;
				default: 
					MsgReply(rcvid, ENOSYS, NULL, 0); 
					break;
			}
		}
		else if(rcvid == 0) { //message
			switch(msg.pulse.code) {
				case _PULSE_CODE_DISCONNECT:
					printf("received disconnect pulse from client, scoid = %d\n", msg.pulse.scoid);
//					list_ptr = remove_client_from_list(list_ptr, msg.pulse.scoid);
//					if(retp == list_ptr) {
//						printf("can't find client %d in list\n", msg.pulse.scoid);
//					}
//					ConnectDetach(msg.pulse.scoid);
					print_list(list_ptr);
					break;
				default:
					printf("unknown pulse received, code = %d\n", msg.pulse.code);
			}
		}
		else {
			printf("received unexpected msg with rcvid < -1 !!!\n");
		}
	}  
	return 0;		 
}
示例#14
0
//#define CFG_DEBUG_MSG
VOID *NTP_LinkManagementThrdFunc(VOID *pThreadParameter)
{
  E_ERR_T            rstatus = E_ERR_Success;
  INT32             chid;
  struct sigevent   event;
  struct itimerspec itime;
  timer_t           timer_id;
  INT32             rcvid;
  NTP_CH_MSG_T      msg;
  struct timespec   tspec;
  UINT8             uccnt;
  UINT8             ucservercnt;
  BOOL_T            isServerActive = E_TYPE_No;
  NTP_PACKET_T      tx_ntppack;
  NTP_PACKET_T      rx_ntppack;
  UINT8             ucntp_packet_sz;
  UINT8             unretrycnt;
  INT32             rlen;             // receive length


  struct mq_attr    mqstat;
  INT32             msglen;
  SYS_MSGQ_MCPR     msgq;
  struct msq_ctrl_st *pcb;
  NTP_MSGQ_MCP_STATUS ntpcstatus;

  #if ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
  CHAR thrdnamebuff[SYS_THRD_NAME_LEN] = {0};
  CHAR acErrMsg[100] = {0};
  #endif // ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)

  #if (((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP) || (defined CFG_PRN_ERR))
  CHAR              errBuff[100] = {0};
  #endif // ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP) ||
         //  (defined CFG_PRN_ERR))
  #if((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
  struct tm         *pbdtime;
  #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)

  if ((chid = ChannelCreate (0)) == TYP_ERROR)
  {
    #ifdef CFG_PRN_ERR
    printf("ERR  [NTP] NTP_LinkManagementThrdFunc, fail to create channel, %s\n",
            strerror(errno));
    #endif // CFG_PRN_ERR
    return (VOID *)E_ERR_InvalidNullPointer;
  }

  // set up the pulse
  event.sigev_notify = SIGEV_PULSE;
  event.sigev_coid =
    ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0);
  event.sigev_priority = getprio(0);
  event.sigev_code = E_SYS_PULSE_NTPC_LinkMgmt;
  timer_create(CLOCK_REALTIME, &event, &timer_id);

  // set timer value
  // First trigger begin after 10 seconds, subsequent after 60 seconds
  itime.it_value.tv_sec = 15;
  itime.it_value.tv_nsec = 0;
  itime.it_interval.tv_sec = pNTP_CB->poll_frequency;
  itime.it_interval.tv_nsec = 0;
  timer_settime(timer_id, 0, &itime, NULL);

  // construct NTP request packet
  tx_ntppack.flags.allbits = 0xe3;
  tx_ntppack.peerClkStranum = TYP_NULL;
  tx_ntppack.peerPollingInterval = 0x4;
  tx_ntppack.peerClockPrecision = -6;
  tx_ntppack.rootDelay = NTP_Fp64ToFpst32(1.0000);
  tx_ntppack.rootDispersion = NTP_Fp64ToFpst32(1.0000);
  tx_ntppack.referenceClockID = TYP_NULL;
  tx_ntppack.referenceClockUpdateTime = NTP_Fp64ToFpst64(0.0000);
  tx_ntppack.originateTimeStamp = NTP_Fp64ToFpst64(0.0000);
  tx_ntppack.receiveTimeStamp = NTP_Fp64ToFpst64(0.0000);

  ucntp_packet_sz = sizeof(NTP_PACKET_T);

  // set all connection to false
  for(ucservercnt = 0; ucservercnt < CGF_NTP_TOTAL_SERVER; ucservercnt++)
  {
    pNTP_CB->server[ucservercnt].isConnectionGood = E_TYPE_No;
  }

  pcb = &pSYS_CB->msq_ctrl[E_SYS_MSQL_NTPC_TxExternalSystemMsg];

  if(pcb == TYP_NULL)
  {
    #ifdef CFG_PRN_WARN
    printf("ERR  [NTP] NTP_LinkManagementThrdFunc, pcb in null pointer\n");
    #endif // CFG_PRN_WARN
    return TYP_NULL;
  }

  // get message queue attribute
  mq_getattr(pcb->msq_id, &mqstat);
  msgq.msgtype = E_SYS_MCP_NTPClientToSWC;

	  while(1)

  {
    rcvid = MsgReceive (chid, &msg, sizeof (msg), NULL);
    if (rcvid < 0)
    {
      //gotAMessage (rcvid, &msg.msg);
      #ifdef CFG_PRN_ERR
      printf("ERR  [NTP] NTP_LinkManagementThrdFunc, error, %s\n",
             strerror(errno));
      #endif //CFG_PRN_ERR
    }

    if (rcvid > 0)
    {
      //gotAMessage (rcvid, &msg.msg);
      #if((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
      printf("[NTP] NTP_LinkManagementThrdFunc, currently not support message"
             "handling\n");
      #endif //((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))
    }

    if (msg.pulse.code != E_SYS_PULSE_NTPC_LinkMgmt)
    {
      #ifdef CFG_PRN_WARN
      printf("WARN [NTP] NTP_LinkManagementThrdFunc, unidentified pulse code"
             "%d\n", msg.pulse.code);
      #endif // CFG_PRN_WARN
      continue;
    }

    isServerActive = E_TYPE_No;
    for(uccnt = 0; uccnt < CGF_NTP_TOTAL_SERVER; uccnt++)
    {
      unretrycnt = 0;
      do{
        if(pNTP_CB->server[uccnt].nfd == TYP_ERROR)
        {
          rstatus = LNC_GetConnectFileDescriptor(
            (const CHAR *)pNTP_CB->server[uccnt].ipaddr,
            (const UINT16) NTP_SERVER_PORT, (const INT32) SOCK_DGRAM,
            NTP_GETFILEDESC_TIMEOUT,
            (INT32 *) &pNTP_CB->server[uccnt].nfd);

          if(rstatus != E_ERR_Success)
          {
            unretrycnt++;
            #if ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            ERR_GetMsgString(rstatus, acErrMsg);
            printf("WARN [NTP] NTP_LinkManagementThrdFunc, server %s is down\n"
                   "  retry %d/%d, error %s\n",
               pNTP_CB->server[uccnt].ipaddr, unretrycnt, pNTP_CB->connectRetry,
               acErrMsg);
            #endif // ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            continue;
          }

          pLNC_CB->endPointConfig[uccnt].nfd = pNTP_CB->server[uccnt].nfd;
        }


        unretrycnt++;

        #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
        rstatus = SYS_GetCurrentTimeInString(&pbdtime, &tspec,
                                             E_SYS_TIME_Local);
        printf("[NTP] %d.%02d.%02d %02d:%02d:%02d.%03d "
               "NTP_LinkManagementThrdFunc,\n"
               "  server %s, fd %d, retry %d/%d\n",
               (pbdtime->tm_year + 1900), (pbdtime->tm_mon + 1),
               pbdtime->tm_mday, pbdtime->tm_hour, pbdtime->tm_min,
               pbdtime->tm_sec, tspec.tv_nsec/1000000,
               pLNC_CB->endPointConfig[uccnt].pipaddr,
               pNTP_CB->server[uccnt].nfd,
               unretrycnt, pNTP_CB->connectRetry);
        //SYS_PrnDataBlock((const UINT8 *) pbuff,const UINT32 prnsz,const UINT8 byteperrow)
        #endif // ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))

        clock_gettime(CLOCK_REALTIME, &tspec);
        tx_ntppack.transmitTimeStamp =
         NTP_Fp64ToFpst64(tspec.tv_sec + NTP_JAN_1970 + 1.0e-9 * tspec.tv_nsec);

        rstatus = LNC_SendWithReply(pNTP_CB->server[uccnt].nfd,
                                    (const CHAR *)&tx_ntppack,
                                    ucntp_packet_sz,
                                    (VOID *)&rx_ntppack,
                                    ucntp_packet_sz, &rlen, 500);
        switch(rstatus)
        {
          case E_ERR_Success:
            break;

          case E_ERR_LNC_InvalidFileDescriptor:
          case E_ERR_LNC_SelectReadTimeOut:
          case E_ERR_LNC_FailToWriteSocket:
          case E_ERR_LNC_FailToConnectDatagramSocket:
            #if ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            ERR_GetMsgString(rstatus, acErrMsg);
            printf("WARN [NTP] NTP_LinkManagementThrdFunc, server %s is down\n"
                   "  fd %d, error %s\n",
               pNTP_CB->server[uccnt].ipaddr, pNTP_CB->server[uccnt].nfd,
               acErrMsg);
            #endif // ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            pNTP_CB->server[uccnt].isConnectionGood = E_TYPE_No;
            close(pNTP_CB->server[uccnt].nfd);
            pNTP_CB->server[uccnt].nfd = TYP_ERROR;
            rlen = 0;
            continue; // E_ERR_LNC_SelectReadTimeOut

          default:
            #if ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            ERR_GetMsgString(rstatus, errBuff);
            printf("WARN [NTP] NTP_LinkManagementThrdFunc, %s\n"
                   "  unhandled rstatus error %s\n",
                   SYS_GetDefaultThrdName(thrdnamebuff, sizeof(thrdnamebuff)),
                   errBuff);
            #endif // ((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP)
            continue;

        }

        if(rlen == ucntp_packet_sz)
        {
          pNTP_CB->server[uccnt].isConnectionGood = E_TYPE_Yes;
          #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
          printf("[NTP] NTP_LinkManagementThrdFunc, fd %d server %s is good\n",
                 pNTP_CB->server[uccnt].nfd,
                 pNTP_CB->server[uccnt].ipaddr);
          #endif // ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))

          // 20100928 BC
          // set active server according to priority
          for(ucservercnt = 0; ucservercnt < CGF_NTP_TOTAL_SERVER;
              ucservercnt++)
          {
            if(pNTP_CB->server[ucservercnt].isConnectionGood == E_TYPE_No)
              continue;

            if(pNTP_CB->pactiveserver == &pNTP_CB->server[ucservercnt])
            {
              isServerActive = E_TYPE_Yes;
              break;
            }

            pNTP_CB->pactiveserver = &pNTP_CB->server[ucservercnt];
            #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
            printf("[NTP] NTP_LinkManagementThrdFunc, fd %d server %s is set "
                   "to active\n",
                   pNTP_CB->server[uccnt].nfd,
                   pNTP_CB->pactiveserver->ipaddr);
            #endif // ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))
            isServerActive = E_TYPE_Yes;
            break;
          }

          // set timer value to start NTP polling thread
          itime.it_value.tv_sec = 1;
          itime.it_value.tv_nsec = 0;
          itime.it_interval.tv_sec = pNTP_CB->poll_frequency;
          itime.it_interval.tv_nsec = 0;
          timer_settime(pNTP_CB->polling_timer_id, 0, &itime, NULL);
          rlen = 0;
          break;
        }else{
          #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
          printf("WARN [NTP] NTP_LinkManagementThrdFunc, invalid rx length, "
               "%d from server %s\n",
               rlen, pNTP_CB->server[uccnt].ipaddr);
          #endif // CFG_PRN_WARN_NTP
          continue;
        }
      }while(unretrycnt < pNTP_CB->connectRetry);

      if(unretrycnt >= pNTP_CB->connectRetry)
      {
        if((pNTP_CB->server[uccnt].ipaddr[0] != 0) &&
           (pNTP_CB->server[uccnt].nfd > 0))
        {
          close(pNTP_CB->server[uccnt].nfd);
          pNTP_CB->server[uccnt].nfd = TYP_ERROR;
          #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
          printf("[NTP] NTP_LinkManagementThrdFunc, reset fd[%d] to TYP_ERROR\n",
                 uccnt);
          #endif // ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))
        }
      }
    } // for(uncnt = 0; uncnt < NTP_TOTAL_SERVER; uncnt++)

    // active server status
    if(isServerActive == E_TYPE_No)
    {
      #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
      printf("[NTP] NTP_LinkManagementThrdFunc, set active server to "
             "TYP_NULL\n");
      #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP))
      pNTP_CB->pactiveserver = TYP_NULL;
    }

    // pack NTP client status information
    rstatus = ntp_McpGetStatus(&ntpcstatus, sizeof(NTP_MSGQ_MCP_STATUS));
    if(rstatus != E_ERR_Success)
    {
      #ifdef CFG_PRN_ERR
      ERR_GetMsgString(rstatus, errBuff);
      printf("ERR  [NTP] NTP_LinkManagementThrdFunc, ntp_McpGetStatus "
             "error, %s\n", errBuff);
      #endif // CFG_PRN_ERR
      #if (((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP) || \
            (defined CFG_PRN_ERR))
      memset(errBuff, 0, sizeof(errBuff));
      #endif  // (((defined CFG_PRN_WARN) && CFG_PRN_WARN_NTP) ||
              //  (defined CFG_PRN_ERR))
    }

    memcpy(msgq.msgbuff, &ntpcstatus, sizeof(NTP_MSGQ_MCP_STATUS));
    msgq.msgsz = sizeof(NTP_MSGQ_MCP_STATUS);

    #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP_TXRESP)
    printf("[NTP] NTP_LinkManagementThrdFunc, send message queue %d "
           "bytes:\n", sizeof(SYS_MSGQ_MCPR));
    SYS_PrnDataBlock((const UINT8 *) &msgq, sizeof(SYS_MSGQ_MCPR), 20);
    #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP))

    // Send result to serial link using message queue
    msglen = mq_send(
      pSYS_CB->msq_ctrl[E_SYS_MSQL_NTPC_TxExternalSystemMsg].msq_id,
      (CHAR *)&msgq, sizeof(SYS_MSGQ_MCPR), SYS_MSQ_PRIOR_NORMAL);

    #if ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))
    printf("[NTP] NTP_LinkManagementThrdFunc, tx message queue %s\n",
           (msglen == 0 ? "OK" : "ERROR"));
    #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP))
    memset(&msgq, 0, sizeof(SYS_MSGQ_MCPR));

    if(pNTP_CB->pactiveserver == TYP_NULL)
    {
      #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
      printf("[NTP] NTP_LinkManagementThrdFunc, set polling time to %d secs\n",
             pCGF_CB->ntp.linkDownRetryFreq);
      #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP))
      itime.it_value.tv_sec = pCGF_CB->ntp.linkDownRetryFreq;
      itime.it_value.tv_nsec = 0;
      itime.it_interval.tv_sec = pCGF_CB->ntp.linkDownRetryFreq;
      itime.it_interval.tv_nsec = 0;
    }else{
      #if ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP)
      printf("[NTP] NTP_LinkManagementThrdFunc, set polling time to %d secs\n",
             pNTP_CB->poll_frequency);
      #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP))
      itime.it_value.tv_sec = pNTP_CB->poll_frequency;
      itime.it_value.tv_nsec = 1;
      itime.it_interval.tv_sec = pNTP_CB->poll_frequency;
      itime.it_interval.tv_nsec = 0;
    }
    timer_settime(timer_id, 0, &itime, NULL);

  }// while(1)

} // NTP_LinkManagementThrdFunc
示例#15
0
/*-----------------------------------------------------------------------------

 PUBLIC ROUTINE

  NTP_PollingThrdFunc

 DESCRIPTION

  This routine will manage NTP polling session. The client will extract
  timing information from the packet which is t1, t2, t3, and t4. Compute
  the delay and offset. The client will update RTC if offset is exceeding
  the defined spurious threshold, and thereby update the clock to the
  BIOS system.

  Timestamp Name ID When Generated
  --------------------------------
  t1: Originate Timestamp, time request sent by client
  t2: Receive Timestamp, time request received by server
  t3: Transmit Timestamp, time reply sent by server
  t4: Destination Timestamp, time reply received by client

  The roundtrip delay d and local clock offset t are defined as
  d = (t4 - t1) - (t2 - t3)
  t = ((t2 - t1) + (t3 - t4)) / 2.

 CALLED BY

  SYS_Initialization

 CALLS

  None

 PARAMETER

  None

 RETURN

   E_ERR_Success      the routine executed successfully

 AUTHOR

  Bryan KW Chong


 HISTORY

    NAME            DATE                    REMARKS

   Bryan Chong    25-Jan-2009      Created initial revision

-----------------------------------------------------------------------------*/
VOID *NTP_PollingThrdFunc(VOID *pThreadParameter)
{
  INT32             chid;
  struct sigevent   event;
  struct itimerspec itime;
  timer_t           timer_id;
  INT32             rcvid;
  NTP_CH_MSG_T      msg;
  E_ERR_T            rstatus;
  #if((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP_POLL)
  struct tm         *pbdtime;
  #endif // ((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP_POLL)
  struct timespec   tspec;
  #if((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))
  struct tm         *tFormatTime;
  #endif // ((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))

  NTP_PACKET_T      tx_ntppack;
  NTP_PACKET_T      rx_ntppack;
  UINT8             ucntp_packet_sz;
  INT32             rlen;

  FP64              t1, t2, t3, t4;
  FP64              tdelay, toffset;
  FP64              tadjust;
  FP64              integer_part;
  timespec          ctspec;

  #ifdef CFG_PRN_WARN
  CHAR              errBuff[100] = {0};
  #endif // CFG_PRN_WARN

  if ((chid = ChannelCreate (0)) == TYP_ERROR)
  {
    #ifdef CFG_PRN_ERR
    printf("ERR  [NTP] NTP_PollingThrdFunc, fail to create channel, %s\n",
            strerror(errno));
    #endif // CFG_PRN_ERR
    return TYP_NULL;
  }

  pNTP_CB->npolling_channelID = chid;

  // set up the pulse
  event.sigev_notify = SIGEV_PULSE;
  event.sigev_coid =
    ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0);
  event.sigev_priority = getprio(0);
  event.sigev_code = E_SYS_PULSE_NTP_Polling;
  timer_create(CLOCK_REALTIME, &event, &timer_id);

  pNTP_CB->polling_timer_id = timer_id;

  while(1)
  {
    rcvid = MsgReceive (chid, &msg, sizeof (msg), NULL);

    if (rcvid < 0)
    {
       //gotAMessage (rcvid, &msg.msg);
       #ifdef CFG_PRN_ERR
       printf("ERR  [NTP] NTP_PollingThrdFunc, error, %s\n",
               strerror(errno));
       #endif //CFG_PRN_ERR
    }

    if (rcvid > 0)
    {
       //gotAMessage (rcvid, &msg.msg);
       #if((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))
       printf("[NTP] NTP_LinkManagementThrdFunc, currently not support message"
              "handling\n");
       #endif //((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))
    }

    // determine where the message came from
    if (msg.pulse.code != E_SYS_PULSE_NTP_Polling)
    {
      #ifdef CFG_PRN_WARN
      printf("WARN [NTP] NTP_PollingThrdFunc, unidentified pulse code"
             "%d\n", msg.pulse.code);
      #endif // CFG_PRN_WARN
      continue;
    }

    #if((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP_POLL)
    rstatus = SYS_GetCurrentTimeInString(&pbdtime, &tspec, E_SYS_TIME_Local);
    if(rstatus != E_ERR_Success)
    {
      #ifdef CFG_PRN_WARN
      printf("WARN [NTP] NTP_PollingThrdFunc, get current time fail, %d\n",
              rstatus);
      #endif // CFG_PRN_WARN
      continue;
    }

    printf("[NTP] %d.%02d.%02d %02d:%02d:%02d.%03d NTP_PollingThrdFunc\n",
           (pbdtime->tm_year + 1900), (pbdtime->tm_mon + 1),
           pbdtime->tm_mday, pbdtime->tm_hour, pbdtime->tm_min,
           pbdtime->tm_sec, tspec.tv_nsec/1000000);
    #endif //((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))

    // construct the ntp request packet
    tx_ntppack.flags.allbits = 0xe3;
    tx_ntppack.peerClkStranum = TYP_NULL;
    tx_ntppack.peerPollingInterval = 0x4;
    tx_ntppack.peerClockPrecision = -6;
    tx_ntppack.rootDelay = NTP_Fp64ToFpst32(1.0000);
    tx_ntppack.rootDispersion = NTP_Fp64ToFpst32(1.0000);
    tx_ntppack.referenceClockID = TYP_NULL;
    tx_ntppack.referenceClockUpdateTime = NTP_Fp64ToFpst64(0.0000);
    tx_ntppack.originateTimeStamp = NTP_Fp64ToFpst64(0.0000);
    tx_ntppack.receiveTimeStamp = NTP_Fp64ToFpst64(0.0000);

    // get current time
    clock_gettime(CLOCK_REALTIME, &tspec);
    tx_ntppack.transmitTimeStamp =
      NTP_Fp64ToFpst64(tspec.tv_sec + NTP_JAN_1970 + 1.0e-9 * tspec.tv_nsec);
    ucntp_packet_sz = sizeof(NTP_PACKET_T);

    if(pNTP_CB->pactiveserver == TYP_NULL)
      continue;

    // transmit and receive ntp reply packet
    rstatus = LNC_SendWithReply(
          pNTP_CB->pactiveserver->nfd,
          (const CHAR *)&tx_ntppack,
          ucntp_packet_sz,
          (VOID *)&rx_ntppack,
          ucntp_packet_sz, &rlen, 2000);
    if (rstatus != E_ERR_Success)
    {
      #ifdef CFG_PRN_WARN
      ERR_GetMsgString(rstatus, errBuff);
      printf("ERR  [NTP] NTP_PollingThrdFunc, LNC_SendWithReply error "
             "%s\n", errBuff);
      #endif // CFG_PRN_WARN
      if(rstatus == E_ERR_LNC_SelectReadTimeOut)
      {
        #ifdef CFG_PRN_WARN
        printf("WARN [NTP] NTP_PollingThrdFunc, server %s is down.\n",
                pNTP_CB->pactiveserver->ipaddr);
        #endif // ((defined CFG_DEBUG_MSG) && (CFG_DEBUG_NTP))
      }
      pNTP_CB->pactiveserver->isConnectionGood = E_TYPE_No;
      pNTP_CB->pactiveserver = TYP_NULL;
      rlen = 0;

      // disarm timer
      itime.it_value.tv_sec = 0;
      itime.it_value.tv_nsec = 0;
      timer_settime(timer_id, 0, &itime, NULL);
      continue;
    }

    // Get t4, destination timestamp, time reply received by client
    clock_gettime(CLOCK_REALTIME, &tspec);
    t4 = tspec.tv_sec + NTP_JAN_1970 + 1.0e-9 * tspec.tv_nsec;

    // Get t1, originate timestamp, time request sent by client
    t1 = NTP_Fpst64ToFp64(rx_ntppack.originateTimeStamp);

    // Get t2, receive timestamp, time request received by server
    t2 = NTP_Fpst64ToFp64(rx_ntppack.receiveTimeStamp);

    // Get t3, transmit timestamp, time reply sent by server
    t3 = NTP_Fpst64ToFp64(rx_ntppack.transmitTimeStamp);

    // compute the delay and offset in seconds
    tdelay = (t4 - t1) - (t2 - t3);
    toffset = ((t2 - t1) + (t3 - t4))/2;

    // check if delay and offset is within the defined tolerance if not
    // update RTC
    clock_gettime(CLOCK_REALTIME, &tspec);
    tadjust = tspec.tv_sec + NTP_JAN_1970 + 1.0e-9 * tspec.tv_nsec;
    tadjust += toffset;

    #if((defined CFG_DEBUG_MSG) && CFG_DEBUG_NTP_POLL)
    tFormatTime = localtime(&tspec.tv_sec);
    printf("[NTP] NTP_PollingThrdFunc, %s:%d fd %d, "
           "%04d-%02d-%02d %02d:%02d:%02d\n"
           "  t1 = %.09f, t2 = %.09f,\n"
           "  t3 = %.09f, t4 = %.09f\n"
           "  delay = %.09f, offset = %.09f tadjust = %.09f\n",
           pNTP_CB->pactiveserver->ipaddr, NTP_SERVER_PORT,
           pNTP_CB->pactiveserver->nfd,
           (tFormatTime->tm_year + 1900), (tFormatTime->tm_mon + 1),
           tFormatTime->tm_mday, tFormatTime->tm_hour, tFormatTime->tm_min,
           tFormatTime->tm_sec, t1, t2, t3, t4, tdelay, toffset, tadjust);
    #endif // ((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))

    // Check if exceed spurious threshold in milliseconds
    if((abs(toffset) * 1e3) < pNTP_CB->threshold)
      continue;

    ctspec.tv_nsec = modf(tadjust, &integer_part) * 1e9;
    ctspec.tv_sec = integer_part - NTP_JAN_1970;

    #if((defined CFG_DEBUG_MSG) || CFG_DEBUG_NTP)
    tFormatTime = localtime(&ctspec.tv_sec);
    printf("[NTP] NTP_PollingThrdFunc, update current time = \n"
           "  sec = %d, nsec = %d\n  %04d-%02d-%02d %02d:%02d:%02d\n",
           ctspec.tv_sec, ctspec.tv_nsec,
           (tFormatTime->tm_year + 1900), (tFormatTime->tm_mon + 1),
           tFormatTime->tm_mday, tFormatTime->tm_hour, tFormatTime->tm_min,
           tFormatTime->tm_sec);
    #endif // ((defined CFG_DEBUG_MSG) || (CFG_DEBUG_NTP))
    if(clock_settime(CLOCK_REALTIME, &ctspec) == TYP_ERROR)
    {
      #ifdef CFG_PRN_ERR
      printf("[NTP] NTP_PollingThrdFunc, set RTC clock fail, error %s\n",
             strerror(errno));
      #endif // CFG_PRN_ERR
    }

    // update current time to hardware BIOS system
    rstatus = SYS_UpdateHardwareRTC();
    if(rstatus != E_ERR_Success)
    {
      #if ((defined CFG_PRN_WARN) && (CFG_PRN_WARN_NTP))
      printf("WARN [NTP] NTP_PollingThrdFunc, update hardware bios RTC fail\n");
      #endif // ((defined CFG_PRN_WARN) && (CFG_PRN_WARN_NTP)
    }

  } // while(1)
  return TYP_NULL;
} // NTP_PollingThrdFunc
示例#16
0
void *_resmgr_thread(void *data) {
    resmgr_ctrl_t						*ctrl = data;
    resmgr_context_t					*ctp;
    resmgr_iomsgs_t						*msg;
    int									n;

    // Detach thread so a join is not needed
    pthread_detach(pthread_self());

    n = offsetof(resmgr_context_t, iov) + ctrl->nparts_max * sizeof(ctp->iov[0]);
    if(!(ctp = malloc(n + ctrl->msg_max_size))) {
        pthread_mutex_lock(&ctrl->mutex);
        atomic_sub(&ctrl->waiting, 1);
        atomic_sub(&ctrl->created, 1);
        pthread_mutex_unlock(&ctrl->mutex);
        pthread_exit(0);
    }
    msg = ctp->msg = (resmgr_iomsgs_t *)((char *)ctp + n);
    ctp->ctrl = ctrl;
    // Zero the 'reserved' field because it's at the same location as
    // 'msg_max_size' in the new style resmgr_context_t and will allow
    // the _resmgr_handler function to tell if it's being invoked by
    // this code or the new dispatch code.
    ctp->reserved = 0;

    // try to make the number of threads waiting equal to THREAD_WAITING_MAX
    pthread_mutex_lock(&ctrl->mutex);
    if(ctrl->waiting < ctrl->increment && ctrl->created < ctrl->maximum) {
        pthread_attr_t				attr;

        if(ctrl->thread_stack_size) {
            (void)pthread_attr_init(&attr);
            (void)pthread_attr_setstacksize(&attr, ctrl->thread_stack_size);
        }
        if(pthread_create(0, ctrl->thread_stack_size ? &attr : 0, _resmgr_thread, ctrl) == EOK) {
            atomic_add(&ctrl->waiting, 1);
            atomic_add(&ctrl->created, 1);
        }
        if(ctrl->thread_stack_size) {
            (void)pthread_attr_destroy(&attr);
        }
    }
    pthread_mutex_unlock(&ctrl->mutex);

    pthread_cleanup_push(_thread_cleanup, ctp);
    for(;; atomic_add(&ctrl->waiting, 1)) {
        // free some threads if too many are waiting
        pthread_mutex_lock(&ctrl->mutex);
        if(ctrl->waiting > ctrl->hi_water) {
            break;
        }
        pthread_mutex_unlock(&ctrl->mutex);

        // Block waiting for someone
        ctp->id = -1;
        ctp->rcvid = MsgReceive(ctrl->chid, msg, ctrl->msg_max_size, &ctp->info);

        // If not enough are waiting, start one new one that will start more
        pthread_mutex_lock(&ctrl->mutex);
        if(atomic_sub_value(&ctrl->waiting, 1) < ctrl->lo_water && ctrl->created < ctrl->maximum) {
            pthread_attr_t				attr;

            if(ctrl->thread_stack_size) {
                (void)pthread_attr_init(&attr);
                (void)pthread_attr_setstacksize(&attr, ctrl->thread_stack_size);
            }
            if(pthread_create(0, ctrl->thread_stack_size ? &attr : 0, _resmgr_thread, ctrl) == EOK) {
                atomic_add(&ctrl->waiting, 1);
                atomic_add(&ctrl->created, 1);
            }
            if(ctrl->thread_stack_size) {
                (void)pthread_attr_destroy(&attr);
            }
        }
        pthread_mutex_unlock(&ctrl->mutex);

        // Doing a network transaction and not all the message was send, so get the rest...
        if(ctp->rcvid > 0 && ctp->info.srcmsglen > ctp->info.msglen && ctp->info.msglen < ctrl->msg_max_size) {
            int						n2;

            if((n2 = MsgRead_r(ctp->rcvid, (char *)msg + ctp->info.msglen,
                               ctrl->msg_max_size - ctp->info.msglen, ctp->info.msglen)) < 0) {
                MsgError(ctp->rcvid, -n2);
                continue;
            }
            ctp->info.msglen += n2;
        }

        _resmgr_handler(ctp);
    }
    pthread_cleanup_pop(1);
    pthread_mutex_unlock(&ctrl->mutex);
    pthread_exit(0);
    /* NOTREACHED */
    return( 0 );
}
示例#17
0
int main(int argc, char* argv[]) {
	int chid;
	int pid;
	int rcvid;
	int status;
	kom_t msg;

	int child_count = atoi(argv[1]);

	chid = ChannelCreate(0);
	if(-1 == chid) {
		perror("ChannelCreate()");
		exit(EXIT_FAILURE);
	}

	pid = getpid();
	printf("Server's pid: %d, chid: %d\n", pid, chid);

	int i = 0;
	for(i = 0; i < child_count; i++) {
		int child_pid = fork();
		if (!child_pid) {
			char pid_chars[20];
			char chid_chars[20];
			int base = 10;

			itoa(pid, pid_chars, base);
			itoa(chid, chid_chars, base);
			execl (CHILD, CHILD, pid_chars, chid_chars, (char *)NULL);
		}
	}

	while(1) {
		rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
		if(rcvid == -1) {
			perror("MsgReceive");
			break;
		}
		if(msg.type == 0) {
			printf("\tProces %d wyslal zakonczenie\n", msg.from);
			status = MsgReply(rcvid, EOK, &msg, sizeof(msg) );
			if(-1 == status) {
				perror("MsgReply");
			}
			child_count--;
			if(child_count == 0) {
				break;
			}
			continue;
		}
		printf("%s", msg.text);
		int i;
		int lowcase_count = 0;
		for (i = 0; msg.text[i]; i++) {
			if(msg.text[i] != toupper(msg.text[i]) && msg.text[i] != '\n') {
				msg.text[i] = toupper(msg.text[i]);
				lowcase_count++;
			}
		}
		msg.from = getpid();
		msg.type = 1;

		status = MsgReply(rcvid, EOK, &msg, sizeof(msg) );
		if(-1 == status) {
			perror("MsgReply");
		}
	}

	printf("po petli\n");

	while((pid=wait(&status))!=-1) {
		printf("Proces %d zakonczony, status %d\n",pid,WEXITSTATUS(status));
	}

	return 0;
}
// ****************************************************************
// TimerThreadMain()
//
void* FastResearchInterface::TimerThreadMain(void *ObjectPointer)
{
	int								OurChannelID	=	0
								,	ReceptionID		=	0;

	timer_t 						TimerID;

	struct sigevent 				Event;

	struct itimerspec 				Timer;

	struct _pulse  					PulseMsg;

	FastResearchInterface			*ThisObjectPtr		=	(FastResearchInterface*)ObjectPointer;

	OurChannelID				=	ChannelCreate(0); //create communication channel

	// Initialize event data structure
	// attach the timer to the channel OurChannelID
	Event.sigev_notify			=	SIGEV_PULSE;
	Event.sigev_coid			=	ConnectAttach(0, 0, OurChannelID, _NTO_SIDE_CHANNEL, 0);
	Event.sigev_priority		=	getprio(0);
	Event.sigev_code			=	TIMER_PULSE;

	timer_create(CLOCK_REALTIME, &Event, &TimerID);

	// Configure the timer
	Timer.it_value.tv_sec		=	0L;
	Timer.it_value.tv_nsec		=	(long int)(1000000000.0 * ThisObjectPtr->CycleTime);	// wait one cycle time interval before start
	Timer.it_interval.tv_sec	=	0L;
	Timer.it_interval.tv_nsec	=	(long int)(1000000000.0 * ThisObjectPtr->CycleTime);

	pthread_mutex_lock(&(ThisObjectPtr->MutexForThreadCreation));
	ThisObjectPtr->ThreadCreated	=	true;
	pthread_mutex_unlock(&(ThisObjectPtr->MutexForThreadCreation));

	pthread_cond_signal(&(ThisObjectPtr->CondVarForThreadCreation));

	// Start the timer
	timer_settime(TimerID, 0, &Timer, NULL);

	pthread_mutex_lock(&(ThisObjectPtr->MutexForCondVarForTimer));

	while(!(ThisObjectPtr->TerminateTimerThread))
	{
		pthread_mutex_unlock(&(ThisObjectPtr->MutexForCondVarForTimer));

		ReceptionID	= MsgReceive(OurChannelID, &PulseMsg, sizeof(PulseMsg), NULL);

		pthread_mutex_lock(&(ThisObjectPtr->MutexForCondVarForTimer));
		if (ReceptionID == 0)
		{
			ThisObjectPtr->TimerFlag = true;
			pthread_cond_signal(&(ThisObjectPtr->CondVarForTimer));
		}
	}
	pthread_mutex_unlock(&(ThisObjectPtr->MutexForCondVarForTimer));

	if (timer_delete(TimerID) != 0)
    {
		ThisObjectPtr->OutputConsole->printf("FastResearchInterface::TimerThreadMain(): ERROR, cannot delete timer...\n");
    }

	pthread_exit(NULL);
}