pmm  1.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
pmm_loadmonitor.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008-2010 Robert Higgins
3  Author: Robert Higgins <robert.higgins@ucd.ie>
4 
5  This file is part of PMM.
6 
7  PMM is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  PMM is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with PMM. If not, see <http://www.gnu.org/licenses/>.
19 */
20 /*!
21  * @file pmm_loadmonitor.c
22  * @brief Code for monitoring the load on a machine
23  *
24  * Contains the load monitoring thread of pmm
25  */
26 #if HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 
31 #include <pthread.h> // for pthreads
32 #include <stdio.h> //for perror
33 #include <stdlib.h> // for getloadavg/exit
34 
35 #include "pmm_load.h"
36 #include "pmm_log.h"
37 #include "pmm_cfgparser.h"
38 
39 extern int signal_quit;
40 extern pthread_mutex_t signal_quit_mutex;
41 
42 /*!
43  * load monitor thread
44  *
45  * monitors and writes load to disk until a quit signal is detected
46  *
47  * @param loadhistory void pointer to the load history structue
48  *
49  * @return void pointer to integer describing return status, 0 for success
50  * -1 for failure
51  */
52 //TODO exit gracefully on failure
53 void*
54 loadmonitor(void *loadhistory)
55 {
56  struct pmm_loadhistory *h;
57  struct pmm_load l;
58  int rc;
59 
60  int sleep_for = 60; //number of seconds we wish to sleep for
61  int sleep_for_counter = 0; //counter for how long we have slept
62  int sleep_for_fraction = 5; //sleep in 5 second fractions
63 
64  int write_period = 10*60; //write the history to disk every 10 minutes
65  int write_period_counter=0; //counter for writing history to disk
66 
67  h = (struct pmm_loadhistory*)loadhistory;
68 
69  LOGPRINTF("[loadmonitor]: h:%p\n", h);
70 
71  // read load history file
72  //if loadfile exists ...
73  //
74 
75  for(;;) {
76 
77  if((l.time = time(NULL)) == (time_t)-1) {
78  ERRPRINTF("Error retreiving unix time.\n");
79  exit(EXIT_FAILURE);
80  }
81 
82  if(getloadavg(l.load, 3) != 3) {
83  ERRPRINTF("Error retreiving load averages from getloadavg.\n");
84  exit(EXIT_FAILURE);
85  }
86 
87 
88  // lock the rwlock for writing
89  if((rc = pthread_rwlock_wrlock(&(h->history_rwlock))) != 0) {
90  ERRPRINTF("Error aquiring write lock:%d\n", rc);
91  exit(EXIT_FAILURE);
92  }
93 
94  //add load to load history data structure
95  add_load(h, &l);
96 
97  // unlock the rwlock
98  rc = pthread_rwlock_unlock(&(h->history_rwlock));
99 
100  //sleep for a total of "sleep_for" seconds, in sleep_for_fraction
101  //segments ...
102  sleep_for_counter = 0;
103  while(sleep_for_counter<=sleep_for) {
104 
105  //check we have not received the quit signal
106  pthread_mutex_lock(&signal_quit_mutex);
107  if(signal_quit) {
108  pthread_mutex_unlock(&signal_quit_mutex);
109 
110  // write load history to file using xml ...
111  LOGPRINTF("signal_quit set, writing history file ...\n");
112  if(write_loadhistory(h) < 0) {
113  perror("[loadmonitor]"); //TODO
114  ERRPRINTF("Error writing history.\n");
115  exit(EXIT_FAILURE);
116  }
117 
118  return (void*)0;
119  }
120  pthread_mutex_unlock(&signal_quit_mutex);
121 
122  //sleep for fraction and add to
123  sleep(sleep_for_fraction);
124 
125  sleep_for_counter += sleep_for_fraction;
126  }
127 
128  write_period_counter += sleep_for;
129 
130  //write history when write_period seconds have elapsed since last write
131  if(write_period_counter == write_period) {
132 
133  // write load history to file using xml ...
134  LOGPRINTF("writing history to file ...\n");
135  if(write_loadhistory(h) < 0) {
136  perror("[loadmonitor]");
137  ERRPRINTF("Error writing history.\n");
138  exit(EXIT_FAILURE);
139  }
140 
141  write_period_counter = 0;
142  }
143 
144  }
145 }
146