mirror of https://github.com/BOINC/boinc.git
Update several files
Signed-off-by: Vitalii Koshura <lestat.de.lionkur@gmail.com>
parent
2ef93ff07a
commit
9143a5cb61
325
CodingStyle.md
325
CodingStyle.md
|
@ -1,201 +1,256 @@
|
|||
[[PageOutline]]
|
||||
# Software and information architecture
|
||||
|
||||
# All languages #all-lang
|
||||
Since I first wrote it in 2002, BOINC has evolved continuously and fairly smoothly.
|
||||
It's now an extremely powerful system,
|
||||
but its code size is fairly small,
|
||||
and the code is malleable (easy to change and extend).
|
||||
I don't see any barriers to BOINC's continued evolution.
|
||||
|
||||
## Code factoring #factoring
|
||||
This success is due in large part to BOINC's architecture.
|
||||
I'll try to articulate some of the principles behind this architecture.
|
||||
|
||||
## Simplicity and brevity
|
||||
|
||||
The most important principle is: make the code as simple as possible.
|
||||
|
||||
To a large extent, shorter is simpler. So:
|
||||
|
||||
* Given two possible implementation, use the shorter one.
|
||||
* If you're writing something new, and it needs a function
|
||||
that might be of general utility,
|
||||
check whether it already exists (in lib/ or html/inc)
|
||||
rather than writing it yourself.
|
||||
* If code is repeated, factor it out and make it into a function.
|
||||
Don't copy and paste code.
|
||||
|
||||
Related principles:
|
||||
|
||||
* If you're adding a new mechanism,
|
||||
try to make it more general than the immediate need,
|
||||
without making it more complicated.
|
||||
* If a function becomes longer than 100 lines or so, split it up.
|
||||
* If a file is becoming 'landfill', split it up.
|
||||
* C++ `.h` files often contain both interface and implementation. Clearly divide these.
|
||||
* If a file is becoming too big,
|
||||
or has a bunch of unrelated stuff, split it up.
|
||||
|
||||
## Code documentation #docs
|
||||
## Uniformity
|
||||
|
||||
* `.cpp` files have a comment at the top saying what's in the file (and perhaps what isn't).
|
||||
Imitate the style and structure of the code that's already there,
|
||||
even if you don't like it.
|
||||
|
||||
## Data architecture
|
||||
|
||||
BOINC stores information in various forms.
|
||||
Guidelines:
|
||||
|
||||
* **MySQL database**:
|
||||
The DB server is a potential performance bottleneck,
|
||||
and there is a code overhead for DB tables
|
||||
(you need to write interface functions in C++ and/or PHP,
|
||||
and you need to write web pages or scripts for editing data).
|
||||
So use the DB only when it's necessary
|
||||
(e.g. because you need indices for large data) and avoid creating new tables.
|
||||
Don't use referential constraints; instead, check for lookups returning null.
|
||||
* **XML fields in DB tables**:
|
||||
Simplify DB design by storing information in XML in DB fields
|
||||
(for example, computing preferences and job file lists).
|
||||
This can eliminate the need for separate tables.
|
||||
* **XML files**:
|
||||
BOINC uses XML format both for internal state (e.g. client_state.xml)
|
||||
and configuration files (cc_config.xml on the client, project.xml on the server).
|
||||
Sometimes we use enclosing tags for multiple items
|
||||
(e.g. \<tasks> in project.xml); sometimes we don't.
|
||||
Either is fine - imitate what's already there.
|
||||
* **PHP and/or C++ code**:
|
||||
If data is used only in PHP, put it in a PHP data structure.
|
||||
You can assume that project admins are able to edit these
|
||||
(e.g. html/project/project.inc).
|
||||
|
||||
## Avoid over-engineering
|
||||
|
||||
If you make a big change to solve a problem that never actually arises,
|
||||
that's over-engineering.
|
||||
Avoid it.
|
||||
|
||||
There are various things (HTTP headers, message boards, XML parsing)
|
||||
where we've had to choose between using someone else's library or doing it ourselves.
|
||||
There are always tradeoffs.
|
||||
If we have something that works and is stable (e.g. XML parsing), leave it.
|
||||
|
||||
In general, big changes should be undertaken only if it's certain
|
||||
that there's going to be a big reward.
|
||||
Big changes introduce bugs, and end up costing more than you think.
|
||||
One exception: occasionally I'll make a change whose only effect
|
||||
is to shorten or simplify the code.
|
||||
|
||||
# Coding style
|
||||
|
||||
## All languages
|
||||
|
||||
### Error codes
|
||||
|
||||
Most functions should return an integer error code.
|
||||
Nonzero means error. See [lib/error_numbers.h](https://github.com/BOINC/boinc/lib/error_numbers.h) for a list of error codes.
|
||||
Exceptions:
|
||||
* PHP database access functions, which use the mysql_* convention
|
||||
that zero means error, and you call mysql_error() or mysql_error_string() to find details.
|
||||
* Functions that return whether a condition holds; such functions should have
|
||||
descriptive names like `is_job_finished()`.
|
||||
* Functions that return a number or other type, and for which no errors are possible.
|
||||
|
||||
Calls to functions that return an error code should check the code.
|
||||
Generally they should return non-zero on error, e.g.:
|
||||
```
|
||||
retval = blah();
|
||||
if (retval) return retval;
|
||||
```
|
||||
|
||||
### Code documentation
|
||||
|
||||
* All files have a comment at the top saying what's in the file (and perhaps what isn't).
|
||||
* Functions are preceded by a comment saying what they do.
|
||||
* structs and classes are preceded by a comment saying what they are.
|
||||
* structs and classes are preceded by a comment saying what they represent.
|
||||
|
||||
## Naming #naming
|
||||
### Naming
|
||||
|
||||
* Names should be descriptive without being verbose (local variables names may be short).
|
||||
* Class and type names, and `#defined` symbols, are all upper case, with underscores to separate words.
|
||||
* Variable and function names are all lower case, with underscores to separate words.
|
||||
* No mixed case names.
|
||||
|
||||
## Indentation #indent
|
||||
### Indentation
|
||||
|
||||
* Each level of indentation is 4 spaces (not a tab).
|
||||
* Multi-line function call:
|
||||
|
||||
func(
|
||||
blah, blah, blah, blah, blah,
|
||||
blah, blah, blah, blah, blah
|
||||
);
|
||||
|
||||
```
|
||||
func(
|
||||
blah, blah, blah, blah, blah,
|
||||
blah, blah, blah, blah, blah
|
||||
);
|
||||
```
|
||||
* `switch` statements: `case` labels are at same indent level as `switch`
|
||||
```
|
||||
switch (foo) {
|
||||
case 1:
|
||||
...
|
||||
break;
|
||||
case 2:
|
||||
...
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
switch (foo) {
|
||||
case 1:
|
||||
...
|
||||
break;
|
||||
case 2:
|
||||
...
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
## Constants #constants
|
||||
### Constants
|
||||
|
||||
* There should be few numeric constants in code. Generally they should be `#define`s.
|
||||
|
||||
## Braces #braces
|
||||
### Braces (C++ and PHP)
|
||||
|
||||
* Opening curly brace goes at end of line (not next line):
|
||||
|
||||
if (foobar) {
|
||||
...
|
||||
} else if (blah) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
if (foobar) {
|
||||
...
|
||||
} else if (blah) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
* Always use curly braces on multi-line `if` statements.
|
||||
|
||||
if (foo)
|
||||
return blah; // WRONG
|
||||
|
||||
```
|
||||
if (foo)
|
||||
return blah; // WRONG
|
||||
```
|
||||
* 1-line `if()` statements are OK:
|
||||
```
|
||||
if (foo) return blah;
|
||||
```
|
||||
|
||||
if (foo) return blah;
|
||||
### Comments and #ifdefs
|
||||
|
||||
* For C++ and PHP, use `*` for all comments.
|
||||
* End multi-line comments with an empty comment line, e.g.
|
||||
```
|
||||
// This function does blah blah
|
||||
// Call it when blah blah
|
||||
//
|
||||
function foo() {
|
||||
}
|
||||
```
|
||||
|
||||
## C++ specific
|
||||
|
||||
## Comments and #ifdefs #comments
|
||||
* C++ `.h` files often contain both interface and implementation. Clearly divide these.
|
||||
|
||||
* Use `///` for all comments. The documentation is generated using Doxygen, so you should have a look at this example:
|
||||
### Includes
|
||||
|
||||
* A `.cpp` file should have the minimum set of #includes to get that particular file to compile
|
||||
(e.g. the includes needed by `foo.cpp` should be in `foo.cpp`, not `foo.h`).
|
||||
* For readability, includes should be ordered from general (`<stdio.h>`) to specific (`foo.h`).
|
||||
However, this order shouldn't matter.
|
||||
|
||||
/// Brief description for class test.
|
||||
### Extern declarations
|
||||
|
||||
/// A more elaborate description for class test,
|
||||
/// could be more than one line.
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
* `foo.h` should have `extern` declarations for all public functions and variables in `foo.cpp`.
|
||||
There should be no `extern` statements in `.cpp` files.
|
||||
|
||||
/// A constructor.
|
||||
|
||||
/// A more elaborate description of the constructor.
|
||||
Test();
|
||||
|
||||
/// A destructor.
|
||||
/// A more elaborate description of the destructor.
|
||||
~Test();
|
||||
|
||||
/// a normal member taking two arguments and returning an integer value.
|
||||
/// @param a an integer argument.
|
||||
/// @param s a constant character pointer.
|
||||
/// @see Test()
|
||||
/// @see ~Test()
|
||||
/// @see testMeToo()
|
||||
/// @see publicVar()
|
||||
/// @return The test results
|
||||
int testMe(int a,const char *s);
|
||||
|
||||
/// A pure virtual member.
|
||||
/// @see testMe()
|
||||
/// @param c1 the first argument.
|
||||
/// @param c2 the second argument.
|
||||
virtual void testMeToo(char c1,char c2) = 0;
|
||||
|
||||
/// a public variable.
|
||||
|
||||
/// Details.
|
||||
int publicVar;
|
||||
|
||||
/// a function variable.
|
||||
|
||||
/// Details.
|
||||
int (*handler)(int a,int b);
|
||||
};
|
||||
|
||||
|
||||
|
||||
* Comment out blocks of code as follows:
|
||||
|
||||
#if 0
|
||||
...
|
||||
#endif
|
||||
|
||||
|
||||
# C++ specific #cpp
|
||||
|
||||
## Includes #includes
|
||||
|
||||
* A `.cpp` file should have the minimum set of #includes to get that particular file to compile (e.g. the includes needed by `foo.cpp` should be in `foo.cpp`, not `foo.h`).
|
||||
* `foo.cpp` should include `foo.h` first; after that, includes should be ordered from general (`<stdio.h>`) to specific (`shmem.h`).
|
||||
|
||||
## Extern declarations #extern
|
||||
|
||||
* `foo.h` should have `extern` declarations for all public functions and variables in `foo.cpp` There should be no `extern` statements in `.cpp` files.
|
||||
|
||||
## Use of static #static
|
||||
### Use of static
|
||||
|
||||
* If a function or variable is used in only one file, declare it `static`.
|
||||
|
||||
## Things to avoid unless there's a truly compelling reason: #try-avoid
|
||||
### Things to avoid unless there's a compelling reason:
|
||||
|
||||
* Operator or function overloading.
|
||||
* Operator and function overloading.
|
||||
* Templates.
|
||||
* Stream I/O; use printf() and scanf().
|
||||
|
||||
## Things to avoid #avoid
|
||||
### Things to avoid
|
||||
|
||||
* Use `typedef` (not `#define`) to define types.
|
||||
* Don't use `memset()` or `memcpy()` to initialize or copy classes that are non-C compatible. Write a default constructor and a copy constructor instead.
|
||||
* Don't use `memset()` or `memcpy()` to initialize or copy classes that are non-C compatible.
|
||||
Write a default constructor and a copy constructor instead.
|
||||
* Dynamic memory allocation. Functions shouldn't return pointers to malloc'd items.
|
||||
|
||||
## Error codes #error-codes
|
||||
|
||||
* (Almost) all functions should return an integer error code. Nonzero means error. See [lib/error_numbers.h](source:boinc/lib/error_numbers.h) for a list of error codes.
|
||||
* Calls to functions that return an error code should check the code. Generally they should return non-zero on error, e.g.:
|
||||
|
||||
retval = blah();
|
||||
if (retval) return retval;
|
||||
|
||||
|
||||
## Structure definitions #structs
|
||||
|
||||
|
||||
struct FOO {
|
||||
...
|
||||
};
|
||||
### Structure definitions
|
||||
|
||||
```
|
||||
struct FOO {
|
||||
...
|
||||
};
|
||||
```
|
||||
You can then declare variables as:
|
||||
```
|
||||
FOO x;
|
||||
```
|
||||
|
||||
FOO x;
|
||||
### Comments
|
||||
Comment out blocks of code as follows:
|
||||
```
|
||||
#if 0
|
||||
...
|
||||
#endif
|
||||
```
|
||||
## PHP specific
|
||||
|
||||
|
||||
# PHP specific #php
|
||||
|
||||
## HTML #html
|
||||
### HTML
|
||||
|
||||
PHP scripts should output "HTML 4.01 Transitional".
|
||||
The HTML should pass the [validator](W3C)(http://validator.w3.org/).
|
||||
The HTML should pass the [W3C validator](http://validator.w3.org/).
|
||||
This means, e.g., you must have quotes around attributes
|
||||
that have non-alpha characters in them.
|
||||
However, all-alpha attributes need not have quotes,
|
||||
and tags like <br> and <p> need not be closed.
|
||||
and tags like \<br> and \<p> need not be closed.
|
||||
|
||||
The HTML need not be XHTML.
|
||||
|
||||
This means no self-closing tags like `<br />`.
|
||||
|
||||
## Getting POST and GET data #post-and-get
|
||||
### Getting POST and GET data
|
||||
|
||||
Do not access `$_POST` or `$_GET` directly.
|
||||
Use `get_int()`, `get_str()`, `post_int()` and `post_str()` (from `util.inc`) to get POST and GET data.
|
||||
These undo the effects of PHP magic quotes.
|
||||
|
||||
## Database access #database-access
|
||||
### Database access
|
||||
* Use the [database abstraction layer](PhpDb).
|
||||
* If a POST or GET value will be used in a database query, use `BoincDb::escape_string` to escape it.
|
||||
|
||||
|
|
|
@ -1,79 +1,83 @@
|
|||
# Running the client under Visual Studio
|
||||
# Debugging the BOINC Windows client
|
||||
|
||||
## Running the client under Visual Studio
|
||||
|
||||
If you've installed BOINC in "secure mode",
|
||||
and later you run the client directly (or from Visual Studio)
|
||||
you'll get 0xc0000142 errors each time the client tries to start an app.
|
||||
|
||||
To fix this, delete the file *client_auth.xml* in your BOINC data directory.
|
||||
To fix this, delete the file **client_auth.xml** in your BOINC data directory.
|
||||
|
||||
# Symbol Files
|
||||
## Symbol Files
|
||||
Symbol files are used by various Windows debugging engines to match up memory addresses to symbol names. Symbol names are names of variables, functions, and subroutines that a developer has named a piece of code before the compilation process.
|
||||
|
||||
Symbol files for BOINC can be found on http://boinc.berkeley.edu/symstore/
|
||||
Symbol files for BOINC can be found on https://boinc.berkeley.edu/symstore/
|
||||
|
||||
You can download them and save them in a temporary directory. Next open a windows command line window (Start->Run, type cmd and click OK), then navigate to the directory you saved the files in.
|
||||
|
||||
Then type *unpack *.pd_ *.pdb* and press Enter. This will decompress the files to their normal size. [[br]]
|
||||
Then type **unpack *.pd_ *.pdb** and press Enter. This will decompress the files to their normal size.
|
||||
|
||||
|
||||
The decompressed files should be stored in the same directory as the BOINC executables are in.
|
||||
|
||||
# Crashes
|
||||
## Crashes
|
||||
If either BOINC or the BOINC Manager crash, (they unexpectedly stop running or disappear), there should be some diagnostic information recorded in stderrdae.txt for BOINC and stderrgui.txt for the BOINC Manager.
|
||||
|
||||
The diagnostic information we are looking for is called a call stack which is described below.
|
||||
|
||||
# Call stacks
|
||||
## Call stacks
|
||||
Call stacks help us identify where the problem is by telling us which file and what line number in the source code the error occurred in.
|
||||
|
||||
Here is an example of a good call stack:
|
||||
|
||||
|
||||
```
|
||||
***UNHANDLED EXCEPTION****
|
||||
Reason: Access Violation (0xc0000005) at address 0x00411A87 write attempt to address 0x00000000
|
||||
|
||||
1: 06/08/05 15:07:01
|
||||
1: c:\boincsrc\main\boinc\client\cs_benchmark.c(310) +8 bytes (CLIENT_STATE::cpu_benchmarks_poll)
|
||||
1: c:\boincsrc\main\boinc\client\client_state.c(431) +0 bytes (CLIENT_STATE::do_something)
|
||||
Reason: Access Violation (0xc0000005) at address 0x00411A87 write attempt to address 0x00000000
|
||||
|
||||
1: 06/08/05 15:07:01
|
||||
1: c:\boincsrc\main\boinc\client\cs_benchmark.c(310) +8 bytes (CLIENT_STATE::cpu_benchmarks_poll)
|
||||
1: c:\boincsrc\main\boinc\client\client_state.c(431) +0 bytes (CLIENT_STATE::do_something)
|
||||
```
|
||||
|
||||
Here is an example of a bad call stack:
|
||||
|
||||
|
||||
```
|
||||
***UNHANDLED EXCEPTION****
|
||||
Reason: Access Violation (0xc0000005) at address 0x7C34FEDC read attempt to address 0x05595D90
|
||||
Reason: Access Violation (0xc0000005) at address 0x7C34FEDC read attempt to address 0x05595D90
|
||||
|
||||
1: 06/08/05 00:36:54
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: 06/08/05 00:36:54
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
1: SymGetLineFromAddr(): GetLastError = 126
|
||||
```
|
||||
|
||||
|
||||
# Extracting call stacks
|
||||
## Extracting call stacks
|
||||
|
||||
If we need a call stack to help solve a problem that doesn't manifest itself as a crash you can still extract a call stack from a running program using some freeware tools Microsoft publishes called Debugging Tools for Windows.
|
||||
|
||||
The Debugging Tools for Windows can be found on [Tools for Windows](Debugging)(http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx)
|
||||
The Debugging Tools for Windows can be found on [Debugging Tools for Windows](http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx)
|
||||
|
||||
Once these tools are installed on your machine and the symbol files are extracted to the BOINC installation directory you can run 'WinDBG.exe' and attach to the 'BOINC.exe' process through the file menu to begin your debugging session. Once 'WinDBG.exe' has attached itself to 'BOINC.exe' you can view the call stack by typing 'kb' in the command window and then hitting enter.
|
||||
|
||||
Here is an example of the output 'WinDBG.exe' displays when it dumps a call stack:
|
||||
|
||||
|
||||
|
||||
ChildEBP RetAddr Args to Child
|
||||
0012fafc 7c821364 77e42439 00000000 0012fb40 ntdllKiFastSystemCallRet
|
||||
0012fb00 77e42439 00000000 0012fb40 ffffff4a ntdllNtDelayExecution+0xc
|
||||
0012fb68 77e424b7 00000064 00000000 0012fee0 kernel32SleepEx+0x68
|
||||
```
|
||||
ChildEBP RetAddr Args to Child
|
||||
0012fafc 7c821364 77e42439 00000000 0012fb40 ntdll!KiFastSystemCallRet
|
||||
0012fb00 77e42439 00000000 0012fb40 ffffff4a ntdll!NtDelayExecution+0xc
|
||||
0012fb68 77e424b7 00000064 00000000 0012fee0 kernel32!SleepEx+0x68
|
||||
*** WARNING: Unable to verify checksum for C:\Program Files\BOINC\boinc.exe
|
||||
0012fb78 00430206 00000064 00424b3c 9999999a kernel32!Sleep+0xf
|
||||
0012fb80 00424b3c 9999999a 3fb99999 00000002 boinc!boinc_sleep+0x16 [@ 251](c:\boincsrc\main\boinc_public\lib\util.c)
|
||||
0012fee0 00424f87 0012fefc 9999999a 3fb99999 boinc!NET_XFER_SET::do_select+0x26c [@ 319](c:\boincsrc\main\boinc_public\client\net_xfer.c)
|
||||
0012fef4 00407a2d 00000000 00000000 7c34f6f4 boinc!NET_XFER_SET::net_sleep+0x17 [@ 245](c:\boincsrc\main\boinc_public\client\net_xfer.c)
|
||||
0012ff18 004225dd 9999999a 3fb99999 00000000 boinc!CLIENT_STATE::net_sleep+0x7d [@ 369](c:\boincsrc\main\boinc_public\client\client_state.c)
|
||||
0012ff38 0042276f 7ffdf000 00000000 00000000 boinc!boinc_main_loop+0x7d [@ 331](c:\boincsrc\main\boinc_public\client\main.c)
|
||||
0012ff60 00431c0d 00000002 017acfc0 016def68 boinc!main+0x11f [@ 412](c:\boincsrc\main\boinc_public\client\main.c)
|
||||
0012ffc0 77e523cd 00000000 00000000 7ffdf000 boinc!mainCRTStartup+0x143 [@ 398](f:\vs70builds\3077\vc\crtbld\crt\src\crtexe.c)
|
||||
0012fff0 00000000 00431aca 00000000 78746341 kernel32BaseProcessStart+0x23
|
||||
|
||||
0012fb78 00430206 00000064 00424b3c 9999999a kernel32!Sleep+0xf
|
||||
0012fb80 00424b3c 9999999a 3fb99999 00000002 boinc!boinc_sleep+0x16 [c:\boincsrc\main\boinc_public\lib\util.c @ 251]
|
||||
0012fee0 00424f87 0012fefc 9999999a 3fb99999 boinc!NET_XFER_SET::do_select+0x26c [c:\boincsrc\main\boinc_public\client\net_xfer.c @ 319]
|
||||
0012fef4 00407a2d 00000000 00000000 7c34f6f4 boinc!NET_XFER_SET::net_sleep+0x17 [c:\boincsrc\main\boinc_public\client\net_xfer.c @ 245]
|
||||
0012ff18 004225dd 9999999a 3fb99999 00000000 boinc!CLIENT_STATE::net_sleep+0x7d [c:\boincsrc\main\boinc_public\client\client_state.c @ 369]
|
||||
0012ff38 0042276f 7ffdf000 00000000 00000000 boinc!boinc_main_loop+0x7d [c:\boincsrc\main\boinc_public\client\main.c @ 331]
|
||||
0012ff60 00431c0d 00000002 017acfc0 016def68 boinc!main+0x11f [c:\boincsrc\main\boinc_public\client\main.c @ 412]
|
||||
0012ffc0 77e523cd 00000000 00000000 7ffdf000 boinc!mainCRTStartup+0x143 [f:\vs70builds\3077\vc\crtbld\crt\src\crtexe.c @ 398]
|
||||
0012fff0 00000000 00431aca 00000000 78746341 kernel32!BaseProcessStart+0x23
|
||||
```
|
||||
|
||||
Warning: You may need to add the BOINC directory to 'WinDBG.exe' symbol search path from the File menu in order to get a valid call stack.
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
# Computing preferences, version 2
|
||||
|
||||
This document describes a new system for "computing preferences" in BOINC.
|
||||
This system lets users express, as a set of logical rules,
|
||||
how resource usage settings vary as a function of external factors.
|
||||
|
||||
Note: the motivation for this is discussed [here](PrefsRemodel); that document is otherwise deprecated.
|
||||
|
||||
The goals of this system include:
|
||||
|
||||
* Generality: allow the expression of any preferences.
|
||||
* Extensibility: make it possible to add new external factors
|
||||
(such as the current cost of electricity) without modifying the client.
|
||||
|
||||
## Static and dynamic settings
|
||||
|
||||
Various "settings" control and limit
|
||||
BOINC's use of computing, memory, storage, and network communication.
|
||||
|
||||
"Dynamic" settings can change in response to factors external to BOINC
|
||||
(such as time of day, non-BOINC CPU usage, etc.).
|
||||
These include:
|
||||
|
||||
### cpu_usage_limit
|
||||
CPU throttling fraction (0..1)
|
||||
### dont_use_cpu
|
||||
don't run any jobs
|
||||
### dont_use_gpu [type][device]
|
||||
don't run GPU jobs. Optional GPU type (nvidia, amd, intel) and device #.
|
||||
### dont_do_file_xfer
|
||||
don't do file xfers
|
||||
### dont_use_network
|
||||
don't do any network communication at all
|
||||
### max_bytes_sec_down
|
||||
max download data rate
|
||||
### max_bytes_sec_up
|
||||
max upload data rate
|
||||
### max_ncpus
|
||||
max # of CPUs to use
|
||||
### max_ncpus_pct
|
||||
max % of CPUs to use
|
||||
### ram_max_used_frac
|
||||
max fraction of RAM to use
|
||||
|
||||
"Static" settings don't vary over time.
|
||||
These include:
|
||||
|
||||
### confirm_before_connecting
|
||||
ask before creating network connection
|
||||
### cpu_scheduling_period
|
||||
time between rescheduling jobs
|
||||
### disk_max_used_gb
|
||||
max disk usage
|
||||
### disk_max_used_pct
|
||||
max % of disk to use
|
||||
### disk_min_free_gb
|
||||
min free disk space
|
||||
### dont_verify_images
|
||||
don't verify image files
|
||||
### hangup_if_dialed
|
||||
hang up modem connection when done
|
||||
### leave_apps_in_memory
|
||||
suspend (rather than quit) non-running jobs
|
||||
### work_buf_additional_days
|
||||
when request work, ask for this much beyond min
|
||||
### work_buf_min_days
|
||||
keep at least this much work
|
||||
|
||||
The XML representation of setting groups:
|
||||
```
|
||||
<settings>
|
||||
[ <max_ncpus_pct>x</max_ncpus_pct> ]
|
||||
...
|
||||
</settings>
|
||||
|
||||
<static_settings>
|
||||
[ <disk_max_used_gb>x</disk_max_used_gb> ]
|
||||
...
|
||||
</static_settings>
|
||||
```
|
||||
|
||||
All elements are optional;
|
||||
a group can define some elements but not others.
|
||||
If A and B are setting groups, the "overlay of A on B" is defined as
|
||||
A together with any elements in B that are not defined in A.
|
||||
|
||||
## Prefs dictionary
|
||||
|
||||
External factors are stored in a "prefs dictionary",
|
||||
which is a name -> value map.
|
||||
The following entries are maintained by the BOINC client:
|
||||
|
||||
### idle_time
|
||||
# seconds since last user input
|
||||
### time
|
||||
time of day
|
||||
### on_batteries
|
||||
system is running on batteries
|
||||
### app_name
|
||||
whether a given application is running
|
||||
### non_boinc_cpu_usage
|
||||
fraction of CPU used for non-BOINC apps recently
|
||||
### daily_xfer_mb_N
|
||||
number of MB of file transfer in last N days
|
||||
### on_ac_power
|
||||
system is running on AC power (Android)
|
||||
### on_usb_power
|
||||
system is running on USB power (Android)
|
||||
### wifi_online
|
||||
WiFi network connection exists (Android)
|
||||
### user_active
|
||||
system thinks user is active (Android)
|
||||
### battery_charge
|
||||
battery charge level, 0..100 (Android)
|
||||
### battery_temperature
|
||||
battery temperature, Centigrade (Android)
|
||||
|
||||
In addition, external programs can add items to the dictionary,
|
||||
and update their values, via GUI RPCs.
|
||||
Hence the prefs system is extensible without modifying the client.
|
||||
|
||||
Values are doubles; Booleans are encoded as 0/1.
|
||||
|
||||
## Preference terms
|
||||
|
||||
Preferences are expressed in terms of "conditions" that are the conjunction
|
||||
of a set of "terms".
|
||||
|
||||
Each term is an assertion about a dictionary item.
|
||||
There are three types of assertions:
|
||||
|
||||
* "greater than": the value of the item is greater than a number X.
|
||||
* "nonzero": the value of the item is nonzero (i.e. Boolean true)
|
||||
* "time range": the value of the item (usually "time") lies in a set of day/week intervals.
|
||||
* "app_running": an app of the given name is running
|
||||
|
||||
A term can also have a "not" flag, which if set reverses its sense.
|
||||
|
||||
The XML representation of a term:
|
||||
```
|
||||
<term>
|
||||
<item>item-name</item>
|
||||
<type>x</type> // greater_than, nonzero, time_range, app_running
|
||||
[<thresh>x</thresh>] // if greater than
|
||||
[<time_range>...</time_range>] // if time range
|
||||
</term>
|
||||
```
|
||||
The representation of a time range:
|
||||
```
|
||||
<time_range>
|
||||
<start>x</start>
|
||||
<end>y</end>
|
||||
[
|
||||
<day_of_week>
|
||||
<day>x</day> // 0 .. 6
|
||||
<start>x</start>
|
||||
<end>y</end>
|
||||
</day_of_week>
|
||||
... other days of week
|
||||
]
|
||||
</time_range>
|
||||
```
|
||||
x and y are hours (0..24).
|
||||
The first start/end apply to all days.
|
||||
This is overwritten by day_of_week elements.
|
||||
|
||||
## Conditions
|
||||
|
||||
A "condition" is the conjunction ("and") of a set of terms, possibly negated.
|
||||
XML format:
|
||||
```
|
||||
<condition>
|
||||
[<not/>]
|
||||
<term> ... </term>
|
||||
...
|
||||
</condition>
|
||||
```
|
||||
|
||||
The conjunction of an empty set of terms is true.
|
||||
|
||||
## Clauses
|
||||
|
||||
A "clause" is the combination of a condition and a dynamic setting group.
|
||||
XML format:
|
||||
```
|
||||
<clause>
|
||||
<condition> ... </condition>
|
||||
<settings> ... </settings>
|
||||
<clause>
|
||||
```
|
||||
|
||||
## Preference sets
|
||||
|
||||
A "preference set" is a list of clauses.
|
||||
XML format:
|
||||
```
|
||||
<computing_prefs>
|
||||
<clause> ... </clause>
|
||||
...
|
||||
<static_settings> ... <static_settings>
|
||||
</computing_prefs>
|
||||
```
|
||||
|
||||
The semantics are as follows.
|
||||
X is a dynamic setting group, initially empty.
|
||||
The clauses are processed in order.
|
||||
For each clause C, evaluate its condition.
|
||||
If the condition is true, overlay X with C's dynamic settings.
|
||||
At the conclusion, X is the dynamic settings to be enforced by the client.
|
||||
|
||||
## Example
|
||||
|
||||
The following says to use all the CPUs and 90% of the RAM if
|
||||
there has been no user input in 3 minutes,
|
||||
and to use 50% of the CPUs and 50% of the RAM otherwise:
|
||||
```
|
||||
<computing_prefs>
|
||||
<clause>
|
||||
<settings>
|
||||
<max_ncpus_pct>50</max_ncpus_pct>
|
||||
<ram_max_used_frac>.5</ram_max_used_frac>
|
||||
</settings>
|
||||
</clause>
|
||||
<clause>
|
||||
<condition>
|
||||
<term>
|
||||
<type>greater_than</type>
|
||||
<item>idle_time</time>
|
||||
<value>180</value>
|
||||
</term>
|
||||
</condition>
|
||||
<settings>
|
||||
<max_ncpus_pct>100</max_ncpus_pct>
|
||||
<ram_max_used_frac>.9</ram_max_used_frac>
|
||||
</settings>
|
||||
</clause>
|
||||
</computing_prefs>
|
||||
```
|
Loading…
Reference in New Issue