int main( int argc, char *argv[]) { db_clt_typ *pclt; char hostname[MAXHOSTNAMELEN]; char *domain = DEFAULT_SERVICE; int xport = COMM_OS_XPORT; posix_timer_typ *ptmr; char buf[1000]; int option; int verbose = 0; int interval = 5000; char *filename = NULL; FILE *fp = NULL; int retval = 0; char str1[100]; char str2[100]; rtms_msg_t rtms; char *pchar; int ms; int matchnum; while ((option = getopt(argc, argv, "vd:i:")) != EOF) { switch(option) { case 'v': verbose = 1; break; case 'd': filename = strdup(optarg); break; case 'i': interval = atoi(optarg); break; default: printf("Usage: %s\n", argv[0]); printf(" -d <data file> \n"); printf(" -v (verbose)\n"); exit(EXIT_FAILURE); } } if ( ((pclt = db_list_init(argv[0], hostname, domain, xport, db_vars, NUM_DB_VARS, NULL, 0)) == NULL)) exit(EXIT_FAILURE); if (setjmp(exit_env) != 0) { db_list_done(pclt, db_vars, NUM_DB_VARS, NULL, 0); if(fp != NULL) fclose(fp); } else sig_ign(sig_list, sig_hand); if ((ptmr = timer_init( interval, ChannelCreate(0))) == NULL) { fprintf(stderr, "Unable to initialize delay timer\n"); exit(EXIT_FAILURE); } if(filename != NULL) { if( (fp = fopen(filename,"r")) == NULL) { perror("fopen"); return -1; } } else fp = stdin; while( (retval = fgets(buf, sizeof(buf), fp) != NULL)) { if( (matchnum = strspn(buf, "0123456789: \t")) >= (retval + 8) ) { sscanf(buf, "%d %d %d %d:\t%d:%d:%d", &rtms.day, &rtms.month, &rtms.year, &rtms.hour, &rtms.minute, &rtms.second, &ms ); if(verbose) printf("Date %02d/%02d/%d Time: %02d:%02d:%02d\n", rtms.month, rtms.day, rtms.year, rtms.hour, rtms.minute, rtms.second ); } if(strstr(buf, "MESSAGE NO.") != NULL) { sscanf(buf, "%s %s %d %s %d %d %d", &str1[0], &str2[0], &rtms.msg_no, &str2[0], &rtms.vol_lane_1, &rtms.vol_lane_2, &rtms.vol_lane_3 ); if(verbose) printf("Message number %d lane 1 volume %d lane 2 volume %d lane 3 volume %d\n", rtms.msg_no, rtms.vol_lane_1, rtms.vol_lane_2, rtms.vol_lane_3 ); } if(strstr(buf, "STATION ID.") != NULL) { sscanf(buf, "%s %s %d %s %f %f %f", &str1[0], &str2[0], &rtms.station_id, &str2[0], &rtms.occ_lane_1, &rtms.occ_lane_2, &rtms.occ_lane_3 ); if(verbose) printf("Station ID %d lane 1 occupancy %.1f lane 2 occupancy %.1f lane 3 occupancy %.1f\n", rtms.msg_no, rtms.occ_lane_1, rtms.occ_lane_2, rtms.occ_lane_3 ); } if(strstr(buf, "SIDEFRD") != NULL) { // Replace the question marks with ASCII '0' while( (pchar = strchr(&buf[0], '?')) != NULL) *pchar = '0'; sscanf(buf, "%s %s %d %s %s %d %d %d %s %s %s %s %s %s", &str1[0], &str2[0], &rtms.sidefrd_spd_1, &str2[0], &str2[0], &rtms.sidefrd_spd_1, &rtms.sidefrd_spd_2, &rtms.sidefrd_spd_3, &str1[0], &str1[0], &str1[0], &str1[0], &str1[0], &str1[0] ); if(verbose) printf("lane 1 sidefired_speed %d lane 2 sidefired_speed %d lane 3 sidefired_speed %d\n", rtms.sidefrd_spd_1, rtms.sidefrd_spd_2, rtms.sidefrd_spd_3 ); } if(strstr(buf, "SPEED 85") != NULL) { // Replace the question marks with ASCII '0' while( (pchar = strchr(&buf[0], '?')) != NULL) *pchar = '0'; sscanf(buf, "%s %s %d %d %d", &str1[0], &str2[0], &rtms.speed_85_1, &rtms.speed_85_2, &rtms.speed_85_3 ); if(verbose) printf("lane 1 speed 85%% %d lane 2 speed 85%% %d lane 3 speed 85%% %d\n", rtms.speed_85_1, rtms.speed_85_2, rtms.speed_85_3 ); } if(strstr(buf, "GAP") != NULL) { // Replace the question marks with ASCII '0' while( (pchar = strchr(&buf[0], '?')) != NULL) *pchar = '0'; sscanf(buf, "%s %f %f %f", &str1[0], &rtms.gap_lane_1, &rtms.gap_lane_2, &rtms.gap_lane_3 ); if(verbose) printf("lane 1 gap %.1f lane 2 gap %.1f lane 3 gap %.1f\n", rtms.gap_lane_1, rtms.gap_lane_2, rtms.gap_lane_3 ); } db_clt_write(pclt, DB_RTMS_VAR, sizeof(rtms_msg_t), &rtms); memset(buf, 0, sizeof(buf)); } exit(EXIT_SUCCESS); return 0; }
main (void) { pid_t pid_gui; pid_t pid_sim; pid_t pid_pport; int simChid; int kill_gui; int kill_sim; int kill_pport; int s_return; //---thread paramters--------------// pthread_attr_t attr; pthread_t timerThreadID; pthread_t keyboardThreadID; pthread_t blockIDThreadID; do { printf("\n=========================================================\n"); printf("Please Selet the Operating Mode:\n"); printf("1: Basic Orientation Mode for Block: 0-10).\n"); printf("2: Rotated Orientation Mode for Block:0-6). (alaph version)\n"); printf("===========================================================\n"); flushall(); scanf ("%c",&programMode); printf("You have selected: Mode %c.\n\n",programMode); flushall(); if((programMode != '1' )&&(programMode !='2')) { printf("Invalid Selection, Please Enter!\n"); flushall(); } } while(programMode != '1'&&programMode !='2'); // ----------------Share Memory---------------------------------------- shMem=shm_open("shared_memory", OFLAGS, 0777); if (shMem == -1) { printf("shared_memory failed to open...\n"); flushall(); } else { if (ftruncate (shMem,SIZE) == -1) { printf ("Failed to set size for -- shmem -- \n"); flushall(); } else { //mapping a shared memory location memLocation = mmap (0, SIZE, PROT, MFLAGS, shMem, 0); if (memLocation == MAP_FAILED) { printf (" Failed to map to shared memory...\n"); flushall(); } } } // ---------------Semorphore------------------------------------- // semorphore for shared memory sem = sem_open ("shared_sem", O_CREAT, S_IRWXG | S_IRWXO | S_IRWXU, 0); if (sem == (sem_t *)(-1)) { printf ("User: Memory Semaphore failed to open....\n"); flushall(); } else { sem_post(sem); } // -----------------------channel creation--------------------------- // Create a channels for the simulator and Gui // The ChannelCreate function returns the channel ID ChannelCreate(0); ChannelCreate(0); //ChannelCreate(0);//for pport simChid = 1; sleep(1); // Spawing a process for the GUI and Simulator pid_gui = spawnl(P_NOWAIT, "/usr/local/bin/gui_g", "gui_g", NULL); pid_sim = spawnl(P_NOWAIT, "/usr/local/bin/newGUIPport_g", "sim", NULL); pid_pport = spawnl(P_NOWAIT, "/usr/local/bin/testPport_g", "pport",NULL); sleep(1); //The Gui process automatically connect to the channel //Thus we only need to attach the simulator process to the created channel coidsim = ConnectAttach(0,pid_sim,simChid,0,0); // Display error message if connection failed if (coidsim == -1) { printf("coidsim error\n"); flushall(); exit(EXIT_FAILURE); } coidpport = ConnectAttach(0,pid_pport,simChid,0,0); // Display error message if connection failed if (coidpport == -1) { printf("coidpport error\n"); flushall(); exit(EXIT_FAILURE); } // --------------------------timer code---------------------------------- // Create a channel for sending a pulse to myself when timer expires timerChid = ChannelCreate(_NTO_CHF_UNBLOCK); if(timerChid == -1) { printf("timer Channel create failed\n"); flushall(); } timerCoid = ConnectAttach ( 0, getpid ( ), timerChid, 0, 0); if(timerCoid == -1 ) { printf ("Channel attach failed!\n"); flushall(); perror ( NULL ); exit ( EXIT_FAILURE); } // Set up pulse event for delivery when the first timer expires; pulse code = 8, pulse value = 0; SIGEV_PULSE_INIT (&timerEvent, timerCoid, SIGEV_PULSE_PRIO_INHERIT, 8, 0); // Create Timer if (timer_create (CLOCK_REALTIME, &timerEvent, &timerid) == -1) { printf ( "Failed to create a timer for pulse delivery\n"); flushall(); perror (NULL); exit ( EXIT_FAILURE); } // Setup one time timer for 2 second timer.it_value.tv_sec = 2; timer.it_value.tv_nsec = 0; timer.it_interval.tv_sec = 0; timer.it_interval.tv_nsec = 0; // --------------------------timer2 code---------------------------------- // Create a channel for sending a pulse to myself when timer expires timerChid2 = ChannelCreate(_NTO_CHF_UNBLOCK); if(timerChid2 == -1) { printf("timer Channel create failed\n"); flushall(); } timerCoid2 = ConnectAttach ( 0, getpid ( ), timerChid2, 0, 0); if(timerCoid2 == -1 ) { printf ("Channel attach failed!\n"); flushall(); perror ( NULL ); exit ( EXIT_FAILURE); } // Set up pulse event for delivery when the first timer expires; pulse code = 8, pulse value = 0; SIGEV_PULSE_INIT (&timerEvent2, timerCoid2, SIGEV_PULSE_PRIO_INHERIT, 8, 0); // Create Timer if (timer_create (CLOCK_REALTIME, &timerEvent2, &timerid2) == -1) { printf ( "Failed to create a timer for pulse delivery\n"); flushall(); perror (NULL); exit ( EXIT_FAILURE); } //-------------------timer monitor thread-------------------- pthread_attr_init(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_create(&timerThreadID,&attr,timer_thread,NULL); if(timerThreadID == -1) { printf("Fail to create timer thread!"); flushall(); } else { printf("The timer thread ID is %i \n",timerThreadID); flushall(); } pthread_create(&timerThreadID,&attr,timer2_thread,NULL); if(timerThreadID == -1) { printf("Fail to create timer thread2!"); flushall(); } else { printf("The timer thread2 ID is %i \n",timerThreadID); flushall(); } // //----start the block Identification thread----------------- // pFile = fopen("Blocks.txt","w+"); pthread_create(&blockIDThreadID,&attr,blockID,NULL); if(blockIDThreadID == -1) { printf("Fail to create block indeptification thread!"); flushall(); } else { printf("The BlockID's thread ID is %i \n",blockIDThreadID); flushall(); } delay(10); //---------------------keyboard thread------------------------ pthread_create(&keyboardThreadID,&attr,keyboard_input,NULL); if(keyboardThreadID == -1) { printf("Fail to create keyboard input!"); flushall(); } else { printf("The keyboard_input ID is %i \n",timerThreadID); flushall(); } delay(10); //----------------GUI Monitor Thread--------------------- pthread_create(NULL,&attr,GUI_thread,NULL); delay(10); // --------------------SIM pulse Handler Loop Thread---------- pthread_create(NULL,&attr,Handlerloop_thread,NULL); delay(10); // --------------------SIM Monitor Thread--------------------- pthread_create(NULL,&attr,SIM_thread,NULL); delay(10); // --------------------Auto mode thread----------------------- pthread_create(NULL,&attr,auto_thread,NULL); delay(10); // --------------------others--------------------------------- // call mainLoop() mainLoop(); // sleep for 10sec printf("Sleep the program for 10 seconds\n"); flushall; sleep(10); // start release system resourse printf("Clean up and release system resourse\n"); flushall; // Kill the existing processes kill_gui = kill(pid_gui, 0); kill_sim = kill(pid_sim, 0); kill_pport = kill(pid_pport, 0); if (kill_gui == -1) { printf("GUI Kill failed\n"); flushall(); } if (kill_sim == -1) { printf("SIM Kill failed\n"); flushall(); } if (kill_pport == -1) { printf("PPort Kill failed\n"); flushall(); } // Close and unlink Semorphore sem_close(sem); s_return = sem_unlink("/dev/sem/home/quad6/workspace/Project_S1/shared_sem"); // Display error messae if semorphonre unlink is failed if (s_return == -1) { printf("a: %s\n", strerror( errno )); flushall(); } // Close, unmap, and unlink shared memory shm_close(shMem); munmap(shmLocation,SIZE); shm_unlink("shared_memory"); // Detach the connections and destroy the channels ConnectDetach(coidGui); ConnectDetach(coidsim); ConnectDetach(coidpport); ChannelDestroy(guiChid); ChannelDestroy(simChid); // fclose(pFile); }
int main(int argc, char **argv) { //***************************************************************************** FILE *pfcfg; syncsig_t *psync; sem_t wrk_sem; sem_t *pwrk_sem = &wrk_sem; struct timespec wait_wrk_sem; size_t i, wrk_amount = CLIENT_MAX, client_max = CLIENT_MAX; pthread_t *pworker; name_attach_t* pnat; frame_t frame; iov_t *piov, *pheader; cash_t *pcash; pheader = malloc(sizeof(iov_t)); SETIOV(pheader, &frame, sizeof(frame_t)); char buf[BUFFER_SIZE], cmd[BUFFER_SIZE], param[BUFFER_SIZE]; int rcvid, slave_chid; char srv_name[BUFFER_SIZE] = SRV_NAME; // Slave support slave_t slave; slave.amount = 0; uint32_t *proute; //***************************************************************************** // Configs //log_start(FILE_NAME_LOG, FILE_NAME_ERR); printf("%s\n", MSG_VER_START); wait_wrk_sem.tv_nsec = WRK_SEM_TIMEOUT; wait_wrk_sem.tv_sec = 0; if(argc == 2) { pfcfg = fopen(argv[1], "r"); } else { pfcfg = fopen(FILE_NAME_CFG, "r"); } if(NULL != pfcfg) { while(0 == feof(pfcfg)) { fscanf(pfcfg, "%s %s", cmd, param); if(0 == strcmp(cmd, CFG_PAR_WRKAM)) { wrk_amount = atoi(param); } else if(0 == strcmp(cmd, CFG_PAR_WRKSEMTIME)) { wait_wrk_sem.tv_nsec = atol(param); } else if(0 == strcmp(cmd, CFG_PAR_MASTER)) { slave.amount = atoi(param); } else if(0 == strcmp(cmd, CFG_PAR_SLAVE)) { strcpy(srv_name, SLAVE_NAME); strcat(srv_name, param); } else if(0 == strcmp(cmd, CFG_PAR_CLIENTMAX)) { client_max = atoi(param); } } fclose(pfcfg); } else { perror(MSG_ERR_CFGFILE); } printf("%s\n", MSG_VER_CFG); signal(SIGINT, fsigint); // Net pnat = name_attach(NULL, srv_name, NAME_FLAG_ATTACH_GLOBAL); __ERROR_EXIT(pnat, NULL, "name_attach"); chid = pnat->chid; // Cash pcash = malloc(sizeof(cash_t)*client_max); //memset(pcash, NULL, sizeof(cash_t)*client_max); /*for(size_t i=0; i<client_max; ++i) { pcash[i].status = EMPTY; }*/ proute = malloc(sizeof(uint32_t)*client_max); // Slaves if(slave.amount > 0) { slave.pslave = malloc(sizeof(slave_info_t)*slave.amount); for(int i = 0; i< slave.amount; ++i) { slave.pslave[i].name = malloc(sizeof(char)*BUFFER_SIZE); strcpy(slave.pslave[i].name, SLAVE_NAME); itoa(i, buf, 10); strcat(slave.pslave[i].name, buf); slave.pslave[i].status = DOWN; slave.pslave[i].clientmax = CLIENT_MAX; slave.pslave[i].clientnow = 0; sem_init(&slave.pslave[i].sem, 0, 1); } connectslaves(&slave); slave_chid = ChannelCreate(0); __ERROR_EXIT(slave_chid, -1, "ChannelCreate"); } // Workers __ERROR_EXIT(sem_init(pwrk_sem, 0, 0), -1, "pwrk_sem: sem_init"); psync = malloc(sizeof(syncsig_t)*wrk_amount); pworker = malloc(sizeof(pthread_t)*wrk_amount); wrk_info_t wrk_info; wrk_info.psem = pwrk_sem; wrk_info.chid = pnat->chid; wrk_info.pcash = pcash; wrk_info.pslave = &slave; wrk_info.client_amount = client_max; wrk_info.wrk_amount = wrk_amount; wrk_info.proute = proute; wrk_info.psync = psync; if(slave.amount > 0) { for(size_t i = 0; i<wrk_amount; ++i) { wrk_info.id = i; pthread_create(&pworker[i], NULL, router, &wrk_info); } } else { for(size_t i = 0; i<wrk_amount; ++i) { wrk_info.id = i; pthread_create(&pworker[i], NULL, worker, &wrk_info); } } /* * __ERROR_CHECK(TimerTimeout(CLOCK_REALTIME , _NTO_TIMEOUT_RECEIVE , NULL, &wait_wrk_sem.tv_nsec, NULL), -1, "TimerTimeout"); */ printf("%s\n", MSG_VER_WORK); //***************************************************************************** while(working) { log_update(); sleep(1); } //***************************************************************************** for(size_t i = 0; i<wrk_amount; ++i) { pthread_kill(pworker[i], SIGKILL); } for(size_t i = 0; i<wrk_amount; ++i) { pthread_join(pworker[i], NULL); } if(slave.amount > 0) { for(size_t i = 0; i<slave.amount; ++i) { free(slave.pslave[i].name); } free(slave.pslave); } name_detach(pnat, NULL); free(pworker); free(psync); free(proute); log_update(); //log_stop(); return EXIT_SUCCESS; }
//#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
static void *interrupt_thread( void *p ) { int ret; int intr; int intr_id; struct sigevent event; struct _pulse pulse; iov_t iov; int rcvid; int chid; int coid; int count; uint64_t rdata; uint16_t target; uint64_t clk; int pool_id; intr = (int)p; rdata = 0; target = 512; ret = ThreadCtl( _NTO_TCTL_IO, 0 ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to gain IO privs: %s", strerror( errno ) ); return NULL; } chid = ChannelCreate( 0 ); if( chid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ChannelCreate() failed: %s", strerror( errno ) ); return NULL; } coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 ); if( coid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ConnectAttach() failed: %s", strerror( errno ) ); return NULL; } ret = yarrow_add_source( Yarrow, &pool_id ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to get pool_id for interrupt %d thread.", intr ); return NULL; } event.sigev_notify = SIGEV_PULSE; event.sigev_coid = coid; event.sigev_code = 1; event.sigev_priority = 15; intr_id = InterruptAttachEvent( intr, &event, _NTO_INTR_FLAGS_TRK_MSK ); if( intr_id == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to attach event to intr %d: %s", intr, strerror( errno ) ); return NULL; } /* This is how many interrupts we are gonna get */ if( Yarrow ) { yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); target = rdata & 0x1FF; } count = 0; SETIOV( &iov, &pulse, sizeof( pulse ) ); while( 1 ) { rcvid = MsgReceivev( chid, &iov, 1, NULL ); if( rcvid == -1 ) { if( errno == ESRCH ) return NULL; continue; } switch( pulse.code ) { case 1: InterruptUnmask( intr, intr_id ); count++; if( count >= target ) { ClockTime( CLOCK_REALTIME, NULL, &clk ); clk = clk ^ rdata; if( Yarrow ) { yarrow_input( Yarrow, (uint8_t *)&clk, sizeof( clk ), pool_id, 8 ); yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); } target = rdata & 0x1FF; count = 0; } break; default: if( rcvid ) MsgError( rcvid, ENOTSUP ); } } return NULL; }
/*----------------------------------------------------------------------------- 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
int main3(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; }
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 ); } }
/**************************************************************************** * * 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); mypid=getpid(); /* Setup the barrier used to syncronize */ pthread_barrier_init(&global_barrier, NULL, 2); /* 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); /* Get io-privity */ rc=ThreadCtl( _NTO_TCTL_IO, 0 ); assert(rc!=-1); /* 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); correct_values_eh=0; 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); /* Setup the event handler */ memset(&my_event_data, 0, sizeof(my_event_data)); memset(data_array, 0, sizeof(data_array)); my_event_data.data_array=data_array; rc=TraceEvent(_NTO_TRACE_ADDEVENTHANDLER, _NTO_TRACE_THREAD,(1<<cur_state), event_handler, &my_event_data); 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_eh<-1) testpntfail("Got bad values in the event handler"); else if (correct_values_eh==0) testpntfail("Event handler not called"); else if (correct_values_eh==1) testpntpass("Good"); else { snprintf(message,sizeof(message),"correct_values_eh : %d",correct_values_eh); testnote(message); snprintf(message,sizeof(message),"correct_values : %d",correct_values); testnote(message); 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); correct_values_eh=0; 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); /* Setup the event handler */ memset(&my_event_data, 0, sizeof(my_event_data)); memset(data_array, 0, sizeof(data_array)); my_event_data.data_array=data_array; rc=TraceEvent(_NTO_TRACE_ADDEVENTHANDLER, _NTO_TRACE_THREAD,(1<<cur_state), event_handler, &my_event_data); 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_eh<-1) testpntfail("Got bad values in the event handler"); else if (correct_values_eh==0) testpntfail("Event handler not called"); else if (correct_values_eh==1) testpntpass("Good"); 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; }
// **************************************************************** // 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); }