popen or fopen freezes my code

Pages: 12
@dhayden
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
void resync(){

    //first lets make some objects to be used later
    struct sysinfo memInfo;//struct to check memory usage
    int iteration = 0;//iteration counter
    uint64_t nextTimeSeconds;
    uint64_t nextTimeMicroSeconds;

	//Sleep until x minute to sync/run chassis simultaneously
	using std::chrono::system_clock;
	std::time_t tt = system_clock::to_time_t (system_clock::now());
	struct std::tm * ptm = std::localtime(&tt);
	std::cout << "Waiting for the next minute to begin...\n";
	++ptm->tm_min; 
	ptm->tm_sec=0;
	std::this_thread::sleep_until (system_clock::from_time_t (mktime(ptm)));

    //do some arithemtic to ensure there are no nonzero decimals on our time object     
    chrono::high_resolution_clock::time_point currTime = chrono::high_resolution_clock::now();
    chrono::high_resolution_clock::time_point nextTime;
    auto currTimeNanoDecimals = (chrono::duration_cast<chrono::nanoseconds>(currTime.time_since_epoch()).count()) -((chrono::duration_cast<chrono::seconds>(currTime.time_since_epoch()).count()) * 1000000000); //find decimals for flooring 

    currTime = currTime - chrono::nanoseconds(currTimeNanoDecimals); //floor to second 
	
    //main program loop
    for(int j = 0; j < (runs); j++) //change this to change how many iterations the FPGA timestamp resyncs for
{
	nextTime = currTime + chrono::seconds(1); //incrementing for next time 
    nextTimeSeconds = chrono::duration_cast<chrono::seconds>(nextTime.time_since_epoch()).count();
    nextTimeMicroSeconds = nextTimeSeconds * 1000000;


	cout << "	Time cycle "<< chrono::duration_cast<chrono::microseconds>(currTime.time_since_epoch()).count() << " to "<< nextTimeMicroSeconds<<"\n\n";

        myfile<<iteration<<",";
       	myfile<< nextTimeSeconds<<","; //nextMicroSec
	//Add easy to read time here
	writeTime();

	chrono::high_resolution_clock::time_point epochTime = chrono::high_resolution_clock::now();
	double epocTime = chrono::duration_cast<chrono::nanoseconds>(epochTime.time_since_epoch()).count();	
	epocTime /= 1E9;

	myfile<<fixed<<epocTime<<",";	

    this_thread::sleep_until(currTime + chrono::nanoseconds(500000000));    
    
ntpSync();

//change some values before next iteration
        currTime = nextTime; //comment out if testing with one sec
        iteration++; 
	this_thread::sleep_until(nextTime);

	cout<<"Current time at end  :                            			 	"<< chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count()<<endl;


    }

}


    
// MAIN
	int main(int argc, char *argv[])
{	
	init();

	myfile<<"iteration, Next Second, current time, current time (epoch), Offset between the local cloak and the source at last measurement [actual measure offset]"<<"\n";

    resync();

    //close out the files
    myfile.close();


    return 0;

}

This is from just the ntpsync code without reading the other registers. Ive run it with the writeTime commented out so that can be ignored/isnt the culprint.

I thought it may be the wait until part but it freezes inconsistently (due to it freezing at random print statements).
Last edited on
Please post the code for sleep_until().



One problem is that you're reading the current time multiple times throughout the code and it can change from one to the next. For example, at line 11, you read the time. Suppose it's 3:29.999999999. Lines 14 & 15 computer 3:30 and line 16 waits until 3:30. But by then, maybe the clock time is 3:30.000001. If sleep_until() doesn't account for the possibility of being given a time in the past, the duration could overflow and cause you to sleep for a very VERY long time.

Along the same line 46 assumes that the each iteration of the loop completes in less that 500ms. If it doesn't (which might happen if there's a network error, or if the writes to myfile get delayed, or the system clock gets updated), then you'll be asking to sleep until time that has already passed.
sleep until is a built in cpp function
http://www.cplusplus.com/reference/thread/this_thread/sleep_until/

lines 10-16 only run once and it never freezes there. Everything executes/is on the microsecond scale except for the sleep until so that shouldnt be an issue.
Print the value you're passing to sleep_until() before each call. Be sure to flush it. e.g.,
myfile << "sleep_until(" << currTime + chrono::nanoseconds(500000000) << ')' << endl;


Let's see what's being passed to it, and if you're still in the loop.
The OP still posts wibble.
Look, if it's harder than copy/paste/compile/test, people will lose interest rapidly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <chrono>
#include <ratio>
#include <thread>
using namespace std;

int runs = 1000;

