From 0801522cb05fb842fbd85d1ef8298f350b150a22 Mon Sep 17 00:00:00 2001 From: Eric Heien Date: Mon, 15 Jul 2002 23:21:20 +0000 Subject: [PATCH] Added comments throughout code. svn path=/trunk/boinc/; revision=202 --- client/app.C | 108 +++++++++++++++++++++++++++++++++-------- client/app.h | 2 + client/client_state.C | 55 ++++++++++++++++++++- client/client_types.C | 62 +++++++++++++++++++---- client/configure | 2 +- client/configure.in | 2 +- client/cs_apps.C | 13 ++++- client/cs_files.C | 11 +++-- client/cs_scheduler.C | 18 +++++-- client/file_names.C | 17 +++++++ client/file_xfer.C | 21 ++++++++ client/filesys.C | 14 +++++- client/hostinfo.C | 4 ++ client/hostinfo_unix.C | 24 ++++++++- client/hostinfo_win.C | 2 + client/http.C | 50 +++++++++++++++++++ client/http.h | 1 + client/log_flags.C | 6 ++- client/main.C | 20 ++++++++ client/net_stats.C | 6 +++ client/net_xfer.C | 38 ++++++++++++--- client/prefs.C | 6 +++ client/speed_stats.C | 99 ++++++++++++++++++++++++------------- client/time_stats.C | 8 ++- client/util.C | 4 ++ 25 files changed, 503 insertions(+), 90 deletions(-) diff --git a/client/app.C b/client/app.C index 64bd922a4c..35f5976a8e 100644 --- a/client/app.C +++ b/client/app.C @@ -49,16 +49,17 @@ #if HAVE_FCNTL_H #include #endif -#include #if HAVE_SIGNAL_H #include #endif + +#include #include #include #include -#include "client_types.h" #include "client_state.h" +#include "client_types.h" #include "filesys.h" #include "file_names.h" #include "log_flags.h" @@ -67,19 +68,23 @@ #include "app.h" #include "api.h" -// take a string containing some words. +// take a string containing some space separated words. // return an array of pointers to the null-terminated words. // Modifies the string arg. -// -void parse_command_line(char* p, char** argv) { +// TODO: use strtok here +int parse_command_line(char* p, char** argv) { char** pp = argv; bool space = true; + if(p==NULL) { fprintf(stderr, "error: parse_command_line: unexpected NULL pointer p\n"); + return ERR_NULL; } if(argv==NULL) { fprintf(stderr, "error: parse_command_line: unexpected NULL pointer argv\n"); + return ERR_NULL; } + while (*p) { if (isspace(*p)) { *p = 0; @@ -93,40 +98,59 @@ void parse_command_line(char* p, char** argv) { p++; } *pp++ = 0; + + return 0; } -static void print_argv(char** argv) { +// Goes through an array of strings, and prints each string +// +static int print_argv(char** argv) { int i; + if(argv==NULL) { fprintf(stderr, "error: print_argv: unexpected NULL pointer argv\n"); + return ERR_NULL; } for (i=0; argv[i]; i++) { fprintf(stderr, "argv[%d]: %s\n", i, argv[i]); } + + return 0; } +// Initialize the ACTIVE_TASK object members to null +// ACTIVE_TASK::ACTIVE_TASK() { result = NULL; wup = NULL; app_version = NULL; + pid = 0; slot = 0; + state = PROCESS_UNINITIALIZED; exit_status = 0; signal = 0; strcpy(dirname, ""); prev_cpu_time = 0; } +// Initialize active task with a specific result requirement +// int ACTIVE_TASK::init(RESULT* rp) { if(rp==NULL) { fprintf(stderr, "error: ACTIVE_TASK.init: unexpected NULL pointer rp\n"); return ERR_NULL; } + result = rp; wup = rp->wup; app_version = wup->avp; + return 0; } +// Start a task in a slot directory. This includes setting up soft links, +// passing preferences, and starting the actual process for computation +// int ACTIVE_TASK::start(bool first_time) { char exec_name[256], file_path[256], link_path[256],temp[256]; char* argv[100]; @@ -139,37 +163,42 @@ int ACTIVE_TASK::start(bool first_time) { APP_IN app_prefs; prev_cpu_time = 0; - // These should be chosen in a better manner + // These should be chosen in a better manner (user specifiable) app_prefs.graphics.xsize = 640; app_prefs.graphics.ysize = 480; app_prefs.graphics.refresh_period = 5; app_prefs.checkpoint_period = 5; app_prefs.poll_period = 5; - // Write out the app prefs + // Write out the app prefs. This has everything in the APP_IN + // struct, including graphics prefs and checkpoint/poll prefs sprintf( prefs_path, "%s/%s", dirname, CORE_TO_APP_FILE ); prefs_fd = fopen( prefs_path, "wb" ); if( !prefs_fd ) { if( log_flags.task_debug ) { printf( "Failed to open core to app prefs file %s.\n", prefs_path ); } - return -1; + return ERR_FOPEN; } rewind( prefs_fd ); write_core_file( prefs_fd,app_prefs ); fclose(prefs_fd); + // Open the init file. This file contains initialization + // information regarding tasks that can only be performed in + // the app, such as redirecting file descriptors + // sprintf( init_path, "%s/%s", dirname, BOINC_INIT_FILE ); init_file = fopen( init_path, "wb" ); if( !init_file ) { if( log_flags.task_debug ) { printf( "Failed to open init file %s.\n", init_path ); } - return -1; + return ERR_FOPEN; } rewind( init_file ); - // make a link to the executable + // make a soft link to the executable(s) // for (i=0; iapp_files.size(); i++) { fip = app_version->app_files[i].file_info; @@ -217,7 +246,7 @@ int ACTIVE_TASK::start(bool first_time) { } } - // hook up the output files + // hook up the output files using BOINC soft links // for (i=0; ioutput_files.size(); i++) { file_ref = result->output_files[i]; @@ -326,15 +355,15 @@ int ACTIVE_TASK::start(bool first_time) { } pid_handle = process_info.hProcess; -#endif - -#ifdef macintosh #endif state = PROCESS_RUNNING; return 0; } +// Sends a request to the process of this active task to exit. If it +// doesn't exist within a set time (seconds), the process is terminated +// void ACTIVE_TASK::request_exit(int seconds) { int retval; if(seconds<0) { @@ -355,6 +384,8 @@ void ACTIVE_TASK::request_exit(int seconds) { #endif } +// Inserts an active task into the ACTIVE_TASK_SET and starts it up +// int ACTIVE_TASK_SET::insert(ACTIVE_TASK* atp) { int retval; if(atp==NULL) { @@ -369,7 +400,7 @@ int ACTIVE_TASK_SET::insert(ACTIVE_TASK* atp) { return 0; } -// check for child process exit +// Checks if any child processes have exited and records their final CPU time // bool ACTIVE_TASK_SET::poll() { int stat; @@ -388,7 +419,6 @@ bool ACTIVE_TASK_SET::poll() { atp = active_tasks[i]; if( GetExitCodeProcess( atp->pid_handle,&exit_code ) ) { // Get the elapsed CPU time - // Factor this into the equivalent of a S@H etime function? if( GetProcessTimes( atp->pid_handle, &creation_time, &exit_time, &kernel_time, &user_time ) ) { tKernel.LowPart = kernel_time.dwLowDateTime; tKernel.HighPart = kernel_time.dwHighDateTime; @@ -401,6 +431,7 @@ bool ACTIVE_TASK_SET::poll() { atp->result->cpu_time = (totTime / 10000000.0); } else { + // This probably isn't correct atp->result->cpu_time = ((double)clock())/CLOCKS_PER_SEC; } if( exit_code != STILL_ACTIVE ) { @@ -465,20 +496,24 @@ bool ACTIVE_TASK_SET::poll() { return true; } +// Find the ACTIVE_TASK in the current set with the matching PID +// ACTIVE_TASK* ACTIVE_TASK_SET::lookup_pid(int pid) { unsigned int i; ACTIVE_TASK* atp; if(pid<0) { fprintf(stderr, "error: ACTIVE_TASK_SET.lookup_pid: negatvie pid\n"); - return 0; + return NULL; } for (i=0; ipid == pid) return atp; } - return 0; + return NULL; } +// Sends a suspend request to all currently running computation processes +// void ACTIVE_TASK_SET::suspend_all() { unsigned int i; ACTIVE_TASK* atp; @@ -488,6 +523,8 @@ void ACTIVE_TASK_SET::suspend_all() { } } +// Sends a resume signal to all currently running computation processes +// void ACTIVE_TASK_SET::unsuspend_all() { unsigned int i; ACTIVE_TASK* atp; @@ -497,6 +534,9 @@ void ACTIVE_TASK_SET::unsuspend_all() { } } +// Attempts to exit all currently running computation processes, either +// via exit request or termination +// void ACTIVE_TASK_SET::exit_tasks() { unsigned int i; ACTIVE_TASK *atp; @@ -508,26 +548,37 @@ void ACTIVE_TASK_SET::exit_tasks() { } #ifdef _WIN32 +// Send a suspend request to the ACTIVE_TASK +// void ACTIVE_TASK::suspend() { prev_cpu_time = cpu_time; // figure out a way to do this, perhaps via trigger file? //kill(atp->pid, SIGSTOP); } +// Send a resume request to the ACTIVE_TASK +// void ACTIVE_TASK::unsuspend() { // figure out a way to do this, perhaps via trigger file? //kill(atp->pid, SIGCONT); } #else +// Send a suspend request to the ACTIVE_TASK +// void ACTIVE_TASK::suspend() { - kill(this->pid, SIGSTOP); + kill(this->pid, SIGSTOP); } +// Send a resume request to the ACTIVE_TASK +// void ACTIVE_TASK::unsuspend() { - kill(this->pid, SIGCONT); + kill(this->pid, SIGCONT); } #endif +// Remove an ACTIVE_TASK from the set, assumes that the task has +// already been shut down via request_exit or similar means +// int ACTIVE_TASK_SET::remove(ACTIVE_TASK* atp) { vector::iterator iter; if(atp==NULL) { @@ -546,6 +597,8 @@ int ACTIVE_TASK_SET::remove(ACTIVE_TASK* atp) { return 1; } +// Restart active tasks without wiping and reinitializing slot directories +// int ACTIVE_TASK_SET::restart_tasks() { vector::iterator iter; ACTIVE_TASK* atp; @@ -569,6 +622,9 @@ int ACTIVE_TASK_SET::restart_tasks() { return 0; } +// Update the CPU time accounting based on the APP_TO_CORE_FILE passed to +// us by the application +// bool ACTIVE_TASK::update_time() { FILE* app_fp; char app_path[256]; @@ -584,6 +640,8 @@ bool ACTIVE_TASK::update_time() { return true; } +// Poll each of the currently running tasks and get their CPU time +// bool ACTIVE_TASK_SET::poll_time() { ACTIVE_TASK* atp; unsigned int i; @@ -595,6 +653,8 @@ bool ACTIVE_TASK_SET::poll_time() { return updated; } +// Write XML data about this ACTIVE_TASK +// int ACTIVE_TASK::write(FILE* fout) { if(fout==NULL) { fprintf(stderr, "error: ACTIVE_TASK.write: unexpected NULL pointer fout\n"); @@ -617,6 +677,8 @@ int ACTIVE_TASK::write(FILE* fout) { return 0; } +// Parse XML information about an active task +// int ACTIVE_TASK::parse(FILE* fin, CLIENT_STATE* cs) { char buf[256], result_name[256], project_master_url[256]; int app_version_num=0; @@ -666,6 +728,8 @@ int ACTIVE_TASK::parse(FILE* fin, CLIENT_STATE* cs) { return -1; } +// Write XML information about this active task set +// int ACTIVE_TASK_SET::write(FILE* fout) { unsigned int i; if(fout==NULL) { @@ -680,6 +744,8 @@ int ACTIVE_TASK_SET::write(FILE* fout) { return 0; } +// Parse XML information about an active task set +// int ACTIVE_TASK_SET::parse(FILE* fin, CLIENT_STATE* cs) { ACTIVE_TASK* atp; char buf[256]; diff --git a/client/app.h b/client/app.h index e7b6706a60..25c897e285 100644 --- a/client/app.h +++ b/client/app.h @@ -20,6 +20,8 @@ #ifndef _TASK_ #define _TASK_ +// Possible states of a process in an ACTIVE_TASK +#define PROCESS_UNINITIALIZED 0 #define PROCESS_RUNNING 1 #define PROCESS_EXITED 2 #define PROCESS_WAS_SIGNALED 3 diff --git a/client/client_state.C b/client/client_state.C index de42273798..74ce708229 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -33,6 +33,7 @@ #define SECONDS_IN_MONTH 2592000 +// Global CLIENT_STATE object CLIENT_STATE gstate; CLIENT_STATE::CLIENT_STATE() { @@ -74,6 +75,9 @@ int CLIENT_STATE::init(PREFS* p) { if (log_flags.state_debug) { print_counts(); } + + // Finally, set up the project and slot directories + // make_project_dirs(); make_slot_dirs(); @@ -81,6 +85,8 @@ int CLIENT_STATE::init(PREFS* p) { } // Returns true if time tests should be run +// This is determined by seeing if the user passed the "-no_time_test" +// flag or if it's been a month since we last checked time stats // bool CLIENT_STATE::run_time_tests() { return (run_time_test && ( @@ -88,7 +94,7 @@ bool CLIENT_STATE::run_time_tests() { )); } -// Updates computer statistics once per month +// Updates computer statistics (roughly once a month) // int CLIENT_STATE::time_tests() { get_host_info(host_info); // this is platform dependent @@ -124,6 +130,9 @@ int CLIENT_STATE::check_suspend_activities() { return 0; } +// do_something is where all the action happens. This is part of the +// finite state machine abstraction of the client. Each of the key +// elements of the client is given a chance to perform work here. // return true if something happened // bool CLIENT_STATE::do_something() { @@ -150,6 +159,8 @@ bool CLIENT_STATE::do_something() { return action; } +// Parse the client_state.xml file +// int CLIENT_STATE::parse_state_file() { char buf[256]; FILE* f = fopen(STATE_FILE_NAME, "r"); @@ -245,6 +256,9 @@ int CLIENT_STATE::parse_state_file() { return ERR_XML_PARSE; } +// Make a directory for each of the projects present +// in the client state +// int CLIENT_STATE::make_project_dirs() { unsigned int i; for (i=0; i")) return 0; else if (match_tag(buf, "")) { @@ -279,6 +305,8 @@ int FILE_INFO::parse(FILE* in, bool from_server) { return 1; } +// Write out XML based file info +// int FILE_INFO::write(FILE* out, bool to_server) { unsigned int i; if(out==NULL) { @@ -317,7 +345,7 @@ int FILE_INFO::write(FILE* out, bool to_server) { return 0; } -// delete underlying file +// delete physical underlying file associated with FILE_INFO // int FILE_INFO::delete_file() { char path[256]; @@ -326,6 +354,8 @@ int FILE_INFO::delete_file() { return file_delete(path); } +// Parse XML based app_version information, usually from client_state.xml +// int APP_VERSION::parse(FILE* in) { char buf[256]; FILE_REF file_ref; @@ -351,6 +381,8 @@ int APP_VERSION::parse(FILE* in) { return 1; } +// Write XML based app_version information, usually to client_state.xml +// int APP_VERSION::write(FILE* out) { unsigned int i; if(out==NULL) { @@ -373,6 +405,8 @@ int APP_VERSION::write(FILE* out) { return 0; } +// Parse XML based file_ref information, usually from client_state.xml +// int FILE_REF::parse(FILE* in) { char buf[256]; if(in==NULL) { @@ -394,19 +428,21 @@ int FILE_REF::parse(FILE* in) { return 1; } +// Write XML based file_ref information, usually to client_state.xml +// int FILE_REF::write(FILE* out) { if(out==NULL) { fprintf(stderr, "error: FILE_REF.write: unexpected NULL pointer out\n"); return ERR_NULL; } - if (strlen(open_name)) { - fprintf(out, " %s\n", open_name); - } fprintf(out, " \n" " %s\n", file_name ); + if (strlen(open_name)) { + fprintf(out, " %s\n", open_name); + } if (fd >= 0) { fprintf(out, " %d\n", fd); } @@ -417,6 +453,8 @@ int FILE_REF::write(FILE* out) { return 0; } +// Parse XML based workunit information, usually from client_state.xml +// int WORKUNIT::parse(FILE* in) { char buf[256]; FILE_REF file_ref; @@ -450,6 +488,8 @@ int WORKUNIT::parse(FILE* in) { return 1; } +// Write XML based workunit information, usually to client_state.xml +// int WORKUNIT::write(FILE* out) { unsigned int i; if(out==NULL) { @@ -612,6 +652,8 @@ int RESULT::write(FILE* out, bool to_server) { } // this is called only after is_compute_done is true. +// returns true if the result and it's associated files +// were successfully uploaded // bool RESULT::is_upload_done() { unsigned int i; diff --git a/client/configure b/client/configure index 58f6a57672..3631c70c1c 100644 --- a/client/configure +++ b/client/configure @@ -1505,7 +1505,7 @@ EOF fi -for ac_hdr in fcntl.h sys/time.h unistd.h sys/select.h sys/statvfs.h sys/swap.h sys/systeminfo.h sys/types.h dirent.h sys/utsname.h netdb.h netinet/in.h arpa/inet.h sys/resource.h signal.h sys/wait.h +for ac_hdr in fcntl.h sys/time.h unistd.h sys/select.h sys/statvfs.h sys/swap.h sys/systeminfo.h sys/socket.h sys/types.h dirent.h sys/utsname.h netdb.h netinet/in.h netinet/tcp.h arpa/inet.h sys/resource.h signal.h sys/wait.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 diff --git a/client/configure.in b/client/configure.in index c959504818..8e7e65fc62 100644 --- a/client/configure.in +++ b/client/configure.in @@ -37,7 +37,7 @@ AC_CHECK_LIB(stdc++, cerr) dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/select.h sys/statvfs.h sys/swap.h sys/systeminfo.h sys/types.h dirent.h sys/utsname.h netdb.h netinet/in.h arpa/inet.h sys/resource.h signal.h sys/wait.h) +AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/select.h sys/statvfs.h sys/swap.h sys/systeminfo.h sys/socket.h sys/types.h dirent.h sys/utsname.h netdb.h netinet/in.h netinet/tcp.h arpa/inet.h sys/resource.h signal.h sys/wait.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/client/cs_apps.C b/client/cs_apps.C index abb1e376f6..d406dc69c8 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -54,7 +54,7 @@ int CLIENT_STATE::app_finished(ACTIVE_TASK& at) { return 0; } -// poll and clean up after existing apps +// poll status of existing apps and and clean up after them // bool CLIENT_STATE::handle_running_apps() { unsigned int i; @@ -80,6 +80,9 @@ bool CLIENT_STATE::handle_running_apps() { return action; } +// Returns true if all the input files for a result are available +// locally, false otherwise +// bool CLIENT_STATE::input_files_available(RESULT* rp) { if(rp==NULL) { fprintf(stderr, "error: CLIENT_STATE.input_files_available: unexpected NULL pointer rp\n"); @@ -111,6 +114,8 @@ bool CLIENT_STATE::start_apps() { bool action = false; for (i=0; iis_compute_done && !rp->is_active && input_files_available(rp)) { if (log_flags.task_debug) { printf("starting application for result %s\n", rp->name); @@ -133,7 +142,7 @@ bool CLIENT_STATE::start_apps() { return action; } -// This is called on initialization. +// This is called when the client is initialized. // Try to restart any tasks that were running when we last shut down. // int CLIENT_STATE::restart_tasks() { diff --git a/client/cs_files.C b/client/cs_files.C index 3e2d9cb2d8..db5c1b13d2 100644 --- a/client/cs_files.C +++ b/client/cs_files.C @@ -39,6 +39,9 @@ #include "client_state.h" #include "error_numbers.h" +// Verify the validity of a downloaded file, through MD5 checksum +// or an RSA signature +// int verify_downloaded_file(char* pathname, FILE_INFO& file_info) { char cksum[64]; PROJECT* project; @@ -77,6 +80,10 @@ int verify_downloaded_file(char* pathname, FILE_INFO& file_info) { return 0; } +// scan all FILE_INFOs. +// start downloads and uploads as needed. +// check for completion of existing transfers +// bool CLIENT_STATE::start_file_xfers() { unsigned int i; FILE_INFO* fip; @@ -85,10 +92,6 @@ bool CLIENT_STATE::start_file_xfers() { int retval; bool action = false; - // scan all FILE_INFOs. - // start downloads and uploads as needed. - // check for completion of existing transfers - // for (i=0; ifile_xfer; diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 9d462d4853..a4704d3ff1 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -158,6 +158,10 @@ PROJECT* CLIENT_STATE::choose_project() { } #endif +// Compute the "resource debt" of each project. This is used +// to determine what project we will focus on next, based on +// the user specified resource share +// void CLIENT_STATE::compute_resource_debts() { unsigned int i, j; PROJECT* p, *pbest; @@ -190,6 +194,10 @@ void CLIENT_STATE::compute_resource_debts() { } } +// Prepare the scheduler request. This writes the request in XML to a +// file (SCHED_OP_REQUEST_FILE) which is later sent to the scheduling +// server +// int CLIENT_STATE::make_scheduler_request(PROJECT* p, double work_req) { FILE* f = fopen(SCHED_OP_REQUEST_FILE, "wb"); unsigned int i; @@ -371,15 +379,19 @@ bool CLIENT_STATE::get_work() { } #endif -// see whether a new preferences set, obtained from -// the given project, looks "reasonable". +// see whether a new preferences set, obtained from the given +// project, looks "reasonable". This is to prevent accidental or +// intentional preferences corruption // Currently this is primitive: just make sure there's at least 1 project -// +// TODO: figure out what else to look for here bool PREFS::looks_reasonable(PROJECT& project) { if (projects.size() > 0) return true; return false; } +// Parse the reply from a scheduler and configure internal structures +// appropriately +// void CLIENT_STATE::handle_scheduler_reply( PROJECT* project, char* scheduler_url ) { diff --git a/client/file_names.C b/client/file_names.C index 422a626c64..0a61dd3cb3 100644 --- a/client/file_names.C +++ b/client/file_names.C @@ -30,6 +30,8 @@ #include "file_names.h" #include "error_numbers.h" +// Converts a character string of a decimal number to hexadecimal string +// static void c2x(char *what) { char buf[3]; char num = atoi(what); @@ -50,6 +52,9 @@ static void c2x(char *what) { strcpy(what, buf); } +// Escape a URL, converting the non alphanumeric characters to +// %XY where XY is their hexadecimal equivalent +// static void escape_url(char *in, char* out) { int x, y; if(in==NULL) { @@ -77,6 +82,8 @@ static void escape_url(char *in, char* out) { out[y] = 0; } +// Gets the pathname of a file +// void get_pathname(FILE_INFO* fip, char* path) { if(fip==NULL) { fprintf(stderr, "error: get_pathname: unexpected NULL pointer fip\n"); @@ -97,6 +104,8 @@ void get_pathname(FILE_INFO* fip, char* path) { } } +// Returns the location of a numbered slot directory +// void get_slot_dir(int slot, char* path) { if(path==NULL) { fprintf(stderr, "error: get_slot_dir: unexpected NULL pointer path\n"); @@ -119,6 +128,8 @@ int make_project_dir(PROJECT& p) { return 0; } +// Returns the location of a numbered slot directory +// int make_slot_dir(int slot) { if(slot<0) { fprintf(stderr, "error: make_slot_dir: negative slot\n"); @@ -133,6 +144,8 @@ int make_slot_dir(int slot) { #else +// Create the directory for the project p +// int make_project_dir(PROJECT& p) { char buf[256]; @@ -141,6 +154,8 @@ int make_project_dir(PROJECT& p) { return 0; } +// Create the slot directory for the specified slot # +// int make_slot_dir(int slot) { char buf[256]; if(slot<0) { @@ -153,6 +168,8 @@ int make_slot_dir(int slot) { return 0; } +// Returns a filename used for prefs backup +// int make_prefs_backup_name(PREFS& prefs, char* name) { if(name==NULL) { fprintf(stderr, "error: make_prefs_backup_name: unexpected NULL pointer name\n"); diff --git a/client/file_xfer.C b/client/file_xfer.C index 691c9e5dfd..cb8910d113 100644 --- a/client/file_xfer.C +++ b/client/file_xfer.C @@ -28,12 +28,21 @@ FILE_XFER::FILE_XFER() { file_xfer_done = false; file_xfer_retval = 0; + start_time = 0; + end_time = 0; + fip = NULL; + strcpy(pathname,""); + strcpy(header,""); + //state = ? } +// Do we need to do anything special when destroying the FILE_XFER object? +// FILE_XFER::~FILE_XFER() { } #if 0 +// Is there any reason to keep this around? int FILE_XFER::init_download(char* url, char* outfile) { if(url==NULL) { fprintf(stderr, "error: FILE_XFER.init_download: unexpected NULL pointer url\n"); @@ -46,6 +55,7 @@ int FILE_XFER::init_download(char* url, char* outfile) { return HTTP_OP::init_get(url, outfile); } +// Is there any reason to keep this around? int FILE_XFER::init_upload(char* url, char* infile) { if(url==NULL) { fprintf(stderr, "error: FILE_XFER.init_upload: unexpected NULL pointer url\n"); @@ -89,10 +99,14 @@ int FILE_XFER::init_upload(FILE_INFO& file_info) { return HTTP_OP::init_post2((char*)(&fip->urls[0]), header, pathname, 0); } +// Returns the total time that the file xfer has taken +// double FILE_XFER::elapsed_time() { return end_time - start_time; } +// Create a new empty FILE_XFER_SET +// FILE_XFER_SET::FILE_XFER_SET(HTTP_OP_SET* p) { if(p==NULL) { fprintf(stderr, "error: FILE_XFER_SET: unexpected NULL pointer p\n"); @@ -100,6 +114,8 @@ FILE_XFER_SET::FILE_XFER_SET(HTTP_OP_SET* p) { http_ops = p; } +// Insert a FILE_XFER object into the set +// int FILE_XFER_SET::insert(FILE_XFER* fxp) { int retval; if(fxp==NULL) { @@ -117,6 +133,8 @@ int FILE_XFER_SET::insert(FILE_XFER* fxp) { return 0; } +// Remove a FILE_XFER object from the set +// int FILE_XFER_SET::remove(FILE_XFER* fxp) { vector::iterator iter; if(fxp==NULL) { @@ -138,6 +156,9 @@ int FILE_XFER_SET::remove(FILE_XFER* fxp) { } +// Run through the FILE_XFER_SET and determine if any of the file +// transfers are complete or had an error +// bool FILE_XFER_SET::poll() { unsigned int i; FILE_XFER* fxp; diff --git a/client/filesys.C b/client/filesys.C index 9b091c4d32..3c46ee77a6 100644 --- a/client/filesys.C +++ b/client/filesys.C @@ -73,6 +73,7 @@ char failed_file[256]; // routines for enumerating the entries in a directory +// Open a directory int dir_open(char* p) { if(p==NULL) { fprintf(stderr, "error: dir_open: unexpected NULL pointer p\n"); @@ -87,6 +88,7 @@ int dir_open(char* p) { strcat(path, "\\*"); first = 1; handle = INVALID_HANDLE_VALUE; + // This is probably incomplete #endif #ifdef macintosh SayErr("\pdir_open called (empty function)"); /* CAF Temp */ @@ -94,6 +96,8 @@ int dir_open(char* p) { return 0; } +// Scan through a directory and return the next file name in it +// int dir_scan(char* p) { if(p==NULL) { fprintf(stderr, "error: dir_scan: unexpected NULL pointer p\n"); @@ -145,6 +149,8 @@ int dir_scan(char* p) { #endif } +// Close a directory +// void dir_close() { #ifdef HAVE_DIRENT_H if (dirp) { @@ -163,6 +169,8 @@ void dir_close() { #endif } +// Delete the file located at path +// int file_delete(char* path) { int retval,i; if(path==NULL) { @@ -200,8 +208,8 @@ int file_size(char* path, int& size) { return 0; } -/* boinc_link creates a file (new) which contains an XML - reference to existing. */ +/* boinc_link creates a file (new_link) which contains an XML + reference (soft link) to existing. */ int boinc_link( char *existing, char *new_link ) { FILE *fp; @@ -222,6 +230,8 @@ int boinc_link( char *existing, char *new_link ) { return 0; } +// Goes through directory specified by dirpath and removes all files from it +// int clean_out_dir(char* dirpath) { char filename[256], path[256]; int retval; diff --git a/client/hostinfo.C b/client/hostinfo.C index 0b97f0ae63..0081bdd30e 100644 --- a/client/hostinfo.C +++ b/client/hostinfo.C @@ -24,6 +24,8 @@ #include "hostinfo.h" #include "error_numbers.h" +// Parse the host information, usually from the client state XML file +// int HOST_INFO::parse(FILE* in) { char buf[256]; if(in==NULL) { @@ -55,6 +57,8 @@ int HOST_INFO::parse(FILE* in) { return 0; } +// Write the host information, usually to the client state XML file +// int HOST_INFO::write(FILE* out) { if(out==NULL) { fprintf(stderr, "error: HOST_INFO.write: unexpected NULL pointer out\n"); diff --git a/client/hostinfo_unix.C b/client/hostinfo_unix.C index 3b6537567a..fdf55f2897 100644 --- a/client/hostinfo_unix.C +++ b/client/hostinfo_unix.C @@ -61,6 +61,9 @@ // functions to get name/addr of local host +// Returns the domain of the local host +// TODO: Should the 256 be MAXHOSTNAMELEN instead? +// int get_local_domain_name(char* p) { char buf[256]; if(p==NULL) { @@ -73,6 +76,8 @@ int get_local_domain_name(char* p) { return 0; } +// Gets the ip address of the local host +// int get_local_ip_addr(int& p) { char buf[256]; struct in_addr addr; @@ -85,6 +90,9 @@ int get_local_ip_addr(int& p) { return 0; } +// Returns the name of the local host +// TODO: Should the 256 be MAXHOSTNAMELEN instead? +// int get_local_ip_addr_str(char* p) { char buf[256]; if(p==NULL) { @@ -101,6 +109,8 @@ int get_local_ip_addr_str(char* p) { return 0; } +// Converts a int ip address to a string representation (i.e. "66.218.71.198") +// char* ip_addr_string(int ip_addr) { in_addr ia; @@ -108,7 +118,8 @@ char* ip_addr_string(int ip_addr) { return inet_ntoa(ia); } - +// What does this return? # of seconds from GMT? +// void get_timezone(int& tz) { tzset(); @@ -120,6 +131,9 @@ void get_timezone(int& tz) { #endif } +// Returns true if the host is currently running off battery power +// TODO: port this to other platforms (Windows, Mac OS X, others?) +// bool host_is_running_on_batteries() { float x1, x2; int i1, i2; @@ -139,6 +153,8 @@ bool host_is_running_on_batteries() { #ifdef linux +// Determine the memory specifications for this host, including RAM and swap space +// void parse_meminfo(HOST_INFO& host) { char buf[256]; FILE* f = fopen("/proc/meminfo", "r"); @@ -157,7 +173,7 @@ void parse_meminfo(HOST_INFO& host) { // Unfortunately the format of /proc/cpuinfo is not standardized. // See http://people.nl.linux.org/~hch/cpuinfo/ for some examples. // The following is for Redhat Linux 2.2.14. -// +// TODO: get this to work on all platforms void parse_cpuinfo(HOST_INFO& host) { char buf[256]; int n; @@ -182,6 +198,8 @@ void parse_cpuinfo(HOST_INFO& host) { #endif #if HAVE_SYS_UTSNAME_H +// Puts the operating system name and version into the HOST_INFO structure +// void get_osinfo(HOST_INFO& host) { struct utsname u; uname(&u); @@ -190,6 +208,8 @@ void get_osinfo(HOST_INFO& host) { } #endif +// General function to get all relevant host information +// int get_host_info(HOST_INFO& host) { host.m_nbytes = 0; host.m_cache = 0; diff --git a/client/hostinfo_win.C b/client/hostinfo_win.C index eb04bf7270..a30014bce7 100644 --- a/client/hostinfo_win.C +++ b/client/hostinfo_win.C @@ -25,6 +25,8 @@ extern int get_local_domain_name(char* p); extern int get_local_ip_addr_str(char* p); +// Gets windows specific host information (not complete) +// int get_host_info(HOST_INFO& host) { OSVERSIONINFO OSVersionInfo; memset( &OSVersionInfo, NULL, sizeof( OSVersionInfo ) ); diff --git a/client/http.C b/client/http.C index b6e0d0dd88..9405a371d2 100644 --- a/client/http.C +++ b/client/http.C @@ -36,6 +36,10 @@ #define HTTP_BLOCKSIZE 4096 +// Breaks a url down into its server and file path components +// TODO: deal with alternate protocols (ftp, gopher, etc) or disallow +// them and parse accordingly +// static void parse_url(char* url, char* host, char* file) { char* p; char buf[256]; @@ -64,6 +68,8 @@ static void parse_url(char* url, char* host, char* file) { // We use 1.0 so we don't have to count bytes. // +// Prints an HTTP 1.0 GET request header into buf +// static void http_get_request_header( char* buf, char* host, char* file, int offset ) { @@ -102,6 +108,8 @@ static void http_get_request_header( } } +// Prints an HTTP 1.0 HEAD request header into buf +// static void http_head_request_header(char* buf, char* host, char* file) { if(buf==NULL) { fprintf(stderr, "error: http_head_request_header: unexpected NULL pointer buf\n"); @@ -122,6 +130,8 @@ static void http_head_request_header(char* buf, char* host, char* file) { ); } +// Prints an HTTP 1.0 POST request header into buf +// static void http_post_request_header( char* buf, char* host, char* file, int size ) { @@ -150,6 +160,8 @@ static void http_post_request_header( } #if 0 +// Do we still need this? +// void http_put_request_header( char* buf, char* host, char* file, int size, int offset ) { @@ -196,6 +208,8 @@ void http_put_request_header( } #endif +// Parse an http reply header into the header struct +// int read_http_reply_header(int socket, HTTP_REPLY_HEADER& header) { int i, n; char buf[1024], *p; @@ -224,6 +238,8 @@ int read_http_reply_header(int socket, HTTP_REPLY_HEADER& header) { return 1; } +// Read the contents of the socket into buf +// static int read_reply(int socket, char* buf, int len) { int i, n; if(socket<0) { @@ -248,11 +264,24 @@ static int read_reply(int socket, char* buf, int len) { HTTP_OP::HTTP_OP() { http_op_state = HTTP_STATE_IDLE; + strcpy(hostname,""); + strcpy(filename,""); + req1 = NULL; + strcpy(infile,""); + strcpy(outfile,""); + content_length = 0; + file_offset = 0; + strcpy(request_header,""); + http_op_state = HTTP_STATE_IDLE; + http_op_type = HTTP_OP_NONE; + http_op_retval = 0; } HTTP_OP::~HTTP_OP() { } +// Initialize HTTP HEAD operation to url +// int HTTP_OP::init_head(char* url) { if(url==NULL) { fprintf(stderr, "error: HTTP_OP.init_head: unexpected NULL pointer url\n"); @@ -266,6 +295,8 @@ int HTTP_OP::init_head(char* url) { return 0; } +// Initialize HTTP GET operation to url +// int HTTP_OP::init_get(char* url, char* out, int off) { if(url==NULL) { fprintf(stderr, "error: HTTP_OP.init_get: unexpected NULL pointer url\n"); @@ -289,6 +320,8 @@ int HTTP_OP::init_get(char* url, char* out, int off) { return 0; } +// Initialize HTTP POST operation to url +// int HTTP_OP::init_post(char* url, char* in, char* out) { int retval; if(url==NULL) { @@ -317,6 +350,8 @@ int HTTP_OP::init_post(char* url, char* in, char* out) { return 0; } +// Initialize HTTP POST operation to url including file offset +// int HTTP_OP::init_post2( char* url, char* r1, char* in, double offset ) { @@ -355,6 +390,7 @@ int HTTP_OP::init_post2( } #if 0 +// Is this still needed? int HTTP_OP::init_put(char* url, char* in, int off) { int retval; @@ -373,6 +409,8 @@ int HTTP_OP::init_put(char* url, char* in, int off) { } #endif +// Returns true if the HTTP operation is complete +// bool HTTP_OP::http_op_done() { return (http_op_state == HTTP_STATE_DONE); } @@ -384,6 +422,8 @@ HTTP_OP_SET::HTTP_OP_SET(NET_XFER_SET* p) { net_xfers = p; } +// Inserts an hTTP_OP into the set +// int HTTP_OP_SET::insert(HTTP_OP* ho) { int retval; if(ho==NULL) { @@ -396,6 +436,10 @@ int HTTP_OP_SET::insert(HTTP_OP* ho) { return 0; } +// Runs through the set of HTTP_OP objects in the set and decides +// what operation is appropriate for each. This section needs more +// thorough documentation, as it is fairly complex +// bool HTTP_OP_SET::poll() { unsigned int i; HTTP_OP* htp; @@ -406,6 +450,8 @@ bool HTTP_OP_SET::poll() { htp = http_ops[i]; switch(htp->http_op_state) { case HTTP_STATE_CONNECTING: + // If the op is in the connecting state, and we notice it is done + // connecting, move it to the HTTP_STATE_REQUEST_HEADER state if (htp->is_connected) { htp->http_op_state = HTTP_STATE_REQUEST_HEADER; htp->want_upload = true; @@ -547,6 +593,8 @@ bool HTTP_OP_SET::poll() { return action; } +// Remove an HTTP_OP from the set +// int HTTP_OP_SET::remove(HTTP_OP* p) { vector::iterator iter; if(p==NULL) { @@ -567,6 +615,8 @@ int HTTP_OP_SET::remove(HTTP_OP* p) { return 1; } +// Returns the size of the set of HTTP_OP objects +// int HTTP_OP_SET::size() { return http_ops.size(); } diff --git a/client/http.h b/client/http.h index 30acf54f38..f9ab81cd94 100644 --- a/client/http.h +++ b/client/http.h @@ -31,6 +31,7 @@ struct HTTP_REPLY_HEADER { int content_length; }; +#define HTTP_OP_NONE 0 // For the first 4, data source/sink are files #define HTTP_OP_GET 1 #define HTTP_OP_POST 2 diff --git a/client/log_flags.C b/client/log_flags.C index 0ffb270c81..0036d89434 100644 --- a/client/log_flags.C +++ b/client/log_flags.C @@ -28,9 +28,13 @@ LOG_FLAGS log_flags; LOG_FLAGS::LOG_FLAGS() { - memset(this, 0, sizeof(LOG_FLAGS)); + task = file_xfer = sched_ops = state_debug = false; + task_debug = file_xfer_debug = sched_op_debug = false; + http_debug = time_debug = net_xfer_debug = false; } +// Parse log flag preferences +// int LOG_FLAGS::parse(FILE* in) { char buf[256]; if(in==NULL) { diff --git a/client/main.C b/client/main.C index 867686c49c..b222399bd2 100644 --- a/client/main.C +++ b/client/main.C @@ -30,6 +30,9 @@ #include "prefs.h" #include "util.h" +// Display a message to the user. Depending on the priority, the +// message may be more or less obtrusive +// void show_message(char* message, char* priority) { if(message==NULL) { fprintf(stderr, "error: show_message: unexpected NULL pointer message\n"); @@ -46,6 +49,7 @@ void show_message(char* message, char* priority) { // Prompt user for project URL and authenticator, // and create a prototype prefs file +// TODO: use better input method here, backspace doesn't always seem to work // int initialize_prefs() { char master_url[256]; @@ -73,14 +77,19 @@ int main(int argc, char** argv) { FILE* f; int retval; + // Set the stdout buffer to 0, such that stdout output + // immediately gets written out setbuf(stdout, 0); + // Read any log flags preferences, used mainly for debugging f = fopen(LOG_FLAGS_FILE, "r"); if (f) { log_flags.parse(f); fclose(f); } + // Read the user preferences file, if it exists. If it doesn't, + // prompt user for project URL via initialize_prefs() prefs = new PREFS; retval = prefs->parse_file(); if (retval) { @@ -96,23 +105,34 @@ int main(int argc, char** argv) { } } + // Initialize the client state with the preferences gstate.init(prefs); + // Parse command line arguments gstate.parse_cmdline(argc, argv); + // Run the time tests and host information check if needed + // TODO: break time tests and host information check into two + // separate functions? if(gstate.run_time_tests()) { gstate.time_tests(); } + // Restart any tasks that were running when we last quit the client gstate.restart_tasks(); while (1) { + // do_something is where the meat of the clients work is done + // it will return false if it had nothing to do, in which case + // client will go to sleep for a second if (!gstate.do_something()) { if (log_flags.time_debug) printf("SLEEP 1 SECOND\n"); fflush(stdout); boinc_sleep(1); } + // If it's time to exit, break out of the while loop if (gstate.time_to_exit()) { printf("time to exit\n"); break; } } + // Clean everything up and gracefully exit gstate.exit_tasks(); return 0; } diff --git a/client/net_stats.C b/client/net_stats.C index bcf73f7c4a..52a7942259 100644 --- a/client/net_stats.C +++ b/client/net_stats.C @@ -26,6 +26,7 @@ #include "error_numbers.h" #include "net_stats.h" +// Is this a reasonable cutoff? #define SMALL_FILE_CUTOFF 32000 NET_STATS::NET_STATS() { @@ -35,6 +36,7 @@ NET_STATS::NET_STATS() { bwdown = 0; } +// Update network statistics void NET_STATS::update(bool is_upload, double nbytes, double nsecs) { double w1, w2, bw; @@ -66,6 +68,8 @@ void NET_STATS::update(bool is_upload, double nbytes, double nsecs) { } } +// Write XML based network statistics +// int NET_STATS::write(FILE* out, bool to_server) { if(out==NULL) { fprintf(stderr, "error: NET_STATS.write: unexpected NULL pointer out\n"); @@ -89,6 +93,8 @@ int NET_STATS::write(FILE* out, bool to_server) { return 0; } +// Read XML based network statistics +// int NET_STATS::parse(FILE* in) { char buf[256]; if(in==NULL) { diff --git a/client/net_xfer.C b/client/net_xfer.C index 137a94a77a..f84ca858b1 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -23,22 +23,38 @@ #ifdef _WIN32 #include "winsock.h" -#else +#endif + +#if HAVE_SYS_TIME_H #include +#endif +#if HAVE_SYS_SOCKET_H #include +#endif +#if HAVE_SYS_SELECT_H #include +#endif +#if HAVE_NETINET_IN_H #include +#endif +#if HAVE_NETINET_TCP_H #include +#endif +#if HAVE_NETDB_H #include +#endif +#if HAVE_UNISTD_H #include #endif +#if HAVE_FCNTL_H +#include +#endif #include //#include #include #include #include -#include #include #include "error_numbers.h" @@ -54,7 +70,8 @@ #define socklen_t size_t #endif - +// Attempt to open a nonblocking socket to a server +// int NET_XFER::open_server() { sockaddr_in addr; hostent* hep; @@ -108,18 +125,23 @@ int NET_XFER::open_server() { void NET_XFER::init(char* host, int p, int b) { - strcpy(hostname, host); - port = p; + // net_xfer_state = ? + socket = -1; is_connected = false; want_download = false; want_upload = false; do_file_io = false; io_done = false; + file = NULL; io_ready = false; error = 0; + strcpy(hostname, host); + port = p; blocksize = b; } +// Insert a NET_XFER object into the set +// int NET_XFER_SET::insert(NET_XFER* nxp) { int retval = nxp->open_server(); if (retval) return retval; @@ -127,6 +149,8 @@ int NET_XFER_SET::insert(NET_XFER* nxp) { return 0; } +// Remove a NET_XFER object from the set +// int NET_XFER_SET::remove(NET_XFER* nxp) { vector::iterator iter; @@ -150,7 +174,7 @@ int NET_XFER_SET::remove(NET_XFER* nxp) { // transfer data to/from a list of active streams // transfer at most max_bytes bytes. -// +// TODO: implement other bandwidth constraints (ul/dl ratio, time of day) int NET_XFER_SET::poll(int max_bytes, int& bytes_transferred) { int n, retval; @@ -252,6 +276,8 @@ int NET_XFER_SET::do_select(int max_bytes, int& bytes_transferred) { return 0; } +// Return the NET_XFER object whose socket matches fd +// NET_XFER* NET_XFER_SET::lookup_fd(int fd) { for (unsigned int i=0; isocket == fd) { diff --git a/client/prefs.C b/client/prefs.C index 4b73d247a4..e44246dbfd 100644 --- a/client/prefs.C +++ b/client/prefs.C @@ -42,6 +42,8 @@ PREFS::PREFS() { disk_min_free_gb = 0; }; +// Parse XML based prefs, usually from prefs.xml +// int PREFS::parse(FILE* in) { char buf[256]; PROJECT* project; @@ -76,6 +78,8 @@ int PREFS::parse(FILE* in) { return ERR_XML_PARSE; } +// Parse prefs.xml for user preferences +// int PREFS::parse_file() { FILE* f; int retval; @@ -87,6 +91,8 @@ int PREFS::parse_file() { return retval; } +// Write the default preference set for a project +// TODO: should mod_time really be 1? int write_initial_prefs(char* master_url, char* authenticator) { FILE* f = fopen(PREFS_FILE_NAME, "w"); if (!f) return ERR_FOPEN; diff --git a/client/speed_stats.C b/client/speed_stats.C index bbe819a4d1..a9ec8a4edd 100644 --- a/client/speed_stats.C +++ b/client/speed_stats.C @@ -6,9 +6,10 @@ #include "speed_stats.h" #include "error_numbers.h" -#define D_FLOP_ITERS 1 -#define I_OP_ITERS 1 -#define BANDWIDTH_ITERS 1 +// # of iterations of each test to run for initial timing purposes +#define D_FLOP_ITERS 100 +#define I_OP_ITERS 100 +#define BANDWIDTH_ITERS 5 //#define RUN_TEST @@ -24,6 +25,29 @@ int main( void ) { return 0; } +void run_test_suite( double num_secs_per_test ) { + if(num_secs_per_test<0) { + fprintf(stderr, "error: run_test_suite: negative num_seconds_per_test\n"); + } + printf( + "Running tests. This will take about %.1lf seconds.\n\n", + num_secs_per_test*3 + ); + + printf( + "Speed: %.5lf million flops/sec\n\n", + run_double_prec_test(num_secs_per_test)/1000000 + ); + printf( + "Speed: %.5lf million integer ops/sec\n\n", + run_int_test(num_secs_per_test)/1000000 + ); + printf( + "Speed: %.5lf MB/sec\n\n", + 12*sizeof(double)*run_mem_bandwidth_test(num_secs_per_test)/1000000 + ); +} + #endif int check_cache_size( int mem_size ) { @@ -163,6 +187,8 @@ int check_cache_size( int mem_size ) { return 0; } +// Run the test of double precision math speed for about num_secs seconds +// double run_double_prec_test( double num_secs ) { int df_test_time, df_iters; double df_secs; @@ -178,7 +204,7 @@ double run_double_prec_test( double num_secs ) { // Calculate the # of iterations based on these tests df_iters = (int)(D_FLOP_ITERS*num_secs/df_secs); - if( df_iters > D_FLOP_ITERS ) { // no need to redo test + if( df_iters > D_FLOP_ITERS ) { // no need to redo test if we already got enough df_test_time = (int)double_flop_test( df_iters, 0 ); } else { df_iters = D_FLOP_ITERS; @@ -189,6 +215,8 @@ double run_double_prec_test( double num_secs ) { return 1000000*df_iters/df_secs; } +// Run the test of integer math speed for about num_secs seconds +// double run_int_test( double num_secs ) { int int_test_time, int_iters; double int_secs; @@ -215,6 +243,8 @@ double run_int_test( double num_secs ) { return 1000000*int_iters/int_secs; } +// Run the test of memory bandwidth speed for about num_secs seconds +// double run_mem_bandwidth_test( double num_secs ) { int bw_test_time; double bw_secs; @@ -241,29 +271,6 @@ double run_mem_bandwidth_test( double num_secs ) { return 1000000*bw_iters/bw_secs; } -void run_test_suite( double num_secs_per_test ) { - if(num_secs_per_test<0) { - fprintf(stderr, "error: run_test_suite: negative num_seconds_per_test\n"); - } - printf( - "Running tests. This will take about %.1lf seconds.\n\n", - num_secs_per_test*3 - ); - - printf( - "Speed: %.5lf million flops/sec\n\n", - run_double_prec_test(num_secs_per_test)/1000000 - ); - printf( - "Speed: %.5lf million integer ops/sec\n\n", - run_int_test(num_secs_per_test)/1000000 - ); - printf( - "Speed: %.5lf MB/sec\n\n", - 12*sizeof(double)*run_mem_bandwidth_test(num_secs_per_test)/1000000 - ); -} - // One iteration == D_LOOP_ITERS (1,000,000) floating point operations // If time_total is negative, there was an error in the calculation, // meaning there is probably something wrong with the CPU @@ -289,9 +296,10 @@ clock_t double_flop_test( int iterations, int print_debug ) { for( j=0;j time_start ) { + time_total -= time_start; + } else { + time_total = 0; // this is just a kludge + } + calc_error = 0; temp = 1; - // Check to make sure all the values are the same + // Check to make sure all the values are the same as when we started for( i=0;i time_start ) { + time_total -= time_start; + } else { + time_total = 0; // this is just a kludge + } calc_error = 0; temp = 1; - // Check to make sure all the values are the same + // Check to make sure all the values are the same as when we started for( i=0;i time_start ) { time_total -= time_start; } else { - time_total -= time_start; + time_total = 0; // this is just a kludge } copy_error = 0; diff --git a/client/time_stats.C b/client/time_stats.C index ed3c4fafa2..b879e0c3cd 100644 --- a/client/time_stats.C +++ b/client/time_stats.C @@ -33,13 +33,15 @@ #define ALPHA (3600.*24*7*30) TIME_STATS::TIME_STATS() { - first = true; last_update = 0; + first = true; on_frac = 1; connected_frac = 1; active_frac = 1; } +// Update time statistics based on current activities +// void TIME_STATS::update(bool is_connected, bool is_active) { int now = time(0), dt; double w1, w2; @@ -78,6 +80,8 @@ void TIME_STATS::update(bool is_connected, bool is_active) { } } +// Write XML based time statistics +// int TIME_STATS::write(FILE* out, bool to_server) { fprintf(out, "\n" @@ -98,6 +102,8 @@ int TIME_STATS::write(FILE* out, bool to_server) { return 0; } +// Parse XML based time statistics, usually from client_state.xml +// int TIME_STATS::parse(FILE* in) { char buf[256]; if(in==NULL) { diff --git a/client/util.C b/client/util.C index 22217aa363..b03ede6df5 100644 --- a/client/util.C +++ b/client/util.C @@ -53,6 +53,8 @@ double dtime() { } #ifdef _WIN32 +// Goes to sleep for a specified number of seconds +// TODO: allow for fractional second sleep times? void boinc_sleep( int seconds ) { if(seconds<0) { fprintf(stderr, "error: boinc_sleep: negative seconds\n"); @@ -63,6 +65,8 @@ void boinc_sleep( int seconds ) { #else +// Goes to sleep for a specified number of seconds +// TODO: allow for fractional second sleep times? void boinc_sleep( int seconds ) { if(seconds<0) { fprintf(stderr,"error: boinc_sleep: negative seconds\n");