示例#1
0
/* 获取当前所有温度传感器最高的温度 */
static INT8 local_max_temperature_get()
{
    UINT8 sensor_id, max = 0, i;
    INT16 temperature;
    /* 获取温度 */
    temperature = ds_get_id_temperaturex16_unblock(&sensor_id);
    if(temperature > -1000 && sensor_id < TEMPERATURE_SENSOR_NUM){	/* 成功获取温度 */
	temperature_info[0].temperature[sensor_id] = temperature / 16;
	temperature_info[0].lastTime[sensor_id] = timebase_get();
    }else{			/* 有错误发生 */
	
    }
    for(i=0; i<1; i++){
	UINT32 diff = time_diff_ms(temperature_info[0].lastTime[i]);
	if(diff > 60000){	/* 60秒没有成功获取温度 */
	    temperature_info[0].temperature[i] = 120;
	}
	if(diff > 10000){	/* 十秒没有成功获取温度,温度+10度 */
	    temperature_info[0].lastTime[i] = local_ms_get();
	    temperature_info[0].temperature[i] += 10;
	    if(temperature_info[0].temperature[i] > 120)
	      temperature_info[0].temperature[i] = 120;
	}
	if(max < temperature_info[0].temperature[i])
	  max = temperature_info[0].temperature[i];
    }
    return max;
}
示例#2
0
文件: slave.c 项目: kemaliu/kFishTank
int main()
{
    UINT32 val;
    char c, forceClearCfg = 0;
    /* enable watchdog */
    wdt_enable(WDTO_8S);
#ifdef INCLUDE_KTANK_UART
    /* init UART */
    init_uart(9600);
    printk("\n\n\n!!!!!!!!!!ktank start!!!!!!!!!!!!!!\n\n\n");
#endif
    /* init PWM, local time */
    pwm_init();
    /* enable i2c bus, rtc need it  */
    I2C_init();
    /* init timer */
    timer_init();
    val = timebase_get();
#ifdef INCLUDE_KTANK_UART
    do{
        if(uart_poll_c((UINT8*)&c) > 0 && c == 'c'){
            forceClearCfg++;
        }
    }while(time_diff_ms(val) < 2000);
#endif
    if(forceClearCfg > 10){
        DBG_PRINT("slave force clear cfg..\n");
        EEPROM_put(EEPROM_OFS_RFAVAIL, 0xff);
    }
    local_device_info_load();
    local_device_info_show();
    if(RF_CFG_AVAL()){
        rf_init(NULL, SLAVE_MODE_NORMAL);

        rf_config(EEPROM_get(EEPROM_OFS_HOSTID), EEPROM_get(EEPROM_OFS_DEVID));
        DBG_PRINT("slave start hostid 0x%x devid 0x%x\n", 
               EEPROM_get(EEPROM_OFS_HOSTID), EEPROM_get(EEPROM_OFS_DEVID));
        nrf_enter_rx_mode();
    }else{
#if 0
        rf_init(NULL, SLAVE_MODE_WAIT_SYNC);
        DBG_PRINT("no cfg, force device id 1, host id 0xef\n");
        rf_config(0xef, 1);
        nrf_enter_rx_mode();
#else

        rf_init(NULL, SLAVE_MODE_WAIT_DISCOVER);
        rf_config(0xc0, 0x80);
        DBG_PRINT("slave start without rf cfg\n");
#endif
    }
    sei();
    while(1){
        wdt_reset();
        rf_process();
	local_device_update();
    }
}
示例#3
0
void report(char *name, struct timespec a, struct timespec b)
{
	uint64_t bytes = FLAGS_num * (KEY_SIZE + VAL_SIZE);
	long long cost_ms = time_diff_ms(a, b) + 1;
	printf("%s:%" PRIu64 ", cost:%d(ms), %.f ops/sec, %6.1f MB/sec\n",
	       name,
	       FLAGS_num,
	       (int)cost_ms,
	       (double)(FLAGS_num / cost_ms) * 1000,
	       (double)((double)(bytes / cost_ms / 1048576.0) * 1000));
}
示例#4
0
int flush_node_callback(void *tree, struct node *n)
{
	int r;
	struct timespec t1, t2;
	struct tree *t = (struct tree*)tree;

	gettime(&t1);
	r = serialize_node_to_disk(t->fd, t->block, n, t->hdr);
	gettime(&t2);
	t->status->tree_node_flush_costs += time_diff_ms(t1, t2);
	t->status->tree_node_flush_nums++;
	if (r != NESS_OK)
		__PANIC("flush node to disk error, errno [%d]", r);

	return r;
}
示例#5
0
int fetch_node_callback(void *tree, NID nid, struct node **n)
{
	int r;
	struct timespec t1, t2;
	struct tree *t = (struct tree*)tree;

	gettime(&t1);
	r = deserialize_node_from_disk(t->fd, t->block, t->hdr, nid, n);
	gettime(&t2);

	atomic64_add(&t->status->tree_node_fetch_costs, (uint64_t)time_diff_ms(t1, t2));
	atomic64_increment(&t->status->tree_node_fetch_nums);
	if (r != NESS_OK)
		__PANIC("fetch node from disk error, errno [%d]", r);

	return r;
}
示例#6
0
文件: db-bench.c 项目: Fleurer/nessDB
int main(int argc, char *argv[])
{

	int loop;
	struct nessdb *db;
	char basedir[] = "./dbbench/";
	struct timespec start;
	struct timespec end;
	struct random *rnd;

	if (argc != 2) {
		printf("./db-bench [count]\n");
		return 0;
	}
	loop = atoi(argv[1]);
	rnd = rnd_new();
	db = db_open(basedir);

	gettime(&start);
	do_bench(db, rnd, loop);
	gettime(&end);

	uint64_t bytes = loop * (KEY_SIZE + VAL_SIZE);
	long long cost_ms = time_diff_ms(start, end) + 1;
	printf("--------loop:%d, cost:%d(ms), %.f ops/sec, %6.1f MB/sec\n",
			loop,
			(int)cost_ms,
			(double)(loop/cost_ms)*1000,
			(double)((bytes/cost_ms/1048576.0) * 1000));


	db_close(db);
	rnd_free(rnd);

	return 1;
}
int workqueue_show_status(struct workqueue_ctx* ctx, FILE *fp)
{
	int i;
	long long time_ms;
	struct TIME_STRUCT_TYPE now_time;
	GET_TIME(now_time);

	LOCK_MUTEX(&ctx->mutex);
	fprintf(fp, "Number of worker threads=%d \n", ctx->num_worker_threads);
	fprintf(fp, "Total jobs added=%d queue_size=%d waiting_jobs=%d \n", ctx->job_count, ctx->queue_size, ctx->waiting_jobs);
	fprintf(fp, "\n");
	fprintf(fp, "%3s | %8s | %4s | %6s ms\n", "Qi", "JobID", "Pri", "Time" );
	fprintf(fp, "---------------------------------\n");
	for (i = 0; i < ctx->queue_size; i++) {
		if (!ctx->queue[i])
			continue; /* unused location */

		if (TIME_SEC(ctx->queue[i]->start_time) ||
			TIME_MSEC(ctx->queue[i]->start_time)) {
			// has been scheduled for a time in the future.
			time_ms = time_diff_ms(&ctx->queue[i]->start_time, &now_time);
		} else {
			// will run ASAP
			time_ms = 0;
		}

		fprintf(fp,"%3d | %8d | %4d | %6lld ms\n", i,
			ctx->queue[i]->job_id,
			ctx->queue[i]->priority, time_ms);
	}

	UNLOCK_MUTEX(&ctx->mutex);

	fflush(fp);
	return 0;
}
示例#8
0
void create_everything(struct main_context *ctx) {
	struct callmaster_config mc;
	struct control_tcp *ct;
	struct control_udp *cu;
	struct control_ng *cn;
	struct cli *cl;
	int kfd = -1;
	struct timeval tmp_tv;
	struct timeval redis_start, redis_stop;
	double redis_diff = 0;

	if (table < 0)
		goto no_kernel;
	if (kernel_create_table(table)) {
		fprintf(stderr, "FAILED TO CREATE KERNEL TABLE %i, KERNEL FORWARDING DISABLED\n", table);
		ilog(LOG_CRIT, "FAILED TO CREATE KERNEL TABLE %i, KERNEL FORWARDING DISABLED\n", table);
		if (no_fallback)
			exit(-1);
		goto no_kernel;
	}
	kfd = kernel_open_table(table);
	if (kfd == -1) {
		fprintf(stderr, "FAILED TO OPEN KERNEL TABLE %i, KERNEL FORWARDING DISABLED\n", table);
		ilog(LOG_CRIT, "FAILED TO OPEN KERNEL TABLE %i, KERNEL FORWARDING DISABLED\n", table);
		if (no_fallback)
			exit(-1);
		goto no_kernel;
	}

no_kernel:
	ctx->p = poller_new();
	if (!ctx->p)
		die("poller creation failed");

	ctx->m = callmaster_new(ctx->p);
	if (!ctx->m)
		die("callmaster creation failed");

	dtls_timer(ctx->p);

	ZERO(mc);
	mc.kernelfd = kfd;
	mc.kernelid = table;
	mc.interfaces = &interfaces;
	mc.port_min = port_min;
	mc.port_max = port_max;
	mc.max_sessions = max_sessions;
	mc.timeout = timeout;
	mc.silent_timeout = silent_timeout;
	mc.delete_delay = delete_delay;
	mc.default_tos = tos;
	mc.b2b_url = b2b_url;
	mc.fmt = xmlrpc_fmt;
	mc.graphite_port = graphite_port;
	mc.graphite_ip = graphite_ip;
	mc.graphite_interval = graphite_interval;

	ct = NULL;
	if (listenport) {
		ct = control_tcp_new(ctx->p, listenp, listenport, ctx->m);
		if (!ct)
			die("Failed to open TCP control connection port");
	}

	cu = NULL;
	if (udp_listenport) {
		callmaster_exclude_port(ctx->m, udp_listenport);
		cu = control_udp_new(ctx->p, udp_listenp, udp_listenport, ctx->m);
		if (!cu)
			die("Failed to open UDP control connection port");
	}

	cn = NULL;
	if (ng_listenport) {
		callmaster_exclude_port(ctx->m, ng_listenport);
		cn = control_ng_new(ctx->p, ng_listenp, ng_listenport, ctx->m);
		if (!cn)
			die("Failed to open UDP control connection port");
	}

	cl = NULL;
	if (cli_listenport) {
	    callmaster_exclude_port(ctx->m, cli_listenport);
	    cl = cli_new(ctx->p, cli_listenp, cli_listenport, ctx->m);
	    if (!cl)
	        die("Failed to open UDP CLI connection port");
	}

	if (redis_ip) {
		mc.redis = redis_new(redis_ip, redis_port, redis_db, MASTER_REDIS_ROLE);
		if (!mc.redis)
			die("Cannot start up without Redis database");
	}

	if (redis_read_ip) {
		mc.redis_read = redis_new(redis_read_ip, redis_read_port, redis_read_db, ANY_REDIS_ROLE);
		if (!mc.redis_read)
			die("Cannot start up without Redis read database");
	}

	if (redis_write_ip) {
		mc.redis_write = redis_new(redis_write_ip, redis_write_port, redis_write_db, ANY_REDIS_ROLE);
		if (!mc.redis_write)
			die("Cannot start up without Redis write database");
	}

	ctx->m->conf = mc;
	callmaster_config_init(ctx->m);

	if (!foreground)
		daemonize();
	wpidfile();

	// start redis restore timer
	gettimeofday(&redis_start, NULL);

	if (mc.redis_read) {
		if (redis_restore(ctx->m, mc.redis_read, ANY_REDIS_ROLE))
			die("Refusing to continue without working Redis read database");
	} else if (mc.redis) {
		if (redis_restore(ctx->m, mc.redis, MASTER_REDIS_ROLE))
			die("Refusing to continue without working Redis database");
	}

	// stop redis restore timer
	gettimeofday(&redis_stop, NULL);

	// print redis restore duration
	redis_diff += time_diff_ms(redis_start, redis_stop);
	ilog(LOG_INFO, "Redis restore time = %.0lf ms", redis_diff);

	gettimeofday(&ctx->m->latest_graphite_interval_start, NULL);

	timeval_from_ms(&tmp_tv, graphite_interval*1000000);
	set_graphite_interval_tv(&tmp_tv);
}
//------------------------------------------------------------------------------
int main(int argc, char** argv) {

    if(argc < 9) {
        std::cerr << "usage: " << argv[0]
                  << " <platform name> <device type = default | cpu | gpu "
                     "| acc | all>  <device num> <OpenCL source file path>"
                     " <kernel name> <size> <local size> <vec element width>"
                  << std::endl;
        exit(EXIT_FAILURE);   
    }
    const int SIZE = atoi(argv[argc - 3]); // number of elements
    const int CL_ELEMENT_SIZE = atoi(argv[argc - 1]); // number of per-element
                                                      // components
    const int CPU_BLOCK_SIZE = 16384; //use block dot product if SIZE divisible
                                  //by this value
    const size_t BYTE_SIZE = SIZE * sizeof(real_t);
    const int BLOCK_SIZE = atoi(argv[argc - 2]); //local cache for reduction
                                                 //equal to local workgroup size
    const int REDUCED_SIZE = SIZE / BLOCK_SIZE;
    const int REDUCED_BYTE_SIZE = REDUCED_SIZE * sizeof(real_t);
    //setup text header that will be prefixed to opencl code
    std::ostringstream clheaderStream;
    clheaderStream << "#define BLOCK_SIZE " << BLOCK_SIZE      << '\n';
    clheaderStream << "#define VEC_WIDTH "  << CL_ELEMENT_SIZE << '\n';
#ifdef USE_DOUBLE    
    clheaderStream << "#define DOUBLE\n";
    const double EPS = 0.000000001;
#else
    const float EPS = 0.00001;
#endif
    const bool PROFILE_ENABLE_OPTION = true;    
    CLEnv clenv = create_clenv(argv[1], argv[2], atoi(argv[3]),
                               PROFILE_ENABLE_OPTION,
                               argv[4], argv[5], clheaderStream.str());
   
    cl_int status;
    //create input and output matrices
    std::vector<real_t> V1 = create_vector(SIZE);
    std::vector<real_t> V2 = create_vector(SIZE);
    real_t hostDot = std::numeric_limits< real_t >::quiet_NaN();
    real_t deviceDot = std::numeric_limits< real_t >::quiet_NaN();      
//ALLOCATE DATA AND COPY TO DEVICE    
    //allocate output buffer on OpenCL device
    //the partialReduction array contains a sequence of dot products
    //computed on sub-arrays of size BLOCK_SIZE
    cl_mem partialReduction = clCreateBuffer(clenv.context,
                                             CL_MEM_WRITE_ONLY,
                                             REDUCED_BYTE_SIZE,
                                             0,
                                             &status);
    check_cl_error(status, "clCreateBuffer");

    //allocate input buffers on OpenCL devices and copy data
    cl_mem devV1 = clCreateBuffer(clenv.context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  BYTE_SIZE,
                                  &V1[0], //<-- copy data from V1
                                  &status);
    check_cl_error(status, "clCreateBuffer");                              
    cl_mem devV2 = clCreateBuffer(clenv.context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  BYTE_SIZE,
                                  &V2[0], //<-- copy data from V2
                                  &status);
    check_cl_error(status, "clCreateBuffer");                              

    //set kernel parameters
    status = clSetKernelArg(clenv.kernel, //kernel
                            0,      //parameter id
                            sizeof(cl_mem), //size of parameter
                            &devV1); //pointer to parameter
    check_cl_error(status, "clSetKernelArg(V1)");
    status = clSetKernelArg(clenv.kernel, //kernel
                            1,      //parameter id
                            sizeof(cl_mem), //size of parameter
                            &devV2); //pointer to parameter
    check_cl_error(status, "clSetKernelArg(V2)");
    status = clSetKernelArg(clenv.kernel, //kernel
                            2,      //parameter id
                            sizeof(cl_mem), //size of parameter
                            &partialReduction); //pointer to parameter
    check_cl_error(status, "clSetKernelArg(devOut)");
   

    //setup kernel launch configuration
    //total number of threads == number of array elements
    const size_t globalWorkSize[1] = {SIZE / CL_ELEMENT_SIZE};
    //number of per-workgroup local threads
    const size_t localWorkSize[1] = {BLOCK_SIZE}; 
//LAUNCH KERNEL
    // make sure all work on the OpenCL device is finished
    status = clFinish(clenv.commandQueue);
    check_cl_error(status, "clFinish");
    cl_event profilingEvent;
    timespec kernelStart = {0,  0};
    timespec kernelEnd = {0, 0};
    clock_gettime(CLOCK_MONOTONIC, &kernelStart);
    //launch kernel
    status = clEnqueueNDRangeKernel(clenv.commandQueue, //queue
                                    clenv.kernel, //kernel                                   
                                    1, //number of dimensions for work-items
                                    0, //global work offset
                                    globalWorkSize, //total number of threads
                                    localWorkSize, //threads per workgroup
                                    0, //number of events that need to
                                       //complete before kernel executed
                                    0, //list of events that need to complete
                                       //before kernel executed
                                    &profilingEvent); //event object associated
                                                      // with this particular
                                                      // kernel execution
                                                      // instance

    check_cl_error(status, "clEnqueueNDRangeKernel");
    status = clFinish(clenv.commandQueue); //ensure kernel execution is
    //terminated; used for timing purposes only; there is no need to enforce
    //termination when issuing a subsequent blocking data transfer operation
    check_cl_error(status, "clFinish");
    status = clWaitForEvents(1, &profilingEvent);
    clock_gettime(CLOCK_MONOTONIC, &kernelEnd);
    check_cl_error(status, "clWaitForEvents");
    //get_cl_time(profilingEvent);  //gives similar results to the following 
    const double kernelElapsedTime_ms = time_diff_ms(kernelStart, kernelEnd);
//READ DATA FROM DEVICE
    //read back and print results
    std::vector< real_t > partialDot(REDUCED_SIZE); 
    status = clEnqueueReadBuffer(clenv.commandQueue,
                                 partialReduction,
                                 CL_TRUE, //blocking read
                                 0, //offset
                                 REDUCED_BYTE_SIZE, //byte size of data
                                 &partialDot[0], //destination buffer in host
                                                 //memory
                                 0, //number of events that need to
                                    //complete before transfer executed
                                 0, //list of events that need to complete
                                    //before transfer executed
                                 &profilingEvent); //event identifying this
                                                   //specific operation
    check_cl_error(status, "clEnqueueReadBuffer");

    const double dataTransferTime_ms = get_cl_time(profilingEvent);

    timespec accStart = {0, 0};
    timespec accEnd   = {0, 0};

//FINAL REDUCTION ON HOST    
    clock_gettime(CLOCK_MONOTONIC, &accStart);
    deviceDot = std::accumulate(partialDot.begin(),
                                partialDot.end(), real_t(0));
    clock_gettime(CLOCK_MONOTONIC, &accEnd);
    const double accTime_ms = time_diff_ms(accStart, accEnd);

//COMPUTE DOT PRODUCT ON HOST
    timespec hostStart = {0, 0};
    timespec hostEnd = {0, 0};
    clock_gettime(CLOCK_MONOTONIC, &hostStart);
    if(true || SIZE % CPU_BLOCK_SIZE != 0) hostDot = host_dot_product(V1, V2);
    else hostDot = host_dot_block(&V1[0], &V2[0], SIZE, CPU_BLOCK_SIZE);
    clock_gettime(CLOCK_MONOTONIC, &hostEnd);
    const double host_time = time_diff_ms(hostStart, hostEnd);
//PRINT RESULTS
    std::cout << deviceDot << ' ' << hostDot << std::endl;

    if(check_result(hostDot, deviceDot, EPS)) {
        std::cout << "PASSED" << std::endl;
        std::cout << "kernel:         " << kernelElapsedTime_ms << "ms\n"
                  << "host reduction: " << accTime_ms << "ms\n"
                  << "total:          " << (kernelElapsedTime_ms + accTime_ms)  
                  << "ms" << std::endl;
        std::cout << "transfer:       " << dataTransferTime_ms 
                  << "ms\n" << std::endl;
        if(true || SIZE % CPU_BLOCK_SIZE != 0) {         
            std::cout << "host:              " << host_time << "ms" << std::endl;
        } else {
            std::cout << "host (16k blocks): " << host_time << "ms" << std::endl; 
        }    
       
    } else {
        std::cout << "FAILED" << std::endl;
    }   

    check_cl_error(clReleaseMemObject(devV1), "clReleaseMemObject");
    check_cl_error(clReleaseMemObject(devV2), "clReleaseMemObject");
    check_cl_error(clReleaseMemObject(partialReduction), "clReleaseMemObject");
    release_clenv(clenv);
   
    return 0;
}
示例#10
0
// dequeue the next job that needes to run in this thread
static struct workqueue_job*  _workqueue_get_job(struct workqueue_thread *thread,
			struct TIME_STRUCT_TYPE *wait_time,
			long long *wait_ms)
{
	int i;
	struct workqueue_job *job = NULL;
	struct workqueue_ctx *ctx = thread->ctx;
	struct TIME_STRUCT_TYPE now;

	if (!thread->keep_running)
		return NULL;

	/* init default wait time*/
	GET_TIME(now);
	*wait_time = now;
	TIME_SECP(wait_time) += 9999;  // if no work wait for 9999 sec
	*wait_ms = 5000;

	assert(ctx);
	DEBUG_MSG("thread %d locking ctx\n",thread->thread_num);
	LOCK_MUTEX(&ctx->mutex);
	DEBUG_MSG("thread %d got lock\n",thread->thread_num);
	assert(ctx->queue);

	/* for each queued job item while keep_running
	 serach for a job and break out if we find one */
	for(i = 0; thread->keep_running && i < ctx->queue_size; i++) {

		/* if queue pointer not null there is a job in this slot */
		if (ctx->queue[i]) {

			DEBUG_MSG("job %d set wait=%u.%03lu start_time=%u.%03lu now=%u.%03lu\n", ctx->queue[i]->job_id,
				(unsigned int) TIME_SECP(wait_time), TIME_MSECP(wait_time),
				(unsigned int) TIME_SEC(ctx->queue[i]->start_time), TIME_MSEC(ctx->queue[i]->start_time),
				(unsigned int) TIME_SEC(now), TIME_MSEC(now));

			/* check scheduled time */
			if (_time_gt(&now, &ctx->queue[i]->start_time))  {
				/* job found that must start now */
				job = ctx->queue[i];
				ctx->queue[i] = NULL;
				DEBUG_MSG("found job %d\n", job->job_id);
				ctx->waiting_jobs--;
				break; /* found job ready to run */
			} else if (_time_gt(wait_time, &ctx->queue[i]->start_time)) {
				/* next job in the queue is not scheduled to be run yet */

				/* calculate time thread should sleep for */
				*wait_time = ctx->queue[i]->start_time;
				*wait_ms = time_diff_ms(&ctx->queue[i]->start_time, &now);
				DEBUG_MSG("waiting %lld ms\n", *wait_ms);
				DEBUG_MSG("set wait to %u.%03lu for job %d\n",
					(unsigned int) TIME_SECP(wait_time), TIME_MSECP(wait_time), ctx->queue[i]->job_id);
			} else {
				DEBUG_MSG("no other job\n", NULL);
			}
		}
	}


	DEBUG_MSG("thread %d unlocking ctx job=%p wait=%u.%03lu\n",
			thread->thread_num, job,
			(unsigned int) TIME_SECP(wait_time), TIME_MSECP(wait_time));

	UNLOCK_MUTEX(&ctx->mutex);
	return job;
}
示例#11
0
//Read a max amount of characters into a buffer.
int uart_read(uart_s* uart, uint8_t* buff, int lenmax, int maxms){
	if (uart == NULL){
		return ERROR_NO_UART;
	}
	if (!uart->opened){
		return 0;
	}
	uart_printf(CLR_CANCEL,2,"uart_read\n");

	int n = 0;
	int rlen = 0;
	int number_of_bytes_read=0;
	struct timeval timeout, holdthis;	
	// initialise the timeout structure
	timeout.tv_sec = 0;
	timeout.tv_usec = 1000UL*(uint32_t)maxms; //Wait 200ms
	//timeout.tv_usec = 5000; 

	struct timeval start, now;

	holdthis=timeout;

	int read_size = lenmax;
	
	//Wait for characters to be sent.
	//fsync(uart->fd);
	
	if (uart->fd == -1){
		return -1;
	}

	//Set for reading.
	fd_set readfds;
	FD_ZERO(&readfds);
	FD_SET(uart->fd, &readfds);


	uint32_t diffms;
   	gettimeofday (&start, NULL);


	while(rlen < lenmax){
		n = select(uart->fd + 1, &readfds, NULL, NULL, &timeout);
		uart_printf(CLR_CANCEL,1,"Selecting to %i, lenmax %i, rlen %i, rsz: %i\n",maxms,lenmax,rlen,read_size);
		
		if(n>0){

			number_of_bytes_read = read(uart->fd,&buff[rlen],read_size);	//This starts writing at bufferout[0].
			//scc_printf(SRC_TCPSERV|LEVEL_WARNING,0,"\x1b[37m%d bytes selected in %dusec, appended at: %d, last was '%02X',\r\n" , number_of_bytes_read, holdthis.tv_usec-timeout.tv_usec, rlen, buffer_out[rlen+number_of_bytes_read-1]);
			rlen += number_of_bytes_read;
			read_size -= number_of_bytes_read;

			uart_printf(CLR_CANCEL,1,"n>0: Read %i/%i\n",rlen,lenmax);
			
			//Set the new timeout, or return:
			gettimeofday (&now, NULL);
			diffms = time_diff_ms(&start,&now);
			//printf("Diff: %lu n==%i\n",diffms,n);
			if (diffms > maxms){
				//uart_close(uart);
				return rlen;
			}
			timeout.tv_sec = 0;
			timeout.tv_usec = 1000L*(int32_t)(maxms-diffms);

			uart_printf(CLR_CANCEL,1,"remaining : %lu\n",timeout.tv_usec);
			timeout=holdthis;
			
		}else if(n == 0){
			//Not all characters received.
			//Set the new timeout, or return:
			gettimeofday (&now, NULL);
			diffms = time_diff_ms(&start,&now);
			uart_printf(CLR_CANCEL,1,"Diff: %lu. n==0\n",diffms);
			//uart_close(uart);
			return rlen;
		}else{
			//Port may be occupied.
			//Set the new timeout, or return:
			gettimeofday (&now, NULL);
			diffms = time_diff_ms(&start,&now);
			uart_printf(CLR_CANCEL,1,"Diff: %lu n== -1\n",diffms);
			//uart_close(uart);
		 	return 0;
		}

		
	}


	uart_printf(CLR_CANCEL,1,"Done.\n");
	//uart_close(uart);
	return rlen;
}
示例#12
0
文件: task.cpp 项目: ongbe/TT
int CTask::report()
{
	TestCase *pCase = m_casesList;

	m_uiSuccCases = m_uiTotalCases - m_uiFailCases;
	m_ulTimeTaskDone = time_diff_ms(m_stTimeStartTask,m_stTimeEndTask);

	int sec = m_ulTimeTaskDone/1000;
	int msec = m_ulTimeTaskDone%1000;
	if(0 == sec)
	{
		//g_log.info("[==========]%u tese cases ran.(%lu ms total)\n", m_uiTotalWorkItem, m_ulTimeTaskDone);
		printf_green("[==========]%u tese cases ran.(%lu ms total)\n", m_uiTotalCases, m_ulTimeTaskDone);
	}
	else
	{
		//g_log.info("[==========]%u tese cases ran.(%d.%d s total)\n", m_uiTotalWorkItem, sec, msec);
		printf_green("[==========]%u tese cases ran.(%d.%d s total)\n", m_uiTotalCases, sec, msec);
	}
	//g_log.info("[==PASSED==]%u tese cases!\n",m_succWorkItem);
	printf_green("[==PASSED==]%u tese cases!\n",m_uiSuccCases);
	
	if(m_uiFailCases > 0)
	{	
		//g_log.info("[==FAILED==]%u tese cases,listed below:\n",m_failWorkItem);
		printf_red("[==FAILED==]%u tese cases,listed below:\n",m_uiFailCases);
		
		pCase = m_casesList;
		while(pCase !=  NULL)	
		{
			if(WORKITEM_DONE_FAIL == pCase->status)
			{
				//g_log.info("[==FAILED==]%s\n",pItem->fileName);
				printf_red("[==FAILED==]%s(Reason: %s)\n",pCase->fileName,pCase->errReason);
			}

			pCase = pCase->next;
		}
	}

	printf_yellow("[==STATIC==]transactionName\t\ttotal              \tlost               \tsuccess            \tavgTime(usec)\tminTime(usec)\tmaxTime(usec)\tmaxIdx\n");	
	
	printf_yellow("[==STATIC==]QuoteInterval  \t\t%-19lld\t%-19lld\t%-19lld\t%-10d\t%-10d\t%-10d\t%-19lld\n",
		m_stQuoteIntervalStatic.quoteNum,
		m_stQuoteIntervalStatic.quoteNum - m_stQuoteIntervalStatic.quoteNum, 
		m_stQuoteIntervalStatic.quoteNum, 
		m_stQuoteIntervalStatic.avgQuoteInterval,
		m_stQuoteIntervalStatic.minQuoteInterval,
		m_stQuoteIntervalStatic.maxQuoteInterval,
		m_stQuoteIntervalStatic.maxIdx);	

	printf_yellow("[==STATIC==]tradeProcTime  \t\t%-19lld\t%-19lld\t%-19lld\t%-10d\t%-10d\t%-10d\t%-19lld\n",
		m_stQuoteIntervalStatic.quoteNum,
		m_stQuoteIntervalStatic.quoteNum - m_stTradeProcTimeStatic.tradeNum, 
		m_stTradeProcTimeStatic.tradeNum,		
		m_stTradeProcTimeStatic.avgTimeTradeProcess,
		m_stTradeProcTimeStatic.mixTimeTradeProcess,
		m_stTradeProcTimeStatic.maxTimeTradeProcess,
		m_stTradeProcTimeStatic.maxIdx);


	PrintResultToXML();


	return ATF_SUCC;
}
示例#13
0
文件: task.cpp 项目: ongbe/TT
int CTask::run()
{
	unsigned long timeDiff = 0;
	TestCase *pCase = NULL;
    unsigned int uiCaseDone = 0;
	CCasesParser cases;
	
    //load test cases 
	if(ATF_SUCC != cases.GetCasesList(m_arrTestcasesPath,m_casesList,&m_uiTotalCases))
	{
		g_log.error("Failed to get cases list !\n");
		return ATF_FAIL;
	}

	if(READABLE == m_exchgConf.isValid)
		m_pExchgSvr = new ExchgServer(m_exchgConf);
	if(READABLE == m_quoteConf.isValid)
		m_pQuoteSvr = new QuoteServer(m_quoteConf);
	
    pCase = m_casesList;
	while(NULL != pCase)
	{
		//g_log.info("[RUN       ] %s :\n",pItem->fileName);
		printf_green("[RUN       ] %s :\n",pCase->fileName);

		pCase->startTime = time_get_now();

		if(0 == uiCaseDone)
			m_stTimeStartTask = pCase->startTime;
		
		pCase->status = WORKITEM_DOING;

		//m_pExchgSvr->SetTradeMode(pCase->exchgOrder.tradeMode);
		
		//start exchange simulator
		if(READABLE == m_exchgConf.isValid)
			m_pExchgSvr->StartNewOrder(&pCase->exchgOrder);

		//start quote data server
		if(READABLE == m_quoteConf.isValid)
			m_pQuoteSvr->StartNewOrder(&pCase->quoteOrder);
		

		if(READABLE == m_quoteConf.isValid)
		{
			if(READABLE == m_exchgConf.isValid)
			{
				if(LIMITED == pCase->exchgOrder.tradeMode)
				{
					while(1)
					{
						sleep(1);	
						if(NO_TASK == m_pQuoteSvr->m_status && NO_TASK == m_pExchgSvr->m_status)
						{
							g_log.debug("%s done.\n",pCase->fileName);
							break;
						}
					}
				}
				/*else
				{
					while(!m_pQuoteSvr->GetQuoteSendFlag())
					{
						sleep(1);			
					}
					sleep(1);
					m_pExchgSvr->Finish();
				}*/
			}
			else
			{
				while(1)
				{
					sleep(1);
					if(NO_TASK == m_pQuoteSvr->m_status)
					{
						g_log.debug("%s done.\n",pCase->fileName);
						break;
					}
				}
			}
		}
		else
		{
			if(READABLE == m_exchgConf.isValid)
			{
				if(LIMITED == pCase->exchgOrder.tradeMode)
				{
					while(1)
					{
						sleep(1);	
						if(NO_TASK == m_pExchgSvr->m_status)
						{
							g_log.debug("%s done.\n",pCase->fileName);
							break;
						}
					}
				}
			}
		}

		
		pCase->endTime = time_get_now();
		if(uiCaseDone == m_uiTotalCases - 1)
			m_stTimeEndTask = pCase->endTime;
		timeDiff = time_diff_ms(pCase->startTime,pCase->endTime);
		
		GetCaseResult(pCase);		
		if(WORKITEM_DONE_SUCC == pCase->status)
		{
			//g_log.info("[==SUCCESS==]%s(%lu ms)\n\n",pItem->fileName,timeDiff);
			printf_green("[==SUCCESS==]%s(%lu ms)\n\n",pCase->fileName,timeDiff);
		}
		else if(WORKITEM_DONE_FAIL == pCase->status)
		{
			//g_log.info("[==FAILED==]%s(%lu ms)\n\n",pItem->fileName,timeDiff);
			printf_red("[==FAILED==]%s(%lu ms)\n\n",pCase->fileName,timeDiff);
		}

		pCase = pCase->next;
		uiCaseDone++;
	}


	finishTransact();

	//get static info from ATF agent
	GotStaticInfo();
	
	report();	

	printf("All test cases done.\n");

	return ATF_SUCC;

}
示例#14
0
文件: flusher.c 项目: yqingp/testness
void _flush_buffer_to_child(struct tree *t, struct node *child, struct nmb *buf)
{
	struct mb_iter iter;

	mb_iter_init(&iter, buf->pma);
	while (mb_iter_next(&iter)) {
		/* TODO(BohuTANG): check msn */
		struct nmb_values nvalues;

		nmb_get_values(&iter, &nvalues);

		struct bt_cmd cmd = {
			.msn = nvalues.msn,
			.type = nvalues.type,
			.key = &nvalues.key,
			.val = &nvalues.val,
			.xidpair = nvalues.xidpair
		};
		node_put_cmd(t, child, &cmd);
	}
}

