Successfully implemented a cpuTime marshaller.
[aesalon.git] / modules / cpuTime / src / collector / cpuTime.c
blobbb996bdc6058753fa78e6597a10551d7159ec2f2
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>
12 #include <time.h>
14 #ifndef TFD_CLOEXEC
15 #error "TFD_CLOEXEC must be defined; this is a Linux-specific feature available in 2.6.27 and later."
16 #endif
18 #include "informer/Informer.h"
20 static int isRunning = 0;
21 static int timerFd;
22 static pthread_t threadID;
23 static ModuleID moduleID;
25 static void *sendTime(void *unused) {
26 isRunning = 1;
27 AI_StopCollection(pthread_self());
28 while(isRunning) {
29 uint64_t exp;
30 read(timerFd, &exp, sizeof(exp));
31 uint8_t buffer[64];
33 /*if(AI_CollectionStatus() == 0) continue;*/
35 /*struct rusage ru;
36 getrusage(RUSAGE_SELF, &ru);*/
38 int targetListSize;
39 pthread_t *targetThreads = AI_TargetThreadList(&targetListSize);
41 AI_StartPacket(moduleID);
42 void *packet = AI_PacketSpace(sizeof(uint64_t) * targetListSize);
44 int i;
45 for(i = 0; i < targetListSize; i ++) {
46 uint64_t *value = (uint64_t *)packet + i;
48 clockid_t clockID;
50 pthread_getcpuclockid(targetThreads[i], &clockID);
52 struct timespec tp;
53 clock_gettime(clockID, &tp);
54 *value = tp.tv_nsec + tp.tv_sec * 1000000000;
57 AI_EndPacket();
59 return NULL;
62 void __attribute__((constructor)) AM_Construct() {
63 /* Just in case, construct the Informer. */
64 AI_Construct();
66 /* Retrieve the module ID# . . . */
67 moduleID = AI_ConfigurationLong("cpuTime:moduleID");
69 /* NOTE: TFD_CLOEXEC was introduced in Linux 2.6.27; timerfd_create() is Linux-specific. */
70 if((timerFd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC)) == -1) {
71 printf("Failed to create timer . . .\n");
72 return;
75 struct itimerspec its;
77 int interval = AI_ConfigurationLong("cpuTime:interval");
78 if(interval == -1) {
79 /* The default interval is 10 times per second, or every 100 ms. */
80 interval = 100000;
82 interval *= 1000;
84 printf("Interval in ns: %i\n", interval);
86 its.it_interval.tv_sec = interval / 1000000000;
87 its.it_interval.tv_nsec = interval % 1000000000;
89 its.it_value.tv_sec = interval / 1000000000;
90 its.it_value.tv_nsec = interval % 1000000000;
92 timerfd_settime(timerFd, 0, &its, NULL);
94 pthread_create(&threadID, NULL, sendTime, NULL);
96 int conductorFd = AI_ConfigurationLong("::conductorFd");
99 void __attribute__((destructor)) AM_Destruct() {
100 isRunning = 0;
101 pthread_join(threadID, NULL);