Fixed enough bugs to allow the cpuTime module to properly create packets.
[aesalon.git] / modules / cpuTime / src / collector / cpuTime.c
blob34fc372e817c905459226667f2c023361922228d
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <dlfcn.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <sys/time.h>
7 #include <sys/times.h>
8 #include <sys/resource.h>
9 #include <sys/timerfd.h>
10 #include <pthread.h>
11 #include <string.h>
13 #ifndef TFD_CLOEXEC
14 #error "TFD_CLOEXEC must be defined; this is a Linux-specific feature available in 2.6.27 and later."
15 #endif
17 #include "informer/Informer.h"
19 static int isRunning = 0;
20 static int timerFd;
21 static pthread_t threadID;
22 static ModuleID moduleID;
24 static void *sendTime(void *unused) {
25 isRunning = 1;
26 AI_StopCollection(pthread_self());
27 while(isRunning) {
28 uint64_t exp;
29 read(timerFd, &exp, sizeof(exp));
30 uint8_t buffer[64];
32 /*if(AI_CollectionStatus() == 0) continue;*/
34 struct rusage ru;
35 getrusage(RUSAGE_SELF, &ru);
37 uint64_t value = (ru.ru_utime.tv_sec * 1000000000) + (ru.ru_utime.tv_usec * 1000);
39 printf("Starting packet . . .\n");
41 AI_StartPacket(moduleID);
43 printf("Packet started . . .\n");
45 void *packet = AI_PacketSpace(sizeof(value));
46 memcpy(packet, &value, sizeof(value));
48 printf("Ending packet . . .\n");
50 AI_EndPacket();
52 printf("Packet finished.\n");
54 return NULL;
57 void __attribute__((constructor)) AM_Construct() {
58 /* Just in case, construct the Informer. */
59 AI_Construct();
61 /* Retrieve the module ID# . . . */
62 moduleID = AI_ConfigurationLong("cpuTime:moduleID");
64 /* NOTE: TFD_CLOEXEC was introduced in Linux 2.6.27; timerfd_create() is Linux-specific. */
65 if((timerFd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC)) == -1) {
66 printf("Failed to create timer . . .\n");
67 return;
70 struct itimerspec its;
72 int interval = AI_ConfigurationLong("cpuTime:interval");
73 if(interval == -1) {
74 /* The default interval is 10 times per second, or every 100 ms. */
75 interval = 100000;
77 interval *= 1000;
79 printf("Interval in ns: %i\n", interval);
81 its.it_interval.tv_sec = interval / 1000000000;
82 its.it_interval.tv_nsec = interval % 1000000000;
84 its.it_value.tv_sec = interval / 1000000000;
85 its.it_value.tv_nsec = interval % 1000000000;
87 timerfd_settime(timerFd, 0, &its, NULL);
89 pthread_create(&threadID, NULL, sendTime, NULL);
91 int conductorFd = AI_ConfigurationLong("::conductorFd");
94 void __attribute__((destructor)) AM_Destruct() {
95 isRunning = 0;
96 pthread_join(threadID, NULL);