*** empty log message ***

svn path=/trunk/boinc/; revision=11207
This commit is contained in:
Charlie Fenton 2006-09-28 01:30:58 +00:00
parent 2dcdde06a0
commit 6b26086f7c
4 changed files with 159 additions and 24 deletions

View File

@ -10507,3 +10507,16 @@ Kevin 27 Sept 2006
clientgui/
sg_BoincSimpleGUI.cpp
sg_ProgressBar.cpp/h
Charlie 27 Sept 2006
- Mac: Use full-duplex pipes s AppStats helper application can stay open
for better efficiency.
- Mac: Update host_info.m_swap on each PROCINFO update.
- Comment out bogus memory usage exceeded message if mem_usage_debug log
flag is set.
client/
app_control.C
app_stats_mac.C
lib/
procinfo_mac.C

View File

@ -469,6 +469,7 @@ bool ACTIVE_TASK::check_max_disk_exceeded() {
bool ACTIVE_TASK::check_max_mem_exceeded() {
if (max_mem_usage != 0 && procinfo.working_set_size > max_mem_usage) {
#if 0
if (log_flags.mem_usage_debug) {
msg_printf(
result->project, MSG_INFO,
@ -477,6 +478,7 @@ bool ACTIVE_TASK::check_max_mem_exceeded() {
);
}
//abort_task(ERR_RSC_LIMIT_EXCEEDED, "Maximum memory usage exceeded");
#endif
}
return false;
}

View File

@ -81,12 +81,14 @@
using std::vector;
static int get_boinc_proc_info(int my_pid, int boinc_pid);
static int build_proc_list (vector<PROCINFO>& pi, int boinc_pid);
static void output_child_totals(PROCINFO& pinfo);
static boolean_t appstats_task_update(task_t a_task, vector<PROCINFO>& piv);
static void find_all_descendants(vector<PROCINFO>& piv, int pid, int rlvl);
static void add_child_totals(PROCINFO& pi, vector<PROCINFO>& piv, int pid, int rlvl);
//static void add_others(PROCINFO&, std::vector<PROCINFO>&);
static void sig_pipe(int signo);
#ifdef _DEBUG
static void print_procinfo(PROCINFO& pinfo);
@ -102,9 +104,7 @@ static void vm_size_render(unsigned long long a_size);
int main(int argc, char** argv) {
int boinc_pid, my_pid;
int retval;
vector<PROCINFO> piv;
PROCINFO child_total;
unsigned int i;
char buf[256];
if (geteuid() != 0) // This must be run setuid root
return EACCES;
@ -114,7 +114,35 @@ int main(int argc, char** argv) {
if (argc == 2)
boinc_pid = atoi(argv[1]); // Pass in any desired valid pid for testing
if (signal(SIGPIPE, sig_pipe) == SIG_ERR) {
fprintf(stderr, "signal error");
return 0;
}
setbuf(stdin, 0);
setbuf(stdout, 0);
while (1) {
if (fgets(buf, sizeof(buf), stdin) == NULL)
return 0;
if (feof(stdin))
return 0;
retval = get_boinc_proc_info(my_pid, boinc_pid);
}
return 0;
}
static int get_boinc_proc_info(int my_pid, int boinc_pid) {
int retval;
vector<PROCINFO> piv;
PROCINFO child_total;
unsigned int i;
retval = build_proc_list(piv, boinc_pid);
if (retval)
return retval;
@ -140,14 +168,14 @@ int main(int argc, char** argv) {
}
}
memset(&child_total, 0, sizeof(child_total));
#if 0
#ifdef _DEBUG
printf("\n\nSumming info for all other processes\n");
#endif
memset(&child_total, 0, sizeof(child_total));
add_others(child_total, piv);
output_child_totals(child_total);
#endif
output_child_totals(child_total); // zero pid signals end of data
return 0;
}
@ -157,6 +185,7 @@ static void output_child_totals(PROCINFO& pinfo) {
printf("%d %d %.0lf %.0lf %lu %lf %lf\n",
pinfo.id, pinfo.parentid, pinfo.working_set_size, pinfo.swap_size,
pinfo.page_fault_count, pinfo.user_time, pinfo.kernel_time);
// fflush(stdout);
}
static int build_proc_list (vector<PROCINFO>& pi, int boinc_pid) {
@ -564,6 +593,11 @@ static void add_others(PROCINFO& pi, vector<PROCINFO>& piv) {
}
#endif
static void sig_pipe(int signo)
{
exit(1);
}
#ifdef _DEBUG
static void print_procinfo(PROCINFO& pinfo) {
unsigned long long rsize, vsize;

View File

@ -20,12 +20,22 @@
// procinfo_mac.C
//
#define SHOW_TIMING 0
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include <cerrno>
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/mount.h>
#if SHOW_TIMING
#include <Carbon/Carbon.h>
#endif
#include "procinfo.h"
#include "client_msgs.h"
@ -57,25 +67,54 @@ using std::vector;
// This code doesn't use PROCINFO.is_boinc_app, but we set it to be consistent
// with the code for other platforms.
static int bidirectional_popen(char *path, int *fd);
int procinfo_setup(vector<PROCINFO>& pi) {
char appstats_path[100];
FILE* fd;
static int fd[2] = {0, 0};
PROCINFO p;
int c;
unsigned int i;
double m_swap;
int c, result, retry = 0;
char buf[256];
struct statfs fs_info;
#if SHOW_TIMING
UnsignedWide start, end, elapsed;
sprintf(appstats_path, "%s/%s", SWITCHER_DIR, APP_STATS_FILE_NAME);
fd = popen(appstats_path, "r");
if (!fd) return 0;
start = UpTime();
#endif
if (fd[0] == 0) {
// Launch AppStats helper application with a bidirectional pipe
RELAUNCH:
sprintf(appstats_path, "%s/%s", SWITCHER_DIR, APP_STATS_FILE_NAME);
result = bidirectional_popen(appstats_path, fd);
#if SHOW_TIMING
msg_printf(NULL, MSG_ERROR, "bidirectional_popen returned %d\n", result);
#endif
if (result) return 0;
retry = 0; // Reset retry counter on success
}
while (1) {
c = write(fd[0], "\n", 1); // Request a set of process info from AppStats helper application
if (c < 0) // AppStats application quit
if (++retry == 1)
goto RELAUNCH;
memset(&p, 0, sizeof(p));
c = fscanf(fd, "%d %d %lf %lf %lu %lf %lf\n",
for (unsigned int i=0; i<sizeof(buf); i++) {
c = read(fd[0], buf+i, 1);
if (c < 0) // AppStats application quit
if (++retry == 1)
goto RELAUNCH;
if (buf[i] == '\n')
break;
}
c = sscanf(buf, "%d %d %lf %lf %lu %lf %lf\n",
&p.id, &p.parentid, &p.working_set_size, &p.swap_size,
&p.page_fault_count, &p.user_time, &p.kernel_time);
if (c < 7) break;
if (p.id == 0)
break;
p.is_boinc_app = false;
pi.push_back(p);
@ -87,18 +126,16 @@ int procinfo_setup(vector<PROCINFO>& pi) {
p.page_fault_count, p.user_time, p.kernel_time
);
}
statfs(".", &fs_info);
gstate.host_info.m_swap = (double)fs_info.f_bsize * (double)fs_info.f_bfree;
}
pclose(fd);
// The sysctl(vm.vmmeter) function doesn't work on OS X, so hostinfo_unix.C
// function HOST_INFO::get_host_info() can't get the total swap space.
// It is easily calculated here, so fill in the value of host_info.m_swap.
m_swap = 0;
for (i=0; i<pi.size(); i++) {
m_swap += pi[i].swap_size;
}
gstate.host_info.m_swap = m_swap;
#if SHOW_TIMING
end = UpTime();
elapsed = AbsoluteToNanoseconds(SubAbsoluteFromAbsolute(end, start));
msg_printf(NULL, MSG_ERROR, "elapsed time = %llu, m_swap = %lf\n", elapsed, gstate.host_info.m_swap);
#endif
return 0;
}
@ -121,9 +158,58 @@ void procinfo_app(PROCINFO& pi, vector<PROCINFO>& piv) {
}
}
#if 0
// the following is not useful because most OSs don't
// move idle processes out of RAM, so physical memory is always full
//
void procinfo_other(PROCINFO& pi, vector<PROCINFO>& piv) {
// AppStat returned total for all other processes as a single PROCINFO
// struct with id field set to zero.
memset(&pi, 0, sizeof(pi));
procinfo_app(pi, piv);
}
#endif
static int bidirectional_popen(char *path, int *fd) {
pid_t pid;
char *appname;
appname = strrchr(path, '/');
if (! appname)
appname = path;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) { /* only need a single stream pipe */
msg_printf(NULL, MSG_ERROR, "%s: pipe error %d: %s\n", appname, errno, strerror(errno));
return ERR_SOCKET;
}
if ( (pid = fork()) < 0) {
close(fd[0]);
close(fd[1]);
msg_printf(NULL, MSG_ERROR, "%s: fork error\n", appname);
return ERR_FORK;
}
else if (pid > 0) { /* parent */
close(fd[1]);
} else { /* child */
close(fd[0]);
if (fd[1] != STDIN_FILENO) {
if (dup2(fd[1], STDIN_FILENO) != STDIN_FILENO) {
fprintf(stderr, "dup2 error to stdin");
exit (1);
}
}
if (fd[1] != STDOUT_FILENO) {
if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
fprintf(stderr, "dup2 error to stdout");
exit (1);
}
}
if (execl(path, appname, NULL) < 0) {
printf("-1\n");
fprintf(stderr, "execl error");
}
}
return 0;
}