Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client: add sporadic app feature #5385

Merged
merged 16 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion android/buildAndroidBOINC-CI.sh
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ vcpkgDir()
echo $vcpkg_dir
}

list_apps_name="boinc_gahp uc2 ucn multi_thread sleeper worker wrapper wrappture_example fermi"
list_apps_name="boinc_gahp uc2 ucn multi_thread sleeper sporadic worker wrapper wrappture_example fermi"

NeonTest()
{
Expand Down Expand Up @@ -327,6 +327,7 @@ RenameAllApps()
../samples/example_app/ ucn
../samples/multi_thread/ multi_thread
../samples/sleeper/ sleeper
../samples/sporadic/ sporadic
../samples/worker/ worker
../samples/wrapper/ wrapper
../samples/wrappture/ wrappture_example
Expand Down
20 changes: 20 additions & 0 deletions api/boinc_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
bool send_remote_desktop_addr = false;
int app_min_checkpoint_period = 0;
// min checkpoint period requested by app
SPORADIC_AC_STATE ac_state;

#define TIMER_PERIOD 0.1
// Sleep interval for timer thread;
Expand Down Expand Up @@ -434,6 +435,10 @@
snprintf(buf, sizeof(buf), "<bytes_received>%f</bytes_received>\n", bytes_received);
strlcat(msg_buf, buf, sizeof(msg_buf));
}
if (ac_state) {
sprintf(buf, "<sporadic_ac>%d</sporadic_ac>\n", ac_state);
strlcat(msg_buf, buf, sizeof(msg_buf));

Check warning on line 440 in api/boinc_api.cpp

View check run for this annotation

Codecov / codecov/patch

api/boinc_api.cpp#L439-L440

Added lines #L439 - L440 were not covered by tests
}
#ifdef MSGS_FROM_FILE
if (fout) {
fputs(msg_buf, fout);
Expand All @@ -450,6 +455,7 @@
char buf[MSG_CHANNEL_SIZE];
double dtemp;
bool btemp;
int i;

if (!app_client_shm->shm->heartbeat.get_msg(buf)) {
return;
Expand All @@ -467,6 +473,9 @@
if (parse_bool(buf, "suspend_network", btemp)) {
boinc_status.network_suspended = btemp;
}
if (parse_int(buf, "<sporadic_ca>", i)) {
boinc_status.ca_state = (SPORADIC_CA_STATE)i;

Check warning on line 477 in api/boinc_api.cpp

View check run for this annotation

Codecov / codecov/patch

api/boinc_api.cpp#L477

Added line #L477 was not covered by tests
}
}

// called in timer thread
Expand Down Expand Up @@ -714,6 +723,7 @@
}

int boinc_get_status(BOINC_STATUS *s) {
// can just do a struct copy??
s->no_heartbeat = boinc_status.no_heartbeat;
s->suspended = boinc_status.suspended;
s->quit_request = boinc_status.quit_request;
Expand All @@ -722,6 +732,7 @@
s->working_set_size = boinc_status.working_set_size;
s->max_working_set_size = boinc_status.max_working_set_size;
s->network_suspended = boinc_status.network_suspended;
s->ca_state = boinc_status.ca_state;

Check warning on line 735 in api/boinc_api.cpp

View check run for this annotation

Codecov / codecov/patch

api/boinc_api.cpp#L735

Added line #L735 was not covered by tests
return 0;
}

Expand Down Expand Up @@ -1697,3 +1708,12 @@
strlcpy(remote_desktop_addr, addr, sizeof(remote_desktop_addr));
send_remote_desktop_addr = true;
}

void boinc_sporadic_set_ac_state(SPORADIC_AC_STATE a) {
ac_state = a;

Check warning on line 1713 in api/boinc_api.cpp

View check run for this annotation

Codecov / codecov/patch

api/boinc_api.cpp#L1712-L1713

Added lines #L1712 - L1713 were not covered by tests
}

SPORADIC_CA_STATE boinc_sporadic_get_ca_state() {
return boinc_status.ca_state;

Check warning on line 1717 in api/boinc_api.cpp

View check run for this annotation

Codecov / codecov/patch

api/boinc_api.cpp#L1716-L1717

Added lines #L1716 - L1717 were not covered by tests
}

