diff --git a/checkin_notes b/checkin_notes index e268b8ac3b..a890f06b6e 100755 --- a/checkin_notes +++ b/checkin_notes @@ -15862,3 +15862,8 @@ Daniel 2004-08-04 client/ hostinfo_unix.C +David 5 Aug 2004 + - Kinder, gentler messages when need work + + client/ + cs_scheduler.C diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 00dfac6def..0d57c32ab1 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -451,13 +451,12 @@ bool CLIENT_STATE::scheduler_rpc_poll() { } else if (!(exit_when_idle && contacted_sched_server) && urgency != DONT_NEED_WORK) { if (urgency == NEED_WORK) { msg_printf(NULL, MSG_INFO, - "CPU scheduler starvation within %.2f days; " - "requesting more work", + "May run out of work in %.2f days; requesting more", global_prefs.work_buf_min_days ); } else if (urgency == NEED_WORK_IMMEDIATELY) { msg_printf(NULL, MSG_INFO, - "CPU scheduler starvation imminent; requesting more work" + "Insufficient work; requesting more" ); } scheduler_op->init_get_work(); diff --git a/doc/compound_app.php b/doc/compound_app.php index 843ec3cb02..deb78d605b 100644 --- a/doc/compound_app.php +++ b/doc/compound_app.php @@ -8,10 +8,10 @@ echo " A compound application consists of a main program and one or more worker programs. -The main program executes the worker programs in sequence. -It maintains a state file that records -which subsidiary programs have already completed. -It assigns to each worker application +The main program executes the worker programs in sequence, +and maintains a 'main state file' that records +which worker programs have completed. +The main program assigns to each worker application a subrange of the overall 'fraction done' range of 0..1. For example, if there are two subsidiary applications with equal runtime, @@ -22,41 +22,104 @@ would have range 0.5 to 1.
The BOINC API provides a number of functions, and in developing a compound application you must decide -whether these -how these functions are to be divided between -the main and worker programs. +whether these functions are to be performed by +the main or worker program. +The functions are represented by flags in the BOINC_OPTIONS structure. +Each flag must be set in either the main or worker programs, +but not both.
struct BOINC_OPTIONS { + bool main_program; + bool check_heartbeat; + bool handle_trickle_ups; + bool handle_trickle_downs; + bool handle_process_control; + bool handle send_status_msgs; + bool direct_process_action; }; --The main program logic is as follows: + +int boinc_init_options(BOINC_OPTIONS&);
-boinc_init_options(...) -read state file +"; +list_start(); +list_item("main_program", + "Set this in the main program." +); +list_item("check_heartbeat", + "If set, the program monitors 'heartbeat' messages from the core client. + If the heartbeat stops, the result depends on the direct_process_action + flag (see below)." +); +list_item("handle_trickle_ups", + "If set, the program can send trickle-up messages." +); +list_item("handle_trickle_downs", + "If set, the program can receive trickle-down messages." +); +list_item("handle_process_control", + "If set, the program will handle 'suspend', 'resume', and 'quit' + messages from the core client. + The action depends on the direct_process_action flag." +); +list_item("send_status_msgs", + "If set, the program will report its CPU time and fraction + done to the core client. Set in worker programs." +); +list_item("direct_process_action", + "If set, the program will respond to quit messages and heartbeat + failures by exiting, and will respond to suspend and resume + messages by suspending and resuming. + Otherwise, these events will result in changes to + the BOINC_STATUS structure, + which can be polled using boinc_get_status()." +); ++Typical main program logic is: +
+BOINC_OPTIONS options; + +options.main_program = true; +... +boinc_init_options(options) +read main state file for each remaining subsidiary application: - boinc_parse_init_data_file() aid.fraction_done_start = x aid.fraction_done_end = y boinc_write_init_data_file() run the app - write state file -exit(0) + wait for the app to finish + poll + write main state file + if last app: + break + boinc_parse_init_data_file() // reads CPU time from app_init.xml file +boinc_finish()where x and y are the appropriate fraction done range limits.-Each subsidiary program should use the normal BOINC API, -including calls to boinc_fraction_done() -with values ranging from 0 to 1. +Typical worker program logic is: +
+BOINC_OPTIONS options; + +options.main_program = false; +... +boinc_init_options(options); +... +do work, calling boinc_fraction_done() with values from 0 to 1, +and boinc_time_to_checkpoint(), occasionally +... +boinc_finish(); // this writes final CPU time to app_init.xml file + +If the graphics is handled in a program that runs concurrently with -the subsidiary applications, it can call -
boinc_init(false)
to designate it as a non-worker thread. -This program can then use the BOINC graphics API, but not the API -calls that handle checkpointing and status updates to BOINC. -It must callboinc_finish(false)
to terminate. +the worker applications, it must also call +boinc_init_options()
, typically with all options false, +thenboinc_init_graphics()
, +and eventuallyboinc_finish()
. ";