I have a couple of questions on this piece of code, running on a jetson nano:
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
float gputemp = 0;
float cputemp = 0;
int count = 0;
int main() {
char* cpu;
char* gpu;
cpu = (char*)malloc(sizeof(char)*6);
gpu = (char*)malloc(sizeof(char)*6);
while (1) {
FILE* fcputemp = fopen("/sys/devices/virtual/thermal/thermal_zone1/temp", "r");
FILE* fgputemp = fopen("/sys/devices/virtual/thermal/thermal_zone2/temp","r");
if (!fcputemp || !fgputemp ) {
printf("Something went wrong\n");
exit(EXIT_FAILURE);
}
cputemp = atoi(fgets(cpu, 6, fcputemp))/1000;
gputemp = atoi(fgets(gpu, 6, fgputemp))/1000;
printf("\rCpu : %.2f, Gpu : %.2f. Elapsed time : %d", cputemp, gputemp, count);
fflush(stdout);
fclose(fcputemp);
fclose(fgputemp);
count++;
sleep(1);
}
}
Here I have to open, get the temperatures, and then close the file each loop iteration in order to get valid data (and dont segfault).
My concern here is the number of (expensive) kernel switches needed to do this.
I know that premature optimization is evil, but there is another way (or maybe the RIGHT way) to do that, opening the file only once?
And why the sensor interface (the file) cant update itself if I have it open?
P.S: Yes, I know, I didnt free cpu nor gpu variables, this is only "demo" code (just watch how i measure the time passed lol)
I'm not sure you can do this opening the files once and once only. You could try rewinding, but sysfs isn't a "real" filesystem and those aren't real files. If you rewind you might get the same data over and over, especially when using buffered calls like fopen().
The open operation is what prepares that data for reading. Since this is all managed by the kernel it should have very little overhead, and no actual disk activity. Consider that programs like top read thousands of these every second and it's no big deal.
I using g++ on linux with eclipse. I am making a code that get file's time and output file's month,hour,etc...
While debugging, the value of time1 changed unexpectedly but I have no idea about this issue.
What is problem of this code?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
struct stat stat1, stat2;
struct tm *time1, *time2;
void filestat1(void);
void filestat2(void);
void filetime1(void);
void filetime2(void);
void datecmp(void);
void timecmp(void);
int main(void)
{
filestat1();
filestat2();
filetime1();
filetime2();
datecmp();
timecmp();
}
void filestat1(void)
{
// check if there is no text1
int check = 0;
check = stat("text1", &stat1);
if(check != 0)
{
printf("Error : there is no text1\n");
}
return;
}
void filestat2(void)
{
// check if there is no text2
int check = 0;
check = stat("text2", &stat2);
if(check != 0)
{
printf("Error : there is no text2\n");
}
return;
}
void filetime1(void)
{
time1 = localtime(&stat1.st_mtime); //!!! this change unexpectedly
return;
}
void filetime2(void)
{
time2 = localtime(&stat2.st_mtime);
return;
}
void datecmp(void)
{
printf("date compare\n");
// compare tm_mon
if(time1->tm_mon > time2->tm_mon)
printf("time1 is early \n");
else if(time1->tm_mon < time2->tm_mon)
printf("time2 is early \n");
else{
// compare tm_mday
if(time1->tm_mday > time2->tm_mday)
printf("time1 is early \n");
else if(time1->tm_mday < time2->tm_mday)
printf("time2 is early \n");
// same date
else
printf("same time \n");
}
printf("\n");
}
void timecmp(void)
{
printf(time1->tm_hour);
printf(time2->tm_hour);
printf("time compare\n");
// compare hour
if(time1->tm_hour > time2->tm_hour)
printf("time1 is early \n");
else if(time1->tm_hour < time2->tm_hour)
printf("time2 is early \n");
else{
// compare minutes
if(time1->tm_min > time2->tm_min)
printf("time1 is early \n");
else if(time1->tm_min < time2->tm_min)
printf("time2 is early \n");
// same time
else
printf("same time \n");
}
}
localtime returns a pointer to a static structure. You need to copy the result before calling localtime again.
I would declare time1 and time2 as structures instead of pointers to store the values.
struct tm time1, time2;
void filetime1(void)
{
struct tm *tmp = localtime(&stat1.st_mtime);
if (tmp == NULL) {
//... handle error
}
time1 = *tmp;
}
Similarly for filetime2.
If you are writing multi-threaded code, it is safer to use the reentrant variant of the function, localtime_r. In that case, you pass in the pointer to the structure for the result.
void filetime1(void)
{
struct tm *tmp = localtime_r(&stat1.st_mtime, &time1);
if (tmp == NULL) {
//... handle error
} else {
assert(tmp == &time1);
}
}
You are using global variables, completely unnecessarily, making your life harder than it has to be. It is very hard for us humans to track where global variables are modified, especially when you have several global variables with very similar names.
So, instead of trying to unravel all that, let's rewrite it using function parameters, without any global variables at all.
First, we tell the C library we want POSIX.1-2008 features, and include the headers that expose the functionality we need:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
Next, let's define a function that takes a file name as a parameter, and pointers to where the function can store the last access and last modification timestamps. If the function is successful, it'll return 0; otherwise, it'll return -1 with errno set to indicate the error.
int filetime(const char *path,
time_t *accessed, long *accessed_nsec,
time_t *modified, long *modified_nsec)
{
struct stat info;
/* Path must not be NULL or empty. */
if (!path || !path[0]) {
errno = EINVAL;
return -1;
}
/* Get file statistics. */
if (stat(path, &info) == -1)
return -1; /* errno was set by stat() */
/* Save timestamps. */
if (accessed)
*accessed = info.st_atim.tv_sec;
if (accessed_nsec)
*accessed_nsec = info.st_atim.tv_nsec;
if (modified)
*modified = info.st_mtim.tv_sec;
if (modified_nsec)
*modified_nsec = info.st_mtim.tv_nsec;
/* Success. */
return 0;
}
Let's continue by writing a simple main(), that takes one or more file names as command-line parameters, and describes them. I like to start the main by checking the number of command line arguments, and if specified, the first argument. If none, or the first one is -h or --help, I like to print the usage of the utility. This way, I can keep my example programs in their own directories, and to find one I'm looking for, I can just execute each one without parameters, to see what each of them does. It's much faster than reading the sources!
int main(int argc, char *argv[])
{
int arg;
if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s FILENAME ...\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "This program will print the last access and\n");
fprintf(stderr, "last modification timestamps for each of\n");
fprintf(stderr, "the specified files.\n");
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
Because there is at least one, but possibly more than one file name parameter, we handle each of them in a loop:
for (arg = 1; arg < argc; arg++) {
time_t accessed, modified;
long accessed_ns, modified_ns;
struct tm accessed_localtime, modified_localtime;
Within the loop, we first call our filetime() function. Note how we have declared the variables we want filled above, and how we call the function: &accessed yields a pointer to accessed.
if (filetime(argv[arg], &accessed, &accessed_ns,
&modified, &modified_ns)) {
/* Nonzero return value, so an error occurred! */
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return EXIT_FAILURE;
}
In C, function parameters are passed by value, not by reference. This means that if a function parameter is say int foo, any changes to foo within the function are visible within the function only; the changes are not visible to the caller. When we pass a pointer to a variable, say int *foo, then changes to foo are still visible only within the function, but *foo refers to the value pointed at by the pointer; and changes to that are visible to the caller.
In short, when we want a function to be able to modify the value of a variable, we use a pointer. That's just how C works.
Now that we have the times in Unix Epoch time (time_t), we want to split them into local time fields:
if (!localtime_r(&accessed, &accessed_localtime) ||
!localtime_r(&modified, &modified_localtime)) {
fprintf(stderr, "%s: Cannot compute timestamps in local time: %s.\n", argv[arg], strerror(errno));
return EXIT_FAILURE;
}
Note that I again used a POSIX.1-2008 function, localtime_r(). In tutorials, you often see the older localtime() used instead, but that one may use a global variable internally (it can always return a pointer to the same structure, reusing it for every call); localtime_r() is better.
See how the second parameter to localtime_r is also a pointer (to a struct tm)? Again, this is just how you do functions that change some values in a way that is visible to the caller.
Also, it is rare for localtime_r() (or localtime()) to fail, so many simply ignore checking it for errors. There is no excuse for that, as it's just a couple of lines more code, and if an error does occur at some point, the user will be immensely more satisfied with a clear error code, rather than just seeing the program crash due to segmentation fault.
All that is left, is to print out the information gathered. I like to use a variant the ISO 8601 international standard for the time format; in particular, it sorts in proper time order even if sorted alphabetically. (My variant is that I like to use a space, and not a T, between the date and the time.)
printf("%s:\n", argv[arg]); /* The file name or path */
printf(" Modified: %04d-%02d-%02d %02d:%02d:%02d.%03d\n",
modified_localtime.tm_year + 1900,
modified_localtime.tm_mon + 1,
modified_localtime.tm_mday,
modified_localtime.tm_hour,
modified_localtime.tm_min,
modified_localtime.tm_sec,
modified_ns / 1000000L);
printf(" Accessed: %04d-%02d-%02d %02d:%02d:%02d.%03d\n",
accessed_localtime.tm_year + 1900,
accessed_localtime.tm_mon + 1,
accessed_localtime.tm_mday,
accessed_localtime.tm_hour,
accessed_localtime.tm_min,
accessed_localtime.tm_sec,
accessed_ns / 1000000L);
/* Make sure everything written to stdout
is actually written to standard output right now. */
fflush(stdout);
}
return EXIT_SUCCESS;
}
The fflush(stdout) tells the C library to ensure all preceding writes to stdout are actually written to the standard output. (By default, stdout is buffered, and stderr is unbuffered.) Normally, the C library will flush the output at every newline, but having the explicit flush there also reminds us human programmers that we want everything thus far printed, to actually appear on the programs standard output at that point. (This way, if one of the files is on some slow filesystem, say old USB stick or a network share, the information on previous files gets shown before the program accesses the slow file. Essentially, the "stall" will occur at the expected place for the human users.)
It is probably a good idea to mention relatime and other related mount options at this point. In simple terms, it means that to avoid the number of writes to storage media due to read accesses, the access time is not always updated. So, if you don't see it changing even after you read a file (using e.g. cat FILENAME >/dev/null), it just means your system has mount options enabled that reduce the access time updates to speed up your filesystem access and reduce the number of writes to it. It is a good option; I use it.
Finally, most Linux filesystems do not have a created timestamp at all. The st_ctime (and st_ctim.tv_sec and st_ctim.tv_nsec) fields refer to last status change timestamp. It tracks changes to the owner, group, permissions, and the number of hard links.
When you examine the above code, especially the if clauses, it is useful to remember that in C, the logical OR operation, ||, is short-circuiting: the left side is evaluated first, but if it fails, the right side is not evaluated at all. So, if you have e.g. int x = 1, y = 0; and you do (x == 0 || ++y), y will not be incremented at all. I utilize this when examining argv[1] in the very first if clause in main().
I've been trying to time how long it takes for an invocation of popen to complete. popen initializes a process which then creates a pipe, forks, and invokes the shell. In my particular case, I'm using the call to read another programs stdout output.
The problem: I'm expecting the call I make to return the correct length of time it took the program to execute (around 15 seconds for a test program). What I get is that the program took no time at all to finish (0.000223s). Despite all the various functions I have tried, I seem unable to time the call correctly.
Here is a reproducible example of my problem. It is composed of the timing program and a child program that the timing program runs (the child takes about 15s to run on my system):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#define MAXBUF 10
static void gettime (struct timespec *t) {
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
t->tv_sec = mts.tv_sec;
t->tv_nsec = mts.tv_nsec;
#else
clock_gettime(CLOCK_REALTIME, t);
#endif
}
int main (void) {
FILE *fp;
struct timespec tic, toc;
char *executableName = "./a.out";
char answer[MAXBUF];
gettime(&tic);
if ((fp = popen(executableName, "r")) == NULL) {
fprintf(stderr, "The file couldn't be opened.\n");
return 1;
}
gettime(&toc);
fgets(answer, MAXBUF, fp);
double elapsed = (double)(toc.tv_nsec - tic.tv_nsec) / 1E9;
fprintf(stdout, "The program says %s, and took %fs to run!\n", answer, elapsed);
pclose(fp);
return 0;
}
Here is the child program:
#include <stdio.h>
#include <stdlib.h>
int timeWastingFunction (long long n) {
if ((n % 2) == 0) {
return 1;
}
for (int i = 1; i < (n / 2); i += 2) {
if ((n % i) == 0) {
return 1;
}
}
return 0;
}
int main (void) {
int start = 687217000;
while (start--) {
timeWastingFunction(start);
}
fprintf(stdout, "Hello!");
return 0;
}
This might look a bit overdone, but I had previously tried using clock_t, (a CPU based timing facility) to do the timing, and gotten the same answers from it. I therefore tried this solution which you see above. I picked: CLOCK_REALTIME as it seemed appropriate for the job. I unfortunately don't have the option to specify if this clock is on a per-process or per-thread level though (I'd want it to be process independent).
Note: I haven't tried using gettimeofday yet, but I don't want to since its apparently inappropriate for timing this way, dependent on the date of the system using it, and being phased out in favor of clock_gettime.
Edit: Just to be clear, what happens when I run this is that the program calling popen will actually stall for the 15 seconds the other program takes to run, before printing the 'wrong' time. It doesn't immediately print the time implying it didn't wait for the call to complete.
popen() only fork and open a pipe. Your test only show the time that take popen() to create the child and the pipe.
A simple way to solve your problem is to get the time after your pclose(), note that will be not perfect because when you read the data return by your child, it could finish before your call to pclose()
Plus your solution to get the result is broken, you only make the difference between nanosecond, I found a solution on git:
void timespec_diff(struct timespec *start, struct timespec *stop,
struct timespec *result)
{
if ((stop->tv_nsec - start->tv_nsec) < 0) {
result->tv_sec = stop->tv_sec - start->tv_sec - 1;
result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000;
} else {
result->tv_sec = stop->tv_sec - start->tv_sec;
result->tv_nsec = stop->tv_nsec - start->tv_nsec;
}
return;
}
The last thing is that CLOCK_REALTIME should be used if you want the date. Here you just want a duration. So you should use CLOCK_MONOTONIC if it's available on your system because CLOCK_REALTIME can rollback. (REALTIME_CLOCK of host_get_clock_service() seam monotonic too).
CLOCK_MONOTONIC: Clock that cannot be set and represents monotonic time since some unspecified starting point.
REALTIME_CLOCK: A moderate resolution clock service that (typically) tracks time since the system last boot.
So the working code could look like that:
int main (void) {
FILE *fp;
struct timespec tic, toc;
char *executableName = "./a.out";
char answer[MAXBUF];
gettime(&tic);
if ((fp = popen(executableName, "r")) == NULL) {
fprintf(stderr, "The file couldn't be opened.\n");
return 1;
}
fgets(answer, MAXBUF, fp);
pclose(fp);
gettime(&toc);
struct timespec result;
timespec_diff(&tic, &toc, &result);
fprintf(stdout, "The program says %s, and took %lld.%.9lds\n", answer, (long long)result.tv_sec, result.tv_nsec);
return 0;
}
Credit:
How to subtract two struct timespec?
How to print struct timespec?
I have a C application whose one of the jobs is to call an executable file. That file has performance measurement routines inserted during compilation, at the level of intermediate code. It can measure time or L1/L2/L3 cache misses. In other words, I have modified the LLVM compiler to insert a call to that function and print the result to stdout for any compiled program.
Now, like I mentioned at the beginning, I would like to execute the program (with this result returned to stdout) from a separate C application and save that result. The way I'm doing it right now is:
void executeProgram(const char* filename, char* time) {
printf("Executing selected program %s...\n", filename);
char filePath[100] = "/home/michal/thesis/Drafts/output/";
strcat(filePath, filename);
FILE *fp;
fp = popen(filePath, "r");
char str[30];
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(str, sizeof(str) - 1, fp) != NULL) {
strcat(time, str);
}
pclose(fp);
}
where filename is the name of the compiled executable to run. The result is saved to time string.
The problem is, that the results I'm getting are pretty different and unstable compared to those that are returned by simply running the executable 'by hand' from the command line (./test16). They look like:
231425
229958
230450
228534
230033
230566
231059
232016
230733
236017
213179
90515
229775
213351
229316
231642
230875
So they're mostly around 230000 us, with some occasional drops. The same executable, run from within the other application, produces:
97097
88706
91418
97970
97972
94597
95846
95139
91070
95918
107006
89988
90882
91986
90997
88824
129136
94976
102191
94400
95215
95061
92115
96319
114091
95230
114500
95533
102294
108473
105730
Note that it is the same executable that's being called. Yet the measured time it returns is different. The program that is being measured consists of a function call to a simple nested loop, accessing array elements. Here is the code:
#include "test.h"
#include <stdio.h>
float data[1000][1000] = {0};
void test(void)
{
int i0, i1;
int N = 80;
float mean[1000];
for (i0 = 0; i0 < N; i0++)
{
mean[i0] = 0.0;
for (i1 = 0; i1 < N; i1++) {
mean[i0] += data[i0][i1];
}
mean[i0] /= 1000;
}
}
I'm suspecting that there is something wrong in the way the program is invoked in the code, maybe the process should be forked or something? Any ideas?
You didnt specify where exactly your time measuring subroutines are inserted, so all I can really offer is guesswork.
The results seem to hint to the exact opposite - running the application from shell is slower, so I wouldn't worry about the way you're starting the process from the C code. My guess would be - when you run your program from shell, it's the terminal that's slowing you down. When you're running the process from your C code, you pipe the output back to your 'starter' application, which is already waiting for input on the pipe.
As a side note, consider switching from strcat to something safer, like strncat.
I'm working on a C program (Ubuntu 14.04) that does basically:
Opens a 1GB file
Reads it by buffer of 1MB
Looks for some objects in the buffer
Computes the MD5 signature of each object found
My program take 10 secondes the first time to achieve this, and then only 1 seconde the next times (even if I work on a second copy of initial file).
I know that this has something to do with caching, does my program work on cached data after the first time ? or directly show cached results without doing any computation ?
int main(int argc, char** argv) {
unsigned char buffer[BUFFER_SIZE];
int i, number, count = 0;
int start, end = 0;
FILE *file;
file = fopen("/dump/ram.lime", "r");
if (file != NULL) {
while ((number = fread(buffer, 1, BUFFER_SIZE, file)) > 0) {
for (i = 0; i < number; i++) {
find_object(buffer, &start, &end);
md5_compute(&buffer[start], end - start);
}
}
} else {
printf("errno %d \n", errno);
}
printf("count = %d \n", count);
return (EXIT_SUCCESS);
}
Because the second time, most of your program code and most of the file data are already sitting in the page cache (and the kernel won't need any disk I/O to get them into RAM)
You'll likely to observe similar speedup if you run any other program (like cat or wc) on that big file which reads it sequentially before running your own code.
See also posix_fadvise(2), sync(2) & the Linux specific readahead(2) & http://www.linuxatemyram.com/ ; use the free(1) command before, during, and after running your program to measure memory. Read also about proc(5), since /proc/ contains a lot of useful pseudo-files describing the kernel state of your machine or your process.
Use also time(1), perhaps as /usr/bin/time -v, to benchmark several times your program. See also time(7) & getrusage(2) ...