5 changes: 5 additions & 0 deletions api/boinc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ typedef struct BOINC_OPTIONS {
// set this if application creates subprocesses.
} BOINC_OPTIONS;

// info passed from client to app in heartbeat message
//
typedef struct BOINC_STATUS {
int no_heartbeat;
int suspended;
Expand All @@ -72,6 +74,7 @@ typedef struct BOINC_STATUS {
double working_set_size;
double max_working_set_size;
int network_suspended;
SPORADIC_CA_STATE ca_state;
} BOINC_STATUS;

extern volatile BOINC_STATUS boinc_status;
Expand Down Expand Up @@ -143,6 +146,8 @@ extern int boinc_temporary_exit(
extern int boinc_finish_message(
int status, const char* message, bool is_notice
);
extern void boinc_sporadic_set_ac_state(SPORADIC_AC_STATE);
extern SPORADIC_CA_STATE boinc_sporadic_get_ca_state();

/////////// API ENDS HERE

Expand Down
1 change: 1 addition & 0 deletions client/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ boinc_client_SOURCES = \
cs_prefs.cpp \
cs_proxy.cpp \
cs_scheduler.cpp \
cs_sporadic.cpp \
cs_statefile.cpp \
cs_trickle.cpp \
current_version.cpp \
Expand Down
2 changes: 2 additions & 0 deletions client/Makefile.linux
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ BOINC_OBJ = \
cs_prefs.o \
cs_proxy.o \
cs_scheduler.o \
cs_sporadic.o \
cs_statefile.o \
cs_trickle.o \
current_version.o \
Expand Down Expand Up @@ -98,6 +99,7 @@ SRC = \
cs_proxy.cpp \
cs_scheduler.cpp \
cs_statefile.cpp \
cs_sporadic.cpp \
cs_trickle.cpp \
current_version.cpp \
dhrystone.cpp \
Expand Down
3 changes: 3 additions & 0 deletions client/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ ACTIVE_TASK::ACTIVE_TASK() {
safe_strcpy(remote_desktop_addr, "");
async_copy = NULL;
finish_file_time = 0;
sporadic_ca_state = CA_NONE;
sporadic_ac_state = AC_NONE;
sporadic_ignore_until = 0;
}

bool ACTIVE_TASK::process_exists() {
Expand Down
16 changes: 16 additions & 0 deletions client/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "procinfo.h"

#include "client_types.h"
#include "result.h"

// values for preempt_type (see ACTIVE_TASK::preempt())
//
Expand Down Expand Up @@ -184,11 +185,26 @@ struct ACTIVE_TASK {
// Used to kill apps that hang after writing finished file
int graphics_pid;
// PID of running graphics app (Mac)
SPORADIC_CA_STATE sporadic_ca_state;
SPORADIC_AC_STATE sporadic_ac_state;
double sporadic_ignore_until;

void set_task_state(int, const char*);
inline int task_state() {
return _task_state;
}
inline bool sporadic() {
return wup->app->sporadic;
}
inline bool non_cpu_intensive() {
return result->app->non_cpu_intensive;
}
inline bool always_run() {
return sporadic() || non_cpu_intensive();
}
inline bool dont_throttle() {
return result->dont_throttle();
}
int request_reread_prefs();
int request_reread_app_info();
int link_user_files();
Expand Down
22 changes: 16 additions & 6 deletions client/app_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,13 @@ void ACTIVE_TASK_SET::send_heartbeats() {
if (gstate.network_suspended) {
safe_strcat(buf, "<network_suspended/>");
}
if (atp->sporadic_ca_state != CA_NONE) {
char buf2[256];
sprintf(buf2, "<sporadic_ca>%d</sporadic_ca>",
atp->sporadic_ca_state
);
safe_strcat(buf, buf2);
}
bool sent = atp->app_client_shm.shm->heartbeat.send_msg(buf);
if (log_flags.heartbeat_debug) {
if (sent) {
Expand Down Expand Up @@ -889,7 +896,7 @@ bool ACTIVE_TASK_SET::check_rsc_limits_exceeded() {
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
if (atp->task_state() != PROCESS_EXECUTING) continue;
if (!atp->result->non_cpu_intensive() && (atp->elapsed_time > atp->max_elapsed_time)) {
if (!atp->always_run() && (atp->elapsed_time > atp->max_elapsed_time)) {
snprintf(buf, sizeof(buf), "exceeded elapsed time limit %.2f (%.2fG/%.2fG)",
atp->max_elapsed_time,
atp->result->wup->rsc_fpops_bound/1e9,
Expand Down Expand Up @@ -943,7 +950,7 @@ bool ACTIVE_TASK_SET::check_rsc_limits_exceeded() {

// don't count RAM usage of non-CPU-intensive jobs
//
if (!atp->result->non_cpu_intensive()) {
if (!atp->non_cpu_intensive()) {
ram_left -= atp->procinfo.working_set_size_smoothed;
}
}
Expand Down Expand Up @@ -1206,7 +1213,7 @@ void ACTIVE_TASK_SET::suspend_all(int reason) {

// special cases for non-CPU-intensive apps
//
if (atp->result->non_cpu_intensive()) {
if (atp->non_cpu_intensive()) {
if (cc_config.dont_suspend_nci) {
continue;
}
Expand All @@ -1218,7 +1225,7 @@ void ACTIVE_TASK_SET::suspend_all(int reason) {
// handle CPU throttling separately
//
if (reason == SUSPEND_REASON_CPU_THROTTLE) {
if (atp->result->dont_throttle()) continue;
if (atp->dont_throttle()) continue;
atp->preempt(REMOVE_NEVER, reason);
continue;
}
Expand Down Expand Up @@ -1246,7 +1253,7 @@ void ACTIVE_TASK_SET::suspend_all(int reason) {
// which uses a lot of CPU.
// Avoid going into a preemption loop.
//
if (atp->result->non_cpu_intensive()) break;
if (atp->always_run()) break;
atp->preempt(REMOVE_NEVER);
break;
case SUSPEND_REASON_BATTERY_OVERHEATED:
Expand Down Expand Up @@ -1390,7 +1397,7 @@ void ACTIVE_TASK::send_network_available() {
bool ACTIVE_TASK::get_app_status_msg() {
char msg_buf[MSG_CHANNEL_SIZE];
double fd;
int other_pid;
int other_pid, i;
double dtemp;
static double last_msg_time=0;

Expand Down Expand Up @@ -1460,6 +1467,9 @@ bool ACTIVE_TASK::get_app_status_msg() {
other_pids.clear();
other_pids.push_back(other_pid);
}
if (parse_int(msg_buf, "<sporadic_ac>", i)) {
sporadic_ac_state = (SPORADIC_AC_STATE)i;
}
if (current_cpu_time < 0) {
msg_printf(result->project, MSG_INFO,
"app reporting negative CPU: %f", current_cpu_time
Expand Down
10 changes: 7 additions & 3 deletions client/app_start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,12 @@ int ACTIVE_TASK::start(bool test) {
return 0;
}

// use special slot for test app
//
if (wup->project->app_test) {
strcpy(slot_dir, "slots/app_test");
}

// run it at above idle priority if it
// - uses coprocs
// - uses less than one CPU
Expand Down Expand Up @@ -691,14 +697,12 @@ int ACTIVE_TASK::start(bool test) {
exit(0);
}

// use special slot and exec path for test app
// use special exec path for test app
//
if (wup->project->app_test) {
strcpy(slot_dir, "slots/app_test");
strcpy(exec_path, gstate.app_test_file.c_str());
}


#ifdef _WIN32
PROCESS_INFORMATION process_info;
STARTUPINFO startup_info;
Expand Down
10 changes: 10 additions & 0 deletions client/app_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@ void CLIENT_STATE::app_test_init() {
strcpy(proj->master_url, "test_project_url");
strcpy(proj->_project_dir, ".");
proj->app_test = true;
proj->non_cpu_intensive = false;
projects.push_back(proj);

APP *app = new APP;
strcpy(app->name, "test app");
strcpy(app->user_friendly_name, "test app");
app->project = proj;
// can put other stuff here like
app->sporadic = true;
have_sporadic_app = true;
apps.push_back(app);

FILE_INFO *fip = new FILE_INFO;
Expand All @@ -56,6 +60,12 @@ void CLIENT_STATE::app_test_init() {
av->app = app;
av->project = proj;
av->app_files.push_back(*fref);
// can put other stuff here like
av->avg_ncpus = 1;
av->flops = 1e9;
av->gpu_ram = 1e7;
av->gpu_usage.rsc_type = PROC_TYPE_NVIDIA_GPU;
av->gpu_usage.usage = 1;
app_versions.push_back(av);

WORKUNIT *wu = new WORKUNIT;
Expand Down
10 changes: 10 additions & 0 deletions client/client_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ CLIENT_STATE::CLIENT_STATE()
#ifdef _WIN32
have_sysmon_msg = false;
#endif
have_sporadic_app = false;
}

void CLIENT_STATE::show_host_info() {
Expand Down Expand Up @@ -858,6 +859,8 @@ int CLIENT_STATE::init() {
client_thread_mutex.lock();
throttle_thread.run(throttler, NULL);

sporadic_init();

initialized = true;
return 0;
}
Expand Down Expand Up @@ -949,6 +952,7 @@ void CLIENT_STATE::do_io_or_sleep(double max_time) {
// possibly triggering state transitions.
// Returns true if something happened
// (in which case should call this again immediately)
// Called every POLL_INTERVAL (1 sec)
//
bool CLIENT_STATE::poll_slow_events() {
int actions = 0, retval;
Expand Down Expand Up @@ -1162,6 +1166,9 @@ bool CLIENT_STATE::poll_slow_events() {
if (!network_suspended) {
POLL_ACTION(scheduler_rpc , scheduler_rpc_poll );
}
if (have_sporadic_app) {
sporadic_poll();
}
retval = write_state_file_if_needed();
if (retval) {
msg_printf(NULL, MSG_INTERNAL_ERROR,
Expand Down Expand Up @@ -1269,6 +1276,9 @@ FILE_INFO* CLIENT_STATE::lookup_file_info(PROJECT* p, const char* name) {
int CLIENT_STATE::link_app(PROJECT* p, APP* app) {
if (lookup_app(p, app->name)) return ERR_NOT_UNIQUE;
app->project = p;
if (!app->non_cpu_intensive) {
p->non_cpu_intensive = false;
}
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions client/client_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,11 @@ struct CLIENT_STATE {
bool had_or_requested_work;
bool scheduler_rpc_poll();

// --------------- cs_sporadic.cpp:
bool have_sporadic_app;
void sporadic_poll();
void sporadic_init();

// --------------- cs_statefile.cpp:
void set_client_state_dirty(const char*);
int parse_state_file();
Expand Down
6 changes: 6 additions & 0 deletions client/client_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ int APP::parse(XML_PARSER& xp) {
safe_strcpy(user_friendly_name, "");
project = NULL;
non_cpu_intensive = false;
sporadic = false;
while (!xp.get_tag()) {
if (xp.match_tag("/app")) {
if (!strlen(user_friendly_name)) {
Expand All @@ -152,7 +153,12 @@ int APP::parse(XML_PARSER& xp) {
if (xp.parse_str("name", name, sizeof(name))) continue;
if (xp.parse_str("user_friendly_name", user_friendly_name, sizeof(user_friendly_name))) continue;
if (xp.parse_bool("non_cpu_intensive", non_cpu_intensive)) continue;
if (xp.parse_bool("sporadic", sporadic)) continue;
if (xp.parse_bool("fraction_done_exact", fraction_done_exact)) continue;
if (xp.parse_bool("sporadic", sporadic)) {
if (sporadic) gstate.have_sporadic_app = true;
continue;
}
#ifdef SIM
if (xp.parse_double("latency_bound", latency_bound)) continue;
if (xp.parse_double("fpops_est", fpops_est)) continue;
Expand Down
Loading
Loading