// Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu // Copyright (C) 2005 University of California // // This is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // To view the GNU Lesser General Public License visit // http://www.gnu.org/copyleft/lesser.html // or write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_) #include "boinc_win.h" #endif #ifdef _WIN32 #include "win_util.h" #endif #ifndef M_LN2 #define M_LN2 0.693147180559945309417 #endif #ifndef _WIN32 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #include "error_numbers.h" #include "common_defs.h" #include "filesys.h" #include "util.h" #ifdef _USING_FCGI_ #include "fcgi_stdio.h" #endif using std::min; using std::string; using std::vector; int g_use_sandbox = 0; #define EPOCHFILETIME_SEC (11644473600.) #define TEN_MILLION 10000000. // return time of day (seconds since 1970) as a double // double dtime() { #ifdef _WIN32 LARGE_INTEGER time; FILETIME sysTime; double t; GetSystemTimeAsFileTime(&sysTime); time.LowPart = sysTime.dwLowDateTime; time.HighPart = sysTime.dwHighDateTime; // Time is in 100 ns units t = (double)time.QuadPart; // Convert to 1 s units t /= TEN_MILLION; /* In seconds */ t -= EPOCHFILETIME_SEC; /* Offset to the Epoch time */ return t; #else struct timeval tv; gettimeofday(&tv, 0); return tv.tv_sec + (tv.tv_usec/1.e6); #endif } // return time today 0:00 in seconds since 1970 as a double // double dday() { const double seconds_per_day=24*60*60; const double now=dtime(); return (now-fmod(now,seconds_per_day)); } // sleep for a specified number of seconds // void boinc_sleep(double seconds) { #ifdef _WIN32 ::Sleep((int)(1000*seconds)); #else unsigned int rem = (int) seconds; while (1) { rem = sleep(rem); if (rem == 0) break; if (rem > seconds) break; // paranoia } int x = (int)fmod(seconds*1000000,1000000); if (x) usleep(x); #endif } void push_unique(string s, vector& v) { for (unsigned int i=0; i0, // using the first-order Taylor expansion of // exp(x)=1+x+O(x^2). // So to the lowest order in diff: // weight = 1 - diff ln(2) / half_life // so one has // avg += (1-weight)*(work/diff_days) // avg += [diff*ln(2)/half_life] * (work*SECONDS_PER_DAY/diff) // notice that diff cancels out, leaving // avg += [ln(2)/half_life] * work*SECONDS_PER_DAY double diff, diff_days, weight; diff = now - avg_time; if (diff<0) diff=0; diff_days = diff/SECONDS_PER_DAY; weight = exp(-diff*M_LN2/half_life); avg *= weight; if ((1.0-weight) > 1.e-6) { avg += (1-weight)*(work/diff_days); } else { avg += M_LN2*work*SECONDS_PER_DAY/half_life; } } else if (work) { // If first time, average is just work/duration // double dd = (now - work_start_time)/SECONDS_PER_DAY; avg = work/dd; } avg_time = now; } #ifndef _WIN32 int lookup_group(char* name, gid_t& gid) { struct group* gp = getgrnam(name); if (!gp) return ERR_GETGRNAM; gid = gp->gr_gid; return 0; } #endif // chdir into the given directory, and run a program there. // If nsecs is nonzero, make sure it's still running after that many seconds. // // argv is set up Unix-style, i.e. argv[0] is the program name // #ifdef _WIN32 int run_program( char* dir, char* file, int argc, char** argv, double nsecs, HANDLE& id ) { int retval; PROCESS_INFORMATION process_info; STARTUPINFO startup_info; char cmdline[1024], path[1024]; unsigned long status; memset(&process_info, 0, sizeof(process_info)); memset(&startup_info, 0, sizeof(startup_info)); strcpy(cmdline, ""); for (int i=1; i timeout) break; } return ERR_ALREADY_RUNNING; } #ifndef _WIN32 // (linux) return current CPU time of the given process // double linux_cpu_time(int pid) { FILE *file; char file_name[24]; unsigned long utime = 0, stime = 0; int n; sprintf(file_name,"/proc/%d/stat",pid); if ((file = fopen(file_name,"r")) != NULL) { n = fscanf(file,"%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%lu%lu",&utime,&stime); fclose(file); if (n != 2) return 0; } return (double)(utime + stime)/100; } #endif const char *BOINC_RCSID_ab65c90e1e = "$Id$";