void _flush_some_child(struct tree *t, struct node *parent);

/*
 * PROCESS:
 *	- check child reactivity
 *	- if FISSIBLE: split child
 *	- if FLUSHBLE: flush buffer from child
 * ENTER:
 *	- parent is already locked
 *	- child is already locked
 * EXIT:
 *	- parent is unlocked
 *	- no nodes are locked
 */
void _child_maybe_reactivity(struct tree *t, struct node *parent, struct node *child)
{
	enum reactivity re = get_reactivity(t, child);

	switch (re) {
	case STABLE:
		cache_unpin(t->cf, child->cpair, make_cpair_attr(child));
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		break;
	case FISSIBLE:
		node_split_child(t, parent, child);
		cache_unpin(t->cf, child->cpair, make_cpair_attr(child));
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		break;
	case FLUSHBLE:
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		_flush_some_child(t, child);
		break;
	}
}

/*
 * PROCESS:
 *	- pick a heaviest child of parent
 *	- flush from parent to child
 *	- maybe split/flush child recursively
 * ENTER:
 *	- parent is already locked
 * EXIT:
 *	- parent is unlocked
 *	- no nodes are locked
 */
void _flush_some_child(struct tree *t, struct node *parent)
{
	int childnum;
	enum reactivity re;
	struct node *child;
	struct partition *part;
	struct nmb *buffer;
	struct timespec t1, t2;

	childnum = node_find_heaviest_idx(parent);
	nassert(childnum < parent->n_children);
	part = &parent->parts[childnum];
	buffer = part->ptr.u.nonleaf->buffer;
	if (cache_get_and_pin(t->cf, part->child_nid, (void**)&child, L_WRITE) != NESS_OK) {
		__ERROR("cache get node error, nid [%" PRIu64 "]", part->child_nid);
		return;
	}

	ngettime(&t1);
	re = get_reactivity(t, child);
	if (re == STABLE) {
		node_set_dirty(parent);
		part->ptr.u.nonleaf->buffer = nmb_new(t->e);
		_flush_buffer_to_child(t, child, buffer);
		nmb_free(buffer);
	}
	ngettime(&t2);
	status_add(&t->e->status->tree_flush_child_costs, time_diff_ms(t1, t2));
	status_increment(&t->e->status->tree_flush_child_nums);

	_child_maybe_reactivity(t, parent, child);
}
示例#15
0
static bool rmi_filter_tap_down_proc(struct rmi_filter * tap_filter,
					struct rmi_input_abs_pos *abs_pos)
{
	struct rmi_touchpad * tp = tap_filter->rmi_input->context;
	struct rmi_touchpad_finger * finger = &tp->fingers[abs_pos->n_finger];
	struct rmi_input_abs_pos last_pkt;

