I am practicing with threads in C. My program have to constantly (periodically) poll free GPU memory (and other info), while being able to handle X events. The problem is when I am calling XNVCTRLQueryTargetAttribute, the program freezes and eat 100% of 1 core. Here is the code, simplified but buggy as well.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <X11/Xlib.h>
#include "NVCtrl/NVCtrl.h"
#include "NVCtrl/NVCtrlLib.h"
Display *display;
pthread_t t1, t2;
void *run(void *t)
{
XEvent e;
int total;
int gpu = 0;
if(t == &t1) {
while(1) {
XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu, 0,
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, &total);
fprintf(stderr, "total memory: %d\n", total);
sleep(1);
}
}
else {
XNextEvent(display, &e);
}
return NULL;
}
int main(int argc, char *argv[])
{
if(!(display = XOpenDisplay(NULL)))
return 1;
pthread_create(&t1, NULL, run, (void *) &t1);
pthread_create(&t2, NULL, run, (void *) &t2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
XCloseDisplay(display);
return EXIT_SUCCESS;
}
And command I use. In order to compile the program you need Nvidia graphics card and proprietary driver.
cc -lpthread -lX11 -L/usr/X11R6/lib -o foo foo.c /usr/lib/libXNVCtrl.so
When I comment out XNextEvent(display, &e); line or the one with XNVCTRLQueryTargetAttribute call, each second "total memory: 0" is printed to the terminal. Otherwise, there is nothing.
I just tested without threads and see no high cpu usage. Moved the following code to main.
XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu, 0,
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, &total);
fprintf(stderr, "total memory: %d\n", total);
XNextEvent(display, &e);
sleep(1);
Message "total memory: 1996" is printed, then XNextEvent blocks for eternity (because of no listeners). I suppose the problem is that I do not understand threads well, perhaps in combination with dynamic linking. I doubt it matter, but anyway, nvidia driver: 435.21-11.