15
15
// To view the GNU Lesser General Public License visit
16
16
// http://www.gnu.org/copyleft/lesser.html
17
17
// or write to the Free Software Foundation, Inc.,
18
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
21
21
#include "boinc_win.h"
106
99
::Sleep((int)(1000*seconds));
108
unsigned int rem = (int) seconds;
101
double end_time = dtime() + seconds - 0.01;
102
// sleep() and usleep() can be interrupted by SIGALRM,
103
// so we may need multiple calls
112
if (rem > seconds) break; // paranoia
107
sleep((unsigned int) seconds);
109
usleep((int)fmod(seconds*1000000, 1000000));
111
seconds = end_time - dtime();
112
if (seconds <= 0) break;
114
int x = (int)fmod(seconds*1000000, 1000000);
174
172
static void get_elapsed_time(double& cpu) {
175
static bool first = true;
176
static DWORD first_count = 0;
173
static double start_time;
179
first_count = GetTickCount();
175
double now = dtime();
177
cpu = now - start_time;
182
// TODO: Handle timer wraparound
183
DWORD cur = GetTickCount();
184
cpu = ((cur - first_count)/1000.);
187
184
int boinc_calling_thread_cpu_time(double& cpu) {
196
pthread_mutex_t getrusage_mutex = PTHREAD_MUTEX_INITIALIZER;
198
// Unix: pthreads doesn't seem to provide an API for getting
199
// per-thread CPU time. So just get the process's CPU time
193
// Unix: pthreads doesn't provide an API for getting per-thread CPU time,
194
// so just get the process's CPU time
201
196
int boinc_calling_thread_cpu_time(double &cpu_t) {
203
197
struct rusage ru;
205
// getrusage can return an error, so try a few times if it returns an error.
207
if (!pthread_mutex_trylock(&getrusage_mutex)) {
208
for (int i=0; i<10; i++) {
209
retval = getrusage(RUSAGE_SELF, &ru);
212
pthread_mutex_unlock(&getrusage_mutex);
215
return ERR_GETRUSAGE;
217
// Sum the user and system time
219
cpu_t = (double)ru.ru_utime.tv_sec + (((double)ru.ru_utime.tv_usec) / ((double)1000000.0));
220
cpu_t += (double)ru.ru_stime.tv_sec + (((double)ru.ru_stime.tv_usec) / ((double)1000000.0));
199
int retval = getrusage(RUSAGE_SELF, &ru);
200
if (retval) return ERR_GETRUSAGE;
201
cpu_t = (double)ru.ru_utime.tv_sec + ((double)ru.ru_utime.tv_usec) / 1e6;
202
cpu_t += (double)ru.ru_stime.tv_sec + ((double)ru.ru_stime.tv_usec) / 1e6;
290
int lookup_group(char* name, gid_t& gid) {
291
struct group* gp = getgrnam(name);
292
if (!gp) return ERR_GETGRNAM;
273
// (linux) return current CPU time of the given process
275
double linux_cpu_time(int pid) {
278
unsigned long utime = 0, stime = 0;
281
sprintf(file_name,"/proc/%d/stat",pid);
282
if ((file = fopen(file_name,"r")) != NULL) {
283
n = fscanf(file,"%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%lu%lu",&utime,&stime);
285
if (n != 2) return 0;
287
return (double)(utime + stime)/100;
300
// read file (at most max_len chars, if nonzero) into malloc'd buf
302
int read_file_malloc(const char* path, char*& buf, int max_len, bool tail) {
307
retval = file_size(path, size);
308
if (retval) return retval;
310
f = fopen(path, "r");
311
if (!f) return ERR_FOPEN;
314
if (max_len && size > max_len) {
316
fseek(f, (long)size-max_len, SEEK_SET);
322
buf = (char*)malloc(isize+1);
323
size_t n = fread(buf, 1, isize, f);
329
// read file (at most max_len chars, if nonzero) into string
331
int read_file_string(const char* path, string& result, int max_len, bool tail) {
336
retval = read_file_malloc(path, buf, max_len, tail);
337
if (retval) return retval;
298
343
// chdir into the given directory, and run a program there.
299
344
// If nsecs is nonzero, make sure it's still running after that many seconds.
301
346
// argv is set up Unix-style, i.e. argv[0] is the program name
305
351
const char* dir, const char* file, int argc, char *const argv[], double nsecs, HANDLE& id
308
354
PROCESS_INFORMATION process_info;
309
355
STARTUPINFO startup_info;
310
356
char cmdline[1024];
357
char error_msg[1024];
311
358
unsigned long status;
313
360
memset(&process_info, 0, sizeof(process_info));
314
361
memset(&startup_info, 0, sizeof(startup_info));
362
startup_info.cb = sizeof(startup_info);
316
364
strcpy(cmdline, "");
317
for (int i=1; i<argc; i++) {
365
for (int i=0; i<argc; i++) {
318
366
strcat(cmdline, argv[i]);
319
strcat(cmdline, " ");
368
strcat(cmdline, " ");
322
372
retval = CreateProcess(
328
CREATE_NEW_PROCESS_GROUP,
334
if (retval) return retval;
385
windows_error_string(error_msg, sizeof(error_msg));
386
fprintf(stderr, "CreateProcess failed: '%s'\n", error_msg);
387
return -1; // CreateProcess returns 1 if successful, false if it failed.
336
391
boinc_sleep(nsecs);
337
392
if (GetExitCodeProcess(process_info.hProcess, &status)) {
391
448
return (int) status;
450
bool process_exists(HANDLE h) {
451
unsigned long status=1;
452
if (GetExitCodeProcess(h, &status)) {
453
if (status == STILL_ACTIVE) return true;
394
459
int get_exit_status(int pid) {
396
461
waitpid(pid, &status, 0);
464
bool process_exists(int pid) {
465
int p = waitpid(pid, 0, WNOHANG);
466
if (p == pid) return false; // process has exited
467
if (p == -1) return false; // PID doesn't exist
437
508
return ERR_ALREADY_RUNNING;
442
// (linux) return current CPU time of the given process
444
double linux_cpu_time(int pid) {
447
unsigned long utime = 0, stime = 0;
450
sprintf(file_name,"/proc/%d/stat",pid);
451
if ((file = fopen(file_name,"r")) != NULL) {
452
n = fscanf(file,"%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%lu%lu",&utime,&stime);
454
if (n != 2) return 0;
456
return (double)(utime + stime)/100;
469
// read file (at most max_len chars, if nonzero) into malloc'd buf
471
int read_file_malloc(const char* path, char*& buf, int max_len, bool tail) {
476
retval = file_size(path, size);
477
if (retval) return retval;
479
f = fopen(path, "r");
480
if (!f) return ERR_FOPEN;
482
if (max_len && size > max_len) {
484
fseek(f, (long)size-max_len, SEEK_SET);
489
buf = (char*)malloc(isize+1);
490
size_t n = fread(buf, 1, isize, f);
496
// read file (at most max_len chars, if nonzero) into string
498
int read_file_string(const char* path, string& result, int max_len, bool tail) {
503
retval = read_file_malloc(path, buf, max_len, tail);
504
if (retval) return retval;
510
const char *BOINC_RCSID_ab65c90e1e = "$Id: util.C 13901 2007-10-18 08:56:44Z charlief $";
511
const char *BOINC_RCSID_ab65c90e1e = "$Id: util.C 15038 2008-04-10 16:42:09Z romw $";