	memset(&last_pkt, 0, sizeof(struct rmi_input_abs_pos));
	last_pkt.n_finger = abs_pos->n_finger;
	last_pkt.tool_type = abs_pos->tool_type;
	rmi_touchpad_queue_peek(&finger->finger_fifo, &last_pkt, 0);

	if (  finger->tap_status == 0 &&  abs_pos->z != 0 ) {
		finger->finger_down_pkt = *abs_pos;
		finger->tap_status = 1;
		pr_debug("aaa 5 finger status 1- x:%d y:%d z:%d wx:%d wy:%d\n",
                         abs_pos->x, abs_pos->y, abs_pos->z,
			abs_pos->w_x,abs_pos->w_y);
		return false;
	}
	if ( finger->tap_status == 1 && abs_pos->z != 0 ) {

		//tracking pre-palm
		if ( abs_pos->w_max >= tp->highw_threshold ) {
			pr_debug("aaa 5 palm pkt- x:%d y:%d z:%d wx:%d wy:%d\n",
				abs_pos->x, abs_pos->y, abs_pos->z,
				abs_pos->w_x,abs_pos->w_y);
			finger->last_palm_time_stamp = abs_pos->time_stamp;
			return false;
			//*abs_pos = last_pkt;
			//return true;

		}
		//tap --make sure time interval and distance in range
		if ( 	time_diff_ms (abs_pos->time_stamp,  finger->finger_down_pkt.time_stamp)
			< MAX_TAP_TIME_IN_MS  &&
			abs(abs_pos->x - finger->finger_down_pkt.x) < MAX_TAP_DISTANCE &&
			abs(abs_pos->y - finger->finger_down_pkt.y) < MAX_TAP_DISTANCE )
		{
			pr_debug("aaa 5 tap pkt- x:%d y:%d z:%d wx:%d wy:%d\n",
				 abs_pos->x, abs_pos->y, abs_pos->z,
				abs_pos->w_x,abs_pos->w_y);
			return false;

			//*abs_pos = last_pkt;
			//return true;
		}

		// if detect palm, ignore a few packet after palm
		if (	time_diff_ms(abs_pos->time_stamp,
			finger->last_palm_time_stamp) < MAX_TAP_TIME_IN_MS )
		{
			pr_debug("aaa 5 ignore pkt - x:%d y:%d z:%d wx:%d wy:%d\n",
				 abs_pos->x, abs_pos->y, abs_pos->z,
				abs_pos->w_x,abs_pos->w_y);
			return false;

			//*abs_pos = last_pkt;
			//return true;
		}
		// normal finger move packet
		finger->tap_status = 2;
		pr_debug("aaa 5 normal status 2- x:%d y:%d z:%d wx:%d wy:%d, time: %u\n",
                         abs_pos->x, abs_pos->y, abs_pos->z,
			abs_pos->w_x,abs_pos->w_y,
			time_diff_ms (abs_pos->time_stamp,  finger->finger_down_pkt.time_stamp));
		return true;
	}

