mirror of https://github.com/BOINC/boinc.git
199 lines
6.1 KiB
PHP
199 lines
6.1 KiB
PHP
<?
|
|
require_once("docutil.php");
|
|
page_head("The BOINC application programming interface (API)");
|
|
echo "
|
|
<p>
|
|
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 <a href=graphics.html>separately</a>.
|
|
|
|
<h3>Initialization and termination</h3>
|
|
The application must call
|
|
<pre>
|
|
int boinc_init();
|
|
</pre>
|
|
before calling other BOINC functions or doing I/O.
|
|
<p>
|
|
When the application has completed it must call
|
|
<pre>
|
|
int boinc_finish(int status);
|
|
</pre>
|
|
<tt>status</tt> is nonzero if an error was encountered.
|
|
This call does not return.
|
|
|
|
<h3>Resolving file names</h3>
|
|
Applications that use named input or output files must call
|
|
<pre>
|
|
int boinc_resolve_filename(char *logical_name, char *physical_name);</tt>
|
|
</pre>
|
|
to convert logical file names to physical names.
|
|
For example, instead of
|
|
<pre>
|
|
f = fopen(\"my_file\", \"r\");
|
|
</pre>
|
|
</p>
|
|
the application might use
|
|
<pre>
|
|
char resolved_name[256];
|
|
retval = boinc_resolve_filename(\"my_file\", resolved_name);
|
|
if (retval) fail(\"can't resolve filename\");
|
|
f = fopen(resolved_name, \"r\");
|
|
</pre>
|
|
<tt>boinc_resolve_filename()</tt> doesn't need to be used for temporary files.
|
|
|
|
<h3>Checkpointing</h3>
|
|
|
|
Computations that use a significant amount of time
|
|
per work unit may want to periodically write the current
|
|
state of the computation to disk.
|
|
This is known as <b>checkpointing</b>.
|
|
The state file must include everything required
|
|
to start the computation again at the same place it was checkpointed.
|
|
On startup, the application
|
|
reads the state file to determine where to begin computation.
|
|
If the BOINC client quits or exits,
|
|
the computation can be restarted from the most recent checkpoint.
|
|
<p>
|
|
Frequency of checkpointing is a user preference
|
|
(e.g. laptop users might want to checkpoint infrequently).
|
|
An application must call
|
|
<pre>
|
|
bool boinc_time_to_checkpoint();
|
|
</pre>
|
|
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
|
|
<pre>
|
|
void boinc_checkpoint_completed();
|
|
</pre>
|
|
<tt>boinc_time_to_checkpoint()</tt> is fast
|
|
(it usually makes no system calls),
|
|
so can be called frequently (hundreds or thousands of times a second).
|
|
|
|
<p>
|
|
<tt>boinc_time_to_checkpoint()</tt> performs other time-based functions;
|
|
e.g. it periodically measures the application's CPU time and
|
|
reports it to the core client.
|
|
So, even for applications that don't do checkpointing,
|
|
it should be called at least once a second.
|
|
|
|
<h3>Atomic file update</h3>
|
|
<p>
|
|
To facilitate atomic checkpoint, an application can write to output and
|
|
state files using the <tt>MFILE</tt> class.
|
|
<pre>
|
|
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();
|
|
};
|
|
</pre>
|
|
MFILE buffers data in memory
|
|
and writes to disk only on <tt>flush()</tt> or <tt>close()</tt>.
|
|
This lets you write output files and state files
|
|
more or less atomically.
|
|
|
|
<h3>Signal masking</h3>
|
|
<p>
|
|
The BOINC API implementation uses a periodic signal.
|
|
If this signal is handled during a system call,
|
|
the call may return with an EINTR error,
|
|
in which case it must be called again.
|
|
To avoid dealing with this possibility.
|
|
applications should mask and unmask the clock signal around system calls.
|
|
This is done using
|
|
<pre>
|
|
boinc_mask();
|
|
boinc_unmask()
|
|
</pre>
|
|
|
|
<h3>Communicating with the core client</h3>
|
|
<p>
|
|
The core client GUI displays the percent done of workunits in progress.
|
|
To keep this display current, an application should periodically call
|
|
<pre>
|
|
boinc_fraction_done(double fraction_done);
|
|
</pre>
|
|
The <tt>fraction_done</tt> argument is a rough estimate of the
|
|
workunit fraction complete (0 to 1).
|
|
This function is fast and can be called frequently.
|
|
|
|
<p>
|
|
The following functions get information from the core client;
|
|
this information may be useful for graphics.
|
|
<pre>
|
|
int boinc_get_init_data(APP_INIT_DATA&);
|
|
|
|
struct APP_INIT_DATA {
|
|
char project_preferences[4096];
|
|
char user_name[256];
|
|
char team_name[256];
|
|
double user_total_credit;
|
|
double user_expavg_credit;
|
|
double team_total_credit;
|
|
double team_expavg_credit;
|
|
};
|
|
</pre>
|
|
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("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 "
|
|
<p>
|
|
An application may call
|
|
<pre>
|
|
int boinc_cpu_time(double &cpu_time, double& working_set_size);
|
|
</pre>
|
|
to get its total CPU time
|
|
(i.e., from the beginning of the work unit,
|
|
not just since the last restart).
|
|
This also returns the virtual memory working set size in bytes.
|
|
|
|
|
|
|
|
<h3>Multi-program applications</h3>
|
|
Some applications consist of multiple programs:
|
|
a <b>main program</b> that acts as coordinator,
|
|
and one or more subsidiary programs.
|
|
Each program should use the BOINC API as described above.
|
|
<p>
|
|
Each program should have its own state file;
|
|
the state file of the coordinator program records
|
|
which subsidiary program was last active.
|
|
<p>
|
|
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.
|
|
<p>
|
|
The coordinator must call
|
|
<pre>
|
|
void boinc_child_start();
|
|
</pre>
|
|
prior to forking a child process.
|
|
When the child is done, the coordinator
|
|
must get the child's CPU time, then call
|
|
<pre>
|
|
void boinc_child_done(double total_cpu);
|
|
</pre>
|
|
before forking the next child process.
|
|
";
|
|
page_tail();
|
|
?>
|