require_once("docutil.php"); page_head("The BOINC application programming interface (API)"); echo "
The BOINC API is a set of C++ functions. Unless otherwise specified, the functions return an integer error code; zero indicates success. On an error return, the application should exit with that status. The BOINC graphics API is described separately.
int boinc_init(bool standalone=false);before calling other BOINC functions or doing I/O. If
standalone
is true,
the application will function independently of the BOINC core client
(this is useful for testing).
When the application has completed it must call
int boinc_finish(int status);
status
is nonzero if an error was encountered.
This call does not return.
int boinc_resolve_filename(char *logical_name, char *physical_name, int len);or ", html_text(" int boinc_resolve_filename(char *logical_name, string& physical_name); "), " to convert logical file names to physical names. For example, instead of
f = fopen(\"my_file\", \"r\");the application might use ", html_text(" string resolved_name; retval = boinc_resolve_filename(\"my_file\", resolved_name); if (retval) fail(\"can't resolve filename\"); f = fopen(resolved_name.c_str(), \"r\"); "), "
boinc_resolve_filename()
doesn't need to be used for temporary files.
Applications should replace fopen() calls with
boinc_fopen(char* path, char* mode);This deals with platform-specific problems. On Windows, where security and indexing programs can briefly lock files, boinc_fopen() does several retries at 1-second intervals. On Unix, where signals can cause fopen() to fail with EINTR, boinc_fopen checks for this and does a few retries.
Frequency of checkpointing is a user preference (e.g. laptop users might want to checkpoint infrequently). An application must call
bool boinc_time_to_checkpoint();whenever it reaches a point where it is able to checkpoint. If this returns true, the application should write the state file and flush all output files, then call
void boinc_checkpoint_completed();
boinc_time_to_checkpoint()
is fast,
so it can be called frequently (hundreds or thousands of times a second).
To facilitate atomic checkpoint, an application can write to output and
state files using the MFILE
class.
class MFILE { public: int open(char* path, char* mode); int _putchar(char); int puts(char*); int printf(char* format, ...); size_t write(const void* buf, size_t size, size_t nitems); int close(); int flush(); };MFILE buffers data in memory and writes to disk only on
flush()
or close()
.
This lets you write output files and state files more or less atomically.
The core client GUI displays the percent done of workunits in progress. To keep this display current, an application should periodically call
boinc_fraction_done(double fraction_done);The
fraction_done
argument is a rough estimate of the
workunit fraction complete (0 to 1).
This function is fast and can be called frequently.
The following functions get information from the core client; this information may be useful for graphics. ", html_text(" int boinc_get_init_data(APP_INIT_DATA&); struct APP_INIT_DATA { char project_preferences[4096]; char user_name[256]; char team_name[256]; char project_dir[256]; char boinc_dir[256]; char wu_name[256]; char authenticator[256]; double user_total_credit; double user_expavg_credit; double team_total_credit; double team_expavg_credit; }; "), " to get the following information: "; list_start(); list_item("project_preferences", "An XML string containing the user's project-specific preferences."); list_item("user_name", " the user's 'screen name' on this project."); list_item("team_name", " the user's team name, if any."); list_item("project_dir", "absolute path of project directory"); list_item("boinc_dir", "absolute path of BOINC root directory"); list_item("wu_name", "name of workunit being processed"); list_item("authenticator", "user's authenticator for this project"); list_item("user_total_credit", " user's total work for this project."); list_item("user_expavg_credit", " user's recent average work per day."); list_item("team_total_credit", " team's total work for this project."); list_item("team_expavg_credit", " team's recent average work per day."); list_end(); echo "
An application may call ", html_text(" int boinc_wu_cpu_time(double &cpu_time); "), "to get its total CPU time (from the beginning of the work unit, not just since the last restart). This excludes CPU time used to render graphics.
'Trickle messages' allow applications with long (multi-day) work units to communicate with the server during execution. This mechanism is described here.
Each program should have its own state file; the state file of the coordinator program records which subsidiary program was last active.
To correctly implement fraction done, the main program should pass information to subsidiary programs (perhaps as command-line arguments) indicating the starting and ending fractions for that program.
The coordinator must call
void boinc_child_start();prior to forking a child process. When the child is done, the coordinator must get the child's CPU time, then call
void boinc_child_done(double total_cpu);before forking the next child process. "; page_tail(); ?>