	//finger up, this will generate tap
	if ( finger->tap_status == 1  && abs_pos->z == 0
		&& time_diff_ms(abs_pos->time_stamp,
		finger->finger_down_pkt.time_stamp) < MAX_TAP_TIME_IN_MS)
	{
		_rmi_input_report_abs(tap_filter->rmi_input, &finger->finger_down_pkt);
		finger->tap_status = 3;

		pr_debug("aaa 5 tap first pkt- x:%d y:%d z:%d wx:%d wy:%d\n",
		         finger->finger_down_pkt.x, finger->finger_down_pkt.y,
			finger->finger_down_pkt.z,
			finger->finger_down_pkt.w_x,finger->finger_down_pkt.w_y);
		return false;
	} else if (finger->tap_status == 3 && abs_pos->z ==0) {
		finger->tap_status = 0;
		pr_debug("aaa 5 tap up pkt\n");
		return true;
	}
	else if (abs_pos->z == 0) {
		finger->tap_status = 0;
	}

	return true;
}
示例#16
0
static
int connect_with_timeout(struct lttcomm_sock *sock)
{
	unsigned long timeout = lttcomm_get_network_timeout();
	int ret, flags, connect_ret;
	struct timespec orig_time, cur_time;

	ret = fcntl(sock->fd, F_GETFL, 0);
	if (ret == -1) {
		PERROR("fcntl");
		return -1;
	}
	flags = ret;

	/* Set socket to nonblock */
	ret = fcntl(sock->fd, F_SETFL, flags | O_NONBLOCK);
	if (ret == -1) {
		PERROR("fcntl");
		return -1;
	}

	ret = clock_gettime(CLOCK_MONOTONIC, &orig_time);
	if (ret == -1) {
		PERROR("clock_gettime");
		return -1;
	}

	connect_ret = connect(sock->fd,
		(struct sockaddr *) &sock->sockaddr.addr.sin,
		sizeof(sock->sockaddr.addr.sin));
	if (connect_ret == -1 && errno != EAGAIN
			&& errno != EWOULDBLOCK
			&& errno != EINPROGRESS) {
		goto error;
	} else if (!connect_ret) {
		/* Connect succeeded */
		goto success;
	}

	/*
	 * Perform poll loop following EINPROGRESS recommendation from
	 * connect(2) man page.
	 */
	do {
		struct pollfd fds;

		fds.fd = sock->fd;
		fds.events = POLLOUT;
		fds.revents = 0;
		ret = poll(&fds, 1, RECONNECT_DELAY);
		if (ret < 0) {
			goto error;
		} else if (ret > 0) {
			int optval;
			socklen_t optval_len = sizeof(optval);

			if (!(fds.revents & POLLOUT)) {
				/* Either hup or error */
				errno = EPIPE;
				goto error;
			}
			/* got something */
			ret = getsockopt(sock->fd, SOL_SOCKET,
				SO_ERROR, &optval, &optval_len);
			if (ret) {
				goto error;
			}
			if (!optval) {
				connect_ret = 0;
				goto success;
			} else {
				goto error;
			}
		}
		/* ret == 0: timeout */
		ret = clock_gettime(CLOCK_MONOTONIC, &cur_time);
		if (ret == -1) {
			PERROR("clock_gettime");
			connect_ret = ret;
			goto error;
		}
	} while (time_diff_ms(&cur_time, &orig_time) < timeout);

	/* Timeout */
	errno = ETIMEDOUT;
	connect_ret = -1;

success:
	/* Restore initial flags */
	ret = fcntl(sock->fd, F_SETFL, flags);
	if (ret == -1) {
		PERROR("fcntl");
		/* Continue anyway */
	}
error:
	return connect_ret;
}
示例#17
0
/*********************************************************************
 * 
 * MAIN process
 * 
 ********************************************************************/ 
