Beispiel #1
0
void Pipe::Run() {
  Parts *parts = CreateParts();
  Features *features = CreateFeatures();
  vector<double> scores;
  vector<double> gold_outputs;
  vector<double> predicted_outputs;

  timeval start, end;
  gettimeofday(&start, NULL);

  if (options_->evaluate()) BeginEvaluation();

  reader_->Open(options_->GetTestFilePath());
  writer_->Open(options_->GetOutputFilePath());

  int num_instances = 0;
  Instance *instance = reader_->GetNext();
  while (instance) {
    Instance *formatted_instance = GetFormattedInstance(instance);

    MakeParts(formatted_instance, parts, &gold_outputs);
    MakeFeatures(formatted_instance, parts, features);
    ComputeScores(formatted_instance, parts, features, &scores);
    decoder_->Decode(formatted_instance, parts, scores, &predicted_outputs);

    Instance *output_instance = instance->Copy();
    LabelInstance(parts, predicted_outputs, output_instance);

    if (options_->evaluate()) {
      EvaluateInstance(instance, output_instance,
                       parts, gold_outputs, predicted_outputs);
    }

    writer_->Write(output_instance);

    if (formatted_instance != instance) delete formatted_instance;
    delete output_instance;
    delete instance;

    instance = reader_->GetNext();
    ++num_instances;
  }

  delete parts;
  delete features;

  writer_->Close();
  reader_->Close();

  gettimeofday(&end, NULL);
  LOG(INFO) << "Number of instances: " << num_instances;
  LOG(INFO) << "Time: " << diff_ms(end,start);

  if (options_->evaluate()) EndEvaluation();
}
Beispiel #2
0
// Reliably sends an array of packets
void rdt_send_packets(struct packet *packets, int sockfd, struct sockaddr_in cli_addr, socklen_t clilen, int cwndsize)
{
  int nextseqnum = 0;
  int base = 0;
  int all_sent = 0;
  int i;

  int timer_running = 0;
  clock_t timer_start = 0;

  while(!all_sent || (base < nextseqnum)) {
    while (nextseqnum < base + cwndsize && !all_sent) {
      send_packet(packets[nextseqnum], sockfd, cli_addr, clilen);
      if (base == nextseqnum) {
        timer_running = 1;
        timer_start = clock();
      }
      if (packets[nextseqnum].type == TYPE_FINAL_DATA) {
        all_sent = 1;
        nextseqnum++;
        break;
      }
      nextseqnum++;
    }

    int ack = listen_for_ack(sockfd);
    if (ack != -99) {
      base = ack + 1;
      if (base == nextseqnum) {
        timer_running = 0;
      }
      else {
        timer_running = 1;
        timer_start = clock();
      }
    }
  
    // Check for timeout
    // fprintf(stderr, "timer_running: %d. diff: %f. RTO: %d\n", timer_running, diff_ms(timer_start, clock()), RETRANSMIT_TIMEOUT);
    if (timer_running && ( diff_ms(timer_start, clock()) > RETRANSMIT_TIMEOUT ) ) {
      printf("Timeout on packet %d. Retransmitting packet(s) %d to %d:\n", base, base, nextseqnum-1);
      timer_running = 1;
      timer_start = clock();
      for (i = base; i < nextseqnum; i++) {
        send_packet(packets[i], sockfd, cli_addr, clilen);
      }
    }
  }
}
void TurboTaggerWorker::LoadTaggerModel(const std::string &file_model) {
  tagger_options_->SetModelFilePath(file_model);

  int time;
  timeval start, end;
  gettimeofday(&start, NULL);

  tagger_pipe_->LoadModelFile();

  gettimeofday(&end, NULL);
  time = diff_ms(end,start);

  LOG(INFO) << "Took " << static_cast<double>(time)/1000.0
            << " sec." << endl;
}
void TurboEntityRecognizerWorker::Tag(const std::string &file_test,
                                      const std::string &file_prediction) {
  entity_options_->SetTestFilePath(file_test);
  entity_options_->SetOutputFilePath(file_prediction);

  int time;
  timeval start, end;
  gettimeofday(&start, NULL);

  entity_pipe_->Run();

  gettimeofday(&end, NULL);
  time = diff_ms(end,start);

  LOG(INFO) << "Took " << static_cast<double>(time)/1000.0
            << " sec." << endl;
}
void TurboSemanticParserWorker::ParseSemanticDependencies(
    const std::string &file_test,
    const std::string &file_prediction) {
  semantic_options_->SetTestFilePath(file_test);
  semantic_options_->SetOutputFilePath(file_prediction);

  int time;
  timeval start, end;
  gettimeofday(&start, NULL);

  semantic_pipe_->Run();

  gettimeofday(&end, NULL);
  time = diff_ms(end,start);

  LOG(INFO) << "Took " << static_cast<double>(time)/1000.0
            << " sec." << endl;
}
Beispiel #6
0
void Pipe::CreateInstances() {
  timeval start, end;
  gettimeofday(&start, NULL);

  LOG(INFO) << "Creating instances...";

  reader_->Open(options_->GetTrainingFilePath());
  DeleteInstances();
  Instance *instance = reader_->GetNext();
  while (instance) {
    AddInstance(instance);
    instance = reader_->GetNext();
  }
  reader_->Close();

  LOG(INFO) << "Number of instances: " << instances_.size();

  gettimeofday(&end, NULL);
  LOG(INFO) << "Time: " << diff_ms(end,start);
}
void TestConstituencyLabeler() {
  int time;
  timeval start, end;
  gettimeofday(&start, NULL);

  ConstituencyLabelerOptions *options = new ConstituencyLabelerOptions;
  options->Initialize();

  ConstituencyLabelerPipe *pipe = new ConstituencyLabelerPipe(options);
  pipe->Initialize();
  pipe->LoadModelFile();
  pipe->Run();

  delete pipe;
  delete options;

  gettimeofday(&end, NULL);
  time = diff_ms(end, start);

  LOG(INFO) << "Testing took " << static_cast<double>(time) / 1000.0
    << " sec." << endl;
}
Beispiel #8
0
void TournamentSR::spawn_player(Player *p) {
    if (!server) {
        TimesOfPlayer *top = get_times_of_player(p);
        if (top) {
            if (!top->running) {
                top->running = true;
            } else {
                if (top->finished) {
                    top->finished = false;
                    gametime_t now;
                    get_now(now);
                    ms_t d_ms = diff_ms(top->start_time, now);
                    GTransportTime *race = new GTransportTime;
                    race->id = p->state.id;
                    race->ms = static_cast<sr_milliseconds_t>(d_ms);
                    race->to_net();
                    add_state_response(GPSRoundFinished, GTransportTimeLen, race);
                }
            }
            get_now(top->start_time);
        }
    }
    Tournament::spawn_player(p);
}
void TrainCoreferenceResolver() {
  int time;
  timeval start, end;
  gettimeofday(&start, NULL);

  CoreferenceOptions *options = new CoreferenceOptions;
  options->Initialize();

  CoreferencePipe *pipe = new CoreferencePipe(options);
  pipe->Initialize();

  LOG(INFO) << "Training the coreference resolver...";
  pipe->Train();
  pipe->SaveModelFile();

  delete pipe;
  delete options;

  gettimeofday(&end, NULL);
  time = diff_ms(end, start);

  LOG(INFO) << "Training took " << static_cast<double>(time) / 1000.0
    << " sec." << endl;
}
Beispiel #10
0
void TournamentSR::draw_score() {
    Player *me = get_me();
    if (!(me->state.server_state.flags & PlayerServerFlagSpectating)) {
        TimesOfPlayer *top = get_times_of_player(me);
        if (top) {
            subsystem.set_color(0.75f, 0.75f, 1.0f, 0.75f);

            if (!game_over) {
                get_now(now_for_drawing);
            }
            ms_t d_ms = diff_ms(top->start_time, now_for_drawing);
            float diff = round(d_ms / 10.0f) / 100.0f;

            char *pb;
            int len;
            int x;
            int view_width = subsystem.get_view_width();
            Tileset *ts = resources.get_tileset("numbers");
            int tile_width = ts->get_tile(0)->get_tilegraphic()->get_width();
            int number_width = tile_width - 13;
            int i = static_cast<int>(floor(diff));
            int m = static_cast<int>((diff - i) * 100);

            /* first part */
            sprintf(buffer, "%d", i);
            len = strlen(buffer);
            x = view_width / 2 - (len * number_width) - number_width / 2;
            pb = buffer;
            while (*pb) {
                subsystem.draw_tile(ts->get_tile(*pb - '0'), x, 5);
                x += number_width;
                pb++;
            }

            /* draw dot */
            subsystem.draw_tile(ts->get_tile(11), x, 5);
            x += number_width;

            /* second part */
            sprintf(buffer, "%02d", m);
            pb = buffer;
            while (*pb) {
                subsystem.draw_tile(ts->get_tile(*pb - '0'), x, 5);
                x += number_width;
                pb++;
            }

            /* reset */
            subsystem.reset_color();

            /* draw best & last lap */
            size_t sz = top->times.size();
            Font *f = resources.get_font("big");

            const TimesOfPlayer& lead = times_of_players[0];
            if (lead.times.size()) {
                subsystem.set_color(0.25f, 1.0f, 0.25f, 1.0f);
                subsystem.draw_text(f, 5, 5, "lead:");
                sprintf(buffer, "%.2f (%s)", lead.best, lead.player->get_player_name().c_str());
                subsystem.draw_text(f, 45, 5, buffer);
                subsystem.reset_color();
            }

            subsystem.draw_text(f, 5, 20, "lap:");
            sprintf(buffer, "%d", static_cast<int>(sz + 1));
            subsystem.draw_text(f, 45, 20, buffer);

            if (sz) {
                subsystem.draw_text(f, 5, 35, "best:");
                sprintf(buffer, "%.2f", top->best);
                subsystem.draw_text(f, 45, 35, buffer);

                subsystem.draw_text(f, 5, 50, "last:");
                sprintf(buffer, "%.2f", top->last);
                subsystem.draw_text(f, 45, 50, buffer);
            }
        }
    }
}
Beispiel #11
0
void Pipe::TrainEpoch(int epoch) {
  Instance *instance;
  Parts *parts = CreateParts();
  Features *features = CreateFeatures();
  vector<double> scores;
  vector<double> gold_outputs;
  vector<double> predicted_outputs;
  double total_cost = 0.0;
  double total_loss = 0.0;
  double eta;
  int num_instances = instances_.size();
  double lambda = 1.0/(options_->GetRegularizationConstant() *
                       (static_cast<double>(num_instances)));
  timeval start, end;
  gettimeofday(&start, NULL);
  int time_decoding = 0;
  int time_scores = 0;
  int num_mistakes = 0;

  LOG(INFO) << " Iteration #" << epoch + 1;

  dictionary_->StopGrowth();

  for (int i = 0; i < instances_.size(); i++) {
    int t = num_instances * epoch + i;
    instance = instances_[i];
    MakeParts(instance, parts, &gold_outputs);
    MakeFeatures(instance, parts, features);

    // If using only supported features, must remove the unsupported ones.
    // This is necessary not to mess up the computation of the squared norm
    // of the feature difference vector in MIRA.
    if (options_->only_supported_features()) {
      RemoveUnsupportedFeatures(instance, parts, features);
    }

    timeval start_scores, end_scores;
    gettimeofday(&start_scores, NULL);
    ComputeScores(instance, parts, features, &scores);
    gettimeofday(&end_scores, NULL);
    time_scores += diff_ms(end_scores, start_scores);

    if (options_->GetTrainingAlgorithm() == "perceptron" ||
        options_->GetTrainingAlgorithm() == "mira" ) {
      timeval start_decoding, end_decoding;
      gettimeofday(&start_decoding, NULL);
      decoder_->Decode(instance, parts, scores, &predicted_outputs);
      gettimeofday(&end_decoding, NULL);
      time_decoding += diff_ms(end_decoding, start_decoding);

      if (options_->GetTrainingAlgorithm() == "perceptron") {
        for (int r = 0; r < parts->size(); ++r) {
          if (!NEARLY_EQ_TOL(gold_outputs[r], predicted_outputs[r], 1e-6)) {
            ++num_mistakes;
          }
        }
        eta = 1.0;
      } else {
        CHECK(false) << "Plain mira is not implemented yet.";
      }

      MakeGradientStep(parts, features, eta, t, gold_outputs,
                       predicted_outputs);

    } else if (options_->GetTrainingAlgorithm() == "svm_mira" ||
               options_->GetTrainingAlgorithm() == "crf_mira" ||
               options_->GetTrainingAlgorithm() == "svm_sgd" ||
               options_->GetTrainingAlgorithm() == "crf_sgd") {
      double loss;
      timeval start_decoding, end_decoding;
      gettimeofday(&start_decoding, NULL);
      if (options_->GetTrainingAlgorithm() == "svm_mira" ||
          options_->GetTrainingAlgorithm() == "svm_sgd") {
        // Do cost-augmented inference.
        double cost;
        decoder_->DecodeCostAugmented(instance, parts, scores, gold_outputs,
                                      &predicted_outputs, &cost, &loss);
        total_cost += cost;
      } else {
        // Do marginal inference.
        double entropy;
        decoder_->DecodeMarginals(instance, parts, scores, gold_outputs,
                                  &predicted_outputs, &entropy, &loss);
        CHECK_GE(entropy, 0.0);
      }
      gettimeofday(&end_decoding, NULL);
      time_decoding += diff_ms(end_decoding, start_decoding);

      if (loss < 0.0) {
        if (!NEARLY_EQ_TOL(loss, 0.0, 1e-9)) {
          LOG(INFO) << "Warning: negative loss set to zero: " << loss;
        }
        loss = 0.0;
      }
      total_loss += loss;

      // Compute difference between predicted and gold feature vectors.
      FeatureVector difference;
      MakeFeatureDifference(parts, features, gold_outputs, predicted_outputs,
                            &difference);

      // Get the stepsize.
      if (options_->GetTrainingAlgorithm() == "svm_mira" ||
          options_->GetTrainingAlgorithm() == "crf_mira") {
        double squared_norm = difference.GetSquaredNorm();
        double threshold = 1e-9;
        if (loss < threshold || squared_norm < threshold) {
          eta = 0.0;
        } else {
          eta = loss / squared_norm;
          if (eta > options_->GetRegularizationConstant()) {
            eta = options_->GetRegularizationConstant();
          }
        }
      } else {
        if (options_->GetLearningRateSchedule() == "fixed") {
          eta = options_->GetInitialLearningRate();
        } else if (options_->GetLearningRateSchedule() == "invsqrt") {
          eta = options_->GetInitialLearningRate() /
            sqrt(static_cast<double>(t+1));
        } else if (options_->GetLearningRateSchedule() == "inv") {
          eta = options_->GetInitialLearningRate() /
            static_cast<double>(t+1);
        } else if (options_->GetLearningRateSchedule() == "lecun") {
          eta = options_->GetInitialLearningRate() /
            (1.0 + (static_cast<double>(t) / static_cast<double>(num_instances)));
        } else {
          CHECK(false) << "Unknown learning rate schedule: "
                       << options_->GetLearningRateSchedule();
        }

        // Scale the parameter vector (only for SGD).
        double decay = 1 - eta * lambda;
        CHECK_GT(decay, 0.0);
        parameters_->Scale(decay);
      }

      MakeGradientStep(parts, features, eta, t, gold_outputs,
                       predicted_outputs);
    } else {
      CHECK(false) << "Unknown algorithm: " << options_->GetTrainingAlgorithm();
    }
  }

  // Compute the regularization value (halved squared L2 norm of the weights).
  double regularization_value =
      lambda * static_cast<double>(num_instances) *
      parameters_->GetSquaredNorm() / 2.0;

  delete parts;
  delete features;

  gettimeofday(&end, NULL);
  LOG(INFO) << "Time: " << diff_ms(end,start);
  LOG(INFO) << "Time to score: " << time_scores;
  LOG(INFO) << "Time to decode: " << time_decoding;
  LOG(INFO) << "Number of Features: " << parameters_->Size();
  if (options_->GetTrainingAlgorithm() == "perceptron" ||
      options_->GetTrainingAlgorithm() == "mira") {
    LOG(INFO) << "Number of mistakes: " << num_mistakes;
  }
  LOG(INFO) << "Total Cost: " << total_cost << "\t"
            << "Total Loss: " << total_loss << "\t"
            << "Total Reg: " << regularization_value << "\t"
            << "Total Loss+Reg: " << total_loss + regularization_value << endl;
}
Beispiel #12
0
int main(int argc, char *argv[])
{
    int sockfd; // socket descriptor
    struct hostent *server; // contains tons of information, including the server's IP address
    int portno;
    char * filename;
    FILE * f;
    double lossprob;
    double corruptprob;
    int result;
    socklen_t servlen;
    struct sockaddr_in serv_addr;
    struct packet request;
    struct packet receive;
    int expected_seq = 0;

    // initialize random number generator
    srand(time(NULL));

    if (argc < 6) {
       fprintf(stderr,"usage %s <hostname> <port> <filename> <loss probability> <corruption probability>\n", argv[0]);
       exit(1);
    }

    // get command line arguments
    server = gethostbyname(argv[1]);
    portno = atoi(argv[2]);
    filename = argv[3];
    lossprob = atof(argv[4]);
    corruptprob = atof(argv[5]);

    // error checks on arguments
    if (lossprob < 0.0 || lossprob > 1.0)
        error("packet loss probability must be between 0 and 1");
    if (corruptprob < 0.0 || corruptprob > 1.0)
        error("packet corruption probability must be between 0 and 1");
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    // create UDP socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    
    // fill in address info
    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);
    
    // create request
    memset((char *) &request, 0, sizeof(request));
    strcpy(request.data, filename);
    request.length = strlen(filename) + 1;
    request.type = TYPE_REQUEST;
    checksum(&request);

    // send request
    if (sendto(sockfd, &request, sizeof(request), 0, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
      error("ERROR sending request");
    printf("Sent request for file %s\n", filename);

    // in case request is lost at sender, enter timeout and resend if necessary
    int received_first_ack = 0;
    clock_t timer_start = clock();

    // create copy of file on receiver's end
    char * prefix = "copy_";
    char * filecopy = malloc(strlen(filename) + strlen(prefix) + 1);
    strcpy(filecopy, prefix);
    strcat(filecopy, filename);
    f = fopen(filecopy, "w");

    // scan for messages from server
    int time_wait_running = 0;
    while (1) {

        // resend request if timeout
        if (!received_first_ack && ( diff_ms(timer_start, clock()) > RETRANSMIT_TIMEOUT )) {
            // send request
            if (sendto(sockfd, &request, sizeof(request), 0, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
              error("ERROR sending request");
            printf("Sent request for file %s\n", filename);
            timer_start = clock();
        }

        if ( time_wait_running && ( diff_ms(timer_start, clock()) > TIME_WAIT ) ) {
            printf("Exiting time wait state.\n");
            break;
        }
        if (is_readable(sockfd)) {
            result = rdt_receive(sockfd, &receive, sizeof(receive), (struct sockaddr *) &serv_addr, &servlen, lossprob, corruptprob, expected_seq);
            if (received_first_ack == 0) {
                received_first_ack = 1;
            }
            if (result == RESULT_PACKET_OK) {
                send_ack(expected_seq, sockfd, serv_addr);
                expected_seq++;
                // transfer data to receiver's copy of the file
                fwrite(receive.data, 1, receive.length, f);
            }
            // don't send ACK if packet loss
            else if (result == RESULT_PACKET_CORRUPT || result == RESULT_PACKET_OUT_OF_ORDER) {
                send_ack(expected_seq - 1, sockfd, serv_addr);
            }
        }
        // only end if final ACK wasn't out of order, lost, or corrupt
        if(receive.type == TYPE_FINAL_DATA && result == RESULT_PACKET_OK && time_wait_running == 0) {
            printf("Final ACK sent, entering time wait state in case ACK is not received by sender.\n");
            timer_start = clock();
            time_wait_running = 1;
        }
    }


    close(sockfd);
    fclose(f);
    free(filecopy);
    return 0;
}
Beispiel #13
0
static
void *thread(void *data)
{
	(void)data;
#if 0
	while (1) {
#else
	for (unsigned cnt = 0; cnt < print_iterations; ++cnt) {
#endif
		for (unsigned i = 0; i < inc_iterations; ++i) {
			pthread_mutex_lock(&mtx);
			globalcounter++;
			pthread_mutex_unlock(&mtx);
		}

		pthread_mutex_lock(&mtx);
		printf("\033[31mThread: %d\n", globalcounter);
		pthread_mutex_unlock(&mtx);
	}
	return NULL;
}


static int diff_ms(struct timeval *t1, struct timeval *t2)
{
	return (((t1->tv_sec - t2->tv_sec) * 1000000) + 
	        (t1->tv_usec - t2->tv_usec))/1000;
}


int main(int argc, char **argv)
{
	(void)argc; (void)argv;

	pthread_t pt;

	struct timeval start, stop;

	gettimeofday(&start, NULL);

	pthread_mutex_init(&mtx, 0);

	int res = pthread_create(&pt, NULL, thread, NULL);
	assert(res == 0);

#if 0
	while (1) {
#else
	for (unsigned cnt = 0; cnt < print_iterations; ++cnt) {
#endif
		for (unsigned i = 0; i < inc_iterations; ++i) {
			pthread_mutex_lock(&mtx);
			globalcounter++;
			pthread_mutex_unlock(&mtx);
		}

		pthread_mutex_lock(&mtx);
		printf("\033[32mMain: %d\n", globalcounter);
		pthread_mutex_unlock(&mtx);
	}

	pthread_join(pt, NULL);
	printf("joined\n");

	gettimeofday(&stop, NULL);

	unsigned long ms = diff_ms(&stop, &start);
	printf("Start %ld.%ld --- Stop %ld.%ld --- Diff %ld.%03ld\n",
	       start.tv_sec, start.tv_usec, stop.tv_sec, stop.tv_usec,
	       ms / 1000, ms % 1000);

	//enter_kdebug("before return");

	return 0;
}
int SSerialInterface::serial_main( )
{
	Dprintf("Linux Loadcell serial app\n");
	if (!_cl_port) { 
		printf("serial_main() - ERROR: Port argument required\n");
	}

	// Specify with the "-p" option.  Should refer to "/dev/ttyUSB0" or other.
	if (_cl_port==NULL)
		return -1;

	// WRITE 1 or 2 BYTES (stored in _cl_single_byte & _cl_another_byte) :
	if (_cl_single_byte >= 0) {
		unsigned char data[2];
		data[0] = (unsigned char)_cl_single_byte;
		if (_cl_another_byte < 0) {
			write(_fd, &data, 1);
		} else {
			data[1] = _cl_another_byte;
			write(_fd, &data, 2);
		}
		return 0;
	}

	// while either User option: "-r" and "-t"
	printf("Entering serial_main while () loop\n");
	while (!(_cl_no_rx && _cl_no_tx)) 
	{
		int retval = poll( &serial_poll, 1, 1000 );
		if (retval == -1) {
			perror("poll()");
		} else if (retval) {
			// Received Data : 
			if (serial_poll.revents & POLLIN) { /* Recieve */
				printf("Poll received\n");
				// 
				if (_cl_rx_delay) { 
					// only read if it has been rx-delay ms
					// since the last read
					struct timespec current;
					clock_gettime(CLOCK_MONOTONIC, &current);
					if (diff_ms(&current, &last_read) > _cl_rx_delay) {
						process_read_data();
						last_read = current;
					}
				} else {
					process_read_data();
				}
			}

			// Transmit Buffer Empty : 
			if (serial_poll.revents & POLLOUT) {

				if (_cl_tx_delay) {
					// only write if it has been tx-delay ms
					// since the last write
					struct timespec current;
					clock_gettime(CLOCK_MONOTONIC, &current);
					if (diff_ms(&current, &last_write) > _cl_tx_delay) {
						process_write_data();
						last_write = current;
					}
				} else {
					//printf(".");
					process_write_data();
				}
			}
		} else if (!(_cl_no_tx && _write_count != 0 && _write_count == _read_count)) {
			// No data. We report this unless we are no longer
			// transmitting and the receive count equals the
			// transmit count, suggesting a loopback test that has
			// finished.
			printf("No data within one second. %s\n", _cl_port);
		}

		if (_cl_stats || _cl_tx_time || _cl_rx_time) {
			struct timespec current;
			clock_gettime(CLOCK_MONOTONIC, &current);

			if (_cl_stats) {
				if (current.tv_sec - last_stat.tv_sec > 5) {
					dump_serial_port_stats();
					last_stat = current;
				}
			}
			if (_cl_tx_time) {
				if (current.tv_sec - start_time.tv_sec >= _cl_tx_time) {
					_cl_tx_time = 0;
					_cl_no_tx = 1;
					serial_poll.events &= ~POLLOUT;
					printf("Stopped transmitting.\n");
				}
			}
			if (_cl_rx_time) {
				if (current.tv_sec - start_time.tv_sec >= _cl_rx_time) {
					_cl_rx_time = 0;
					_cl_no_rx = 1;
					serial_poll.events &= ~POLLIN;
					printf("Stopped receiving.\n");
				}
			}
		}
	}

	tcdrain(_fd);
	dump_serial_port_stats();
	tcflush(_fd, TCIOFLUSH);
	free(_cl_port);

	printf("serial_main()  Thread Terminated.\n");
	int result = abs(_write_count - _read_count) + _error_count;
	return (result > 255) ? 255 : result;
}