int numSyncCalls = 0;
void ntpSync()
{
  numSyncCalls++;
  char ntp[] = "oojit";
  FILE *jitter;
  char line[100];
  int numLinesRead = 0;

  //system("chronyc sources|cat > offset.txt");
  jitter = fopen("offset.txt", "r");
  while ( fgets(line,sizeof(line),jitter) ) {
    ++numLinesRead;
    if ( strstr(line,ntp) ) {
      char *start = strpbrk(line,"+-");
      //myfile<<start;
    }
  }
  fclose(jitter);
}


void resync()
{
  //first lets make some objects to be used later
  //struct sysinfo memInfo;       //struct to check memory usage
  int iteration = 0;            //iteration counter
  uint64_t nextTimeSeconds;
  uint64_t nextTimeMicroSeconds;

  //Sleep until x minute to sync/run chassis simultaneously
  using std::chrono::system_clock;
  std::time_t tt = system_clock::to_time_t(system_clock::now());
  struct std::tm * ptm = std::localtime(&tt);
  std::cout << "Waiting for the next minute to begin...\n";
  ++ptm->tm_min;
  ptm->tm_sec = 0;
  std::this_thread::sleep_until(system_clock::from_time_t(mktime(ptm)));

  //do some arithemtic to ensure there are no nonzero decimals on our time object
  chrono::high_resolution_clock::time_point currTime = chrono::high_resolution_clock::now();
  chrono::high_resolution_clock::time_point nextTime;
  auto currTimeNanoDecimals = (chrono::duration_cast<chrono::nanoseconds > (currTime.time_since_epoch()).count()) -
                            ( (chrono::duration_cast<chrono::seconds> (currTime.time_since_epoch()).count()) * 1000000000); //find decimals for flooring

  currTime = currTime - chrono::nanoseconds(currTimeNanoDecimals);  //floor to second

  //main program loop
  for (int j = 0; j < (runs); j++)  //change this to change how many iterations the FPGA timestamp resyncs for
  {
    nextTime = currTime + chrono::seconds(1); //incrementing for next time
    nextTimeSeconds = chrono::duration_cast<chrono::seconds>(nextTime.time_since_epoch()).count();
    nextTimeMicroSeconds = nextTimeSeconds * 1000000;

    cout << "	Time cycle "
         << chrono::duration_cast<chrono::microseconds>(currTime.time_since_epoch()).count()
         << " to "
         << nextTimeMicroSeconds
         << "\n\n";

    //myfile << iteration << ",";
    //myfile << nextTimeSeconds << ","; //nextMicroSec
    //Add easy to read time here
    //writeTime();

    chrono::high_resolution_clock::time_point epochTime = chrono::high_resolution_clock::now();
    double epocTime = chrono::duration_cast<chrono::nanoseconds>(epochTime.time_since_epoch()).count();
    epocTime /= 1E9;

    //myfile << fixed << epocTime << ",";

    this_thread::sleep_until(currTime + chrono::nanoseconds(500000000));

    ntpSync();

    //change some values before next iteration
    currTime = nextTime;        //comment out if testing with one sec
    iteration++;
    this_thread::sleep_until(nextTime);

    cout << "Current time at end  :                            			 	"
        << chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count()
        << endl;
  }
}


// MAIN
int main(int argc, char *argv[])
{
  //init();

  //myfile << "iteration, Next Second, current time, current time (epoch), "
  //          "Offset between the local cloak and the source at last "
  //          "measurement [actual measure offset]"
  //       << "\n";
  resync();
  //close out the files
  //myfile.close();
  return 0;
}


> chrono::high_resolution_clock::time_point currTime = chrono::high_resolution_clock::now();
https://en.cppreference.com/w/cpp/chrono/high_resolution_clock

Notes

The high_resolution_clock is not implemented consistently across different standard library implementations, and its use should be avoided. It is often just an alias for std::chrono::steady_clock or std::chrono::system_clock, but which one it is depends on the library or configuration. When it is a system_clock, it is not monotonic (e.g., the time can go backwards). For example, for gcc's libstdc++ it is system_clock, for MSVC it is steady_clock, and for clang's libc++ it depends on configuration.

Generally one should just use std::chrono::steady_clock or std::chrono::system_clock directly instead of std::chrono::high_resolution_clock: use steady_clock for duration measurements, and system_clock for wall-clock time.


So yeah, since you're on Linux, you've got a system_clock (which is NOT monotonic).
If your code doesn't deal with negatives as dhayden surmises, I wouldn't be surprised if you don't end up waiting for a billion seconds at some point, instead of a billion nanoseconds.

Fix your clock.

It appears that @Dhayden and salem c were right and I need to eat my words. Somehow my clock randomly jumps a couple seconds and since it goes past the wait time, it freezes. I was confusing where it froze from the csv due to there being a lag time from the code executing and it actually appearing in the csv.

Thanks everyone!
Topic archived. No new replies allowed.
Pages: 12