int main(int argc, char* argv[])
{
  pid_t pid;
  int num_counters=0;
  int last_counter;
  int i, k;
  PIN_STATE_t pin_value;
  PIN_STATE_t active_value=LOW;
  struct timespec pulse_start_time, pulse_end_time;
  unsigned char pulse_started;
  
   
  /* Parse input parameters */
  if ((argc==1) || ((argc==2) && !strcmp(argv[1], "-h")))
  {
    printf("Usage:\n");
    printf("  pulsecountd <pin1> <div1> [<statefile1>] [<pin2> <div2> [<statefile2>] ... [<pinN> <divN> [<statefileN>]]]\n");
    printf("      pinX:       kernel Id of GPIO pin to count pulses on (use 0 for dummy pin)\n");
    printf("      divX:       divisor for pulse count values\n");
    printf("      statefileX: file containing the counter selection\n");
    printf("                  (optional, used for dual virtual counters)\n\n");
    printf("      Note: max number of counters is %d\n", MAX_COUNTERS);
    return 1;
  }
 
  memset(counter_param, 0, sizeof(counter_param));
  for (i=1, k=0; i<(argc); i++, k++)
  {
    /* Get pin Id and divisor for each counter */
    counter_param[k].pin = atoi(argv[i++]);
    counter_param[k].divisor = atof(argv[i]);
     
    /* is this the last parameter? */
    if (i<(argc-1))
    {
      /* is next parameter a string (filename)? */
      if ((*argv[i+1] < '0') || (*argv[i+1] > '9'))
      {
        /* next parameter is the optional statefile name, save it */
        strcpy(counter_param[k].statefile, argv[++i]);
      }
    }
    if (counter_param[k].pin) num_counters++;
#if 0
    printf("counter_param[%d].pin=%d\n", k, counter_param[k].pin);
    printf("counter_param[%d].divisor=%f\n", k, counter_param[k].divisor);
    printf("counter_param[%d].statefile=%s\n\n", k, counter_param[k].statefile);
#endif
  }
  last_counter = k;

  openlog("pulsecountd", LOG_PID|LOG_CONS, LOG_USER);
  syslog(LOG_DAEMON | LOG_NOTICE, "Starting Pulse counter daemon (version %s)", VERSION);
  syslog(LOG_DAEMON | LOG_NOTICE, "Using %s logic", (active_value==HIGH)?"ACTIVE_HIGH":"ACTIVE_LOW" );

  /* Install signal handler for SIGTERM and SIGINT ("CTRL C") 
   * to be used to cleanly terminate parent annd child  processes
   */
  signal(SIGTERM, doExit);
  signal(SIGINT, doExit);
  
  /* Save the parent pid (used in signal handler) */
  parentpid = getpid();

  /* Init counter struct */
  memset((void*)&counter, 0, sizeof(counter));
  
  syslog(LOG_DAEMON | LOG_NOTICE, "Creating %d counter processes", num_counters);
  
  /* Create a child process for each counter */
  for (i=0; i<last_counter; i++)
  {  
    /* Check for dummy pin */
    if (counter_param[i].pin == 0) continue;
    
    /* Create child */
    pid=fork();
    
    if (pid == -1)
    {
      syslog(LOG_DAEMON | LOG_ERR, "Error creating child process for counter %d", i+1);
      return 2;
    }
    
    if (pid != 0)
    {
      /***** We are in the parent process *****/

      /* Save child pid */
      counter_param[i].child_pid=pid;
    }
    else
    {
      /***** We are in the child process *****/
         
      syslog(LOG_DAEMON | LOG_NOTICE, "Started child process counting pulses on GPIO pin with Kernel Id %d", 
                                                                                      counter_param[i].pin);
      
      /* Init */
      if (setup(counter_param[i], &counter) != 0)
      {
        /* Setup failed, wait to be terminated */
        while (1) usleep(100000);
      }
      
      /* Wait for possibly ongoing pulse to end */   
      while (digitalRead(counter.value_fd) == active_value) usleep(100000);
      pulse_started = 0;
      
      
      /***** Main child loop *****/
      while (1)
      {
        if (waitForEdge(&pin_value, counter.value_fd) == 0)
        {
          if (pin_value == active_value)
          {
            /* Pulse started */
            if (pulse_started == 0)
            {
              clock_gettime(CLOCK_REALTIME, &pulse_start_time);
              pulse_started = 1;
            }
            else
            {
#if DEBUG
              syslog(LOG_DAEMON | LOG_DEBUG, "Warning: detected starting pulse out of sequence on pin %d",
                                              counter_param[i].pin);
#endif
            }
          }
          else
          {
            char str[20];
            
            /* Pulse ended */
            if (pulse_started == 1)
            {
              clock_gettime(CLOCK_REALTIME, &pulse_end_time);
#if DEBUG
              syslog(LOG_DAEMON | LOG_DEBUG, "Detected pulse with length %lu ms on pin %d", 
                                              time_diff_ms(pulse_end_time, pulse_start_time), counter_param[i].pin);
#endif
              pulse_started = 0;
            }
            else
            {
#if DEBUG
              syslog(LOG_DAEMON | LOG_DEBUG, "Warning: detected ending pulse out of sequence on pin %d",
                                              counter_param[i].pin);
#endif
              continue;
            }
            
            /* TODO: check pulse lenght and filter glitches */
            
            /* Check statefile for which virtual counter to increment */
            switch (stateRead(counter.state_fd))
            {
               case 1:
                  /* Increment counter 1, apply divisor and save value */
                  counter.pulse_count1++;
                  sprintf(str, "%010lu\n", (unsigned long)(counter.pulse_count1/counter.divisor));
                  pwrite(counter.export1_fd, str, strlen(str), 0);
                  break;
                  
               case 2:
                  /* Increment counter 2, apply divisor and save value */
                  counter.pulse_count2++;
                  sprintf(str, "%010lu\n", (unsigned long)(counter.pulse_count2/counter.divisor));
                  pwrite(counter.export2_fd, str, strlen(str), 0);
                  break;
                  
               default:
                  /* unknown state, do nothing */
                  ;
                  //printf("unknown value %d in statefile\n", stateRead(counter.state_fd));
            }
          }
        }
        else
        {
          /* waitForEdge failed, wait to be terminated */
          while (1) usleep(100000);
        }
      }
    }
  }
  
  /* Create child process for TCP server */
  modbus_server_pid=fork();
  if (modbus_server_pid == -1)
  {
    syslog(LOG_DAEMON | LOG_ERR, "Error creating child process for Modbus server");
    return 3;
  }
    
  if (modbus_server_pid == 0)
  {
    /***** We are in the child process *****/
    
    modbus_server_pid = getpid();
   
    /* Start Modbus TCP server loop */
    modbustcp_server(MODBUS_SLAVE_ADDRESS,  // Modbus slave address
                     read_register_handler, // Read register handler
                     NULL                   // Write register handler
                    );
  }
  else
  {
    /***** We are in the parent process *****/

    /* Wait for termination signal */
    while (cont) sleep(1);
  }

  
  /* Wait for all counter child processes to terminate */
  for (i=0; i<last_counter; i++)
  {
    /* Check for dummy pin */
    if (counter_param[i].pin == 0) continue;
    
    kill(counter_param[i].child_pid, SIGTERM);
    if (waitpid(counter_param[i].child_pid, NULL, 0) == counter_param[i].child_pid)
    {
      syslog(LOG_DAEMON | LOG_NOTICE, "Child process %d successfully terminated", counter_param[i].child_pid);
    }
    else
    {
      syslog(LOG_DAEMON | LOG_ERR, "Error terminating child process %d", counter_param[i].child_pid);
    }
  }
  
  /* Terminate Modbus server */
  kill(modbus_server_pid, SIGTERM);
  if (waitpid(modbus_server_pid, NULL, 0) == modbus_server_pid)
  {
    syslog(LOG_DAEMON | LOG_NOTICE, "Modbus server process %d successfully terminated", modbus_server_pid);
  }
  else
  {
    syslog(LOG_DAEMON | LOG_ERR, "Error terminating Modbus server process %d", modbus_server_pid);
  }
  
  syslog(LOG_DAEMON | LOG_NOTICE, "Exiting Pulse counter daemon");
  closelog();
   
  return 0;
}