mirror of https://github.com/BOINC/boinc.git
284 lines
9.5 KiB
PHP
284 lines
9.5 KiB
PHP
<?php
|
|
require_once("docutil.php");
|
|
page_head("The BOINC application programming interface (API)");
|
|
echo "
|
|
<p>
|
|
The BOINC API is a set of C++ functions.
|
|
Most of the functions have a C interface,
|
|
so that they can be used from programs written in C and other languages.
|
|
Unless otherwise specified,
|
|
the functions return an integer error code; zero indicates success.
|
|
<p>
|
|
BOINC applications may generate graphics,
|
|
allowing them to provide a screensaver.
|
|
This API is described <a href=graphics.php>here</a>.
|
|
<p>
|
|
BOINC applications may consist of several programs that are
|
|
executed in sequence;
|
|
these are called <b>compound applications</b>.
|
|
This API is described <a href=compound_app.php>here</a>.
|
|
|
|
|
|
<h3>Initialization and termination</h3>
|
|
|
|
<p>
|
|
Applications should
|
|
<a href=diagnostics.php>initialize diagnostics</a>
|
|
before any other BOINC calls.
|
|
<p>
|
|
Initialization for graphical and compound applications
|
|
are described elsewhere (see links above).
|
|
Other applications 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>
|
|
<code>status</code> is nonzero if an error was encountered.
|
|
This call does not return.
|
|
|
|
<h3>Is your application running under the control of the BOINC client?</h3>
|
|
<p>
|
|
BOINC applications can be run in \"standalone\" mode for testing, or under
|
|
the control of the BOINC client. You might want your application to behave differently
|
|
in the two cases. For example you might want to output debugging information if
|
|
the application is running standalone. To determine if the application is
|
|
running in standalone mode or under the control of the BOINC client, call
|
|
<pre>
|
|
int boinc_is_standalone(void);
|
|
</pre>
|
|
This returns non-zero (True) if the application is running standalone, and zero (False) if the application
|
|
is running under the control of the BOINC client.
|
|
|
|
|
|
|
|
<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, int len);
|
|
</pre>
|
|
or
|
|
", html_text("
|
|
int boinc_resolve_filename_s(char *logical_name, std::string& physical_name);
|
|
"), "
|
|
to convert logical file names to physical names.
|
|
For example, instead of
|
|
<pre>
|
|
f = fopen(\"my_file\", \"r\");
|
|
</pre>
|
|
</p>
|
|
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\");
|
|
"), "
|
|
<code>boinc_resolve_filename()</code> doesn't need to be used for temporary files.
|
|
|
|
<h3>I/O wrappers</h3>
|
|
<p>
|
|
Applications should replace fopen() calls with
|
|
<pre>
|
|
boinc_fopen(char* path, char* mode);
|
|
</pre>
|
|
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;
|
|
it also sets the 'close-on-exec' flag.
|
|
|
|
<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>
|
|
int boinc_time_to_checkpoint();
|
|
</pre>
|
|
whenever it reaches a point where it is able to checkpoint.
|
|
If this returns nonzero (True) then
|
|
the application should checkpoint immediately
|
|
(i.e., write the state file and flush all output files),
|
|
then call
|
|
<pre>
|
|
void boinc_checkpoint_completed();
|
|
</pre>
|
|
<code>boinc_time_to_checkpoint()</code> is fast,
|
|
so it can be called frequently (hundreds or thousands of times a second).
|
|
|
|
<h3>Critical sections</h3>
|
|
<pre>
|
|
void boinc_begin_critical_section();
|
|
void boinc_end_critical_section();
|
|
</pre>
|
|
Call these around code segments during which you
|
|
don't want to be suspended or killed by the core client.
|
|
NOTE: this is done automatically while checkpointing.
|
|
|
|
<h3>Atomic file update</h3>
|
|
<p>
|
|
To facilitate atomic checkpoint, an application can write to output and
|
|
state files using the <code>MFILE</code> 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 <code>flush()</code> or <code>close()</code>.
|
|
This lets you write output files and state files more or less atomically.
|
|
|
|
<a name=credit>
|
|
<h3>Credit reporting</h3>
|
|
<p>
|
|
By default, the claimed credit of a result is based on
|
|
the product of its total CPU time and the
|
|
benchmark values obtained by the core client.
|
|
This can produce results that are too low if
|
|
the application uses processor-specific optimizations
|
|
not present in the core client,
|
|
is compiled with different compiler settings,
|
|
or uses a GPU or other non-CPU computing resource.
|
|
To handle such cases, the following functions can be used.
|
|
<pre>
|
|
void boinc_ops_per_cpu_second(double floating_point_ops, double integer_ops);
|
|
</pre>
|
|
This reports the results of an application-specific benchmark,
|
|
expressed as number of floating-point and integer operations per CPU second.
|
|
<pre>
|
|
void boinc_ops_cumulative(double floating_point_ops, double integer_ops);
|
|
</pre>
|
|
This reports the total number of floating-point and integer operations
|
|
since the start of the result.
|
|
It must be called just before boinc_finish(),
|
|
and optionally at intermediate points.
|
|
|
|
<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 <code>fraction_done</code> argument is an estimate of the
|
|
workunit fraction complete (0 to 1).
|
|
This function is fast and can be called frequently.
|
|
The sequence of arguments in successive calls should
|
|
be non-decreasing.
|
|
An application should never 'reset' and start over
|
|
if an error occurs; it should exit with an error code.
|
|
|
|
<p>
|
|
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 {
|
|
int core_version;
|
|
char app_name[256];
|
|
char project_preferences[65536];
|
|
char user_name[256];
|
|
char team_name[256];
|
|
char project_dir[256];
|
|
char boinc_dir[256];
|
|
char wu_name[256];
|
|
char authenticator[256];
|
|
int slot;
|
|
double user_total_credit;
|
|
double user_expavg_credit;
|
|
double team_total_credit;
|
|
double team_expavg_credit;
|
|
HOST_INFO host_info;
|
|
};
|
|
"), "
|
|
to get the following information:
|
|
";
|
|
list_start();
|
|
list_item("core version", "The version number of the core client");
|
|
list_item("app_name", "The application name (from the server's DB)");
|
|
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("slot", "The number of the app's 'slot' (0, 1, ...)");
|
|
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_item("host_info", "A structure describing the host hardware and OS");
|
|
list_end();
|
|
echo "
|
|
<p>
|
|
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.
|
|
|
|
<h3>Non-CPU-intensive periods</h3>
|
|
<p>
|
|
Some applications may have periods when they don't use much CPU time
|
|
(e.g. because they're doing network communication).
|
|
Call the following functions at the start and end of these periods.
|
|
",html_text("
|
|
void boinc_not_using_cpu();
|
|
void boinc_using_cpu();
|
|
"), "
|
|
This allows the BOINC client to schedule other applications
|
|
during these periods.
|
|
<h3>Requesting network connection</h3>
|
|
<p>
|
|
If it appears that there is no physical network connection
|
|
(e.g. gethostbyname() fails for a valid name) then
|
|
<ul>
|
|
<li> Call <code>boinc_need_network()</code>.
|
|
This will alert the user that a network connection is needed.
|
|
<li> Periodically call <code>boinc_network_poll()</code>
|
|
until it returns zero.
|
|
<li> Do whatever communication is needed.
|
|
<li> When done, call <code>boinc_network_done()</code>.
|
|
This enables that hangup of a modem connection, if needed.
|
|
</ul>
|
|
",html_text("
|
|
void boinc_need_network();
|
|
int boinc_network_poll();
|
|
void boinc_network_done();
|
|
"), "
|
|
|
|
Note: this should be enclosed in
|
|
<code>boinc_not_using_cpu() ... boinc_using_cpu()</code>.
|
|
";
|
|
page_tail();
|
|
?>
|