20 #include <utility/io/izstream.hh>
29 #include <utility/io/ozstream.hh>
30 #include <utility/basic_sys_util.hh>
31 #include <utility/string_util.hh>
33 #include <basic/options/option.hh>
34 #include <basic/options/after_opts.hh>
43 #include <ObjexxFCL/format.hh>
59 #include <basic/options/keys/boinc.OptionKeys.gen.hh>
67 static Boinc theBoinc;
83 boinc_init_diagnostics(
84 BOINC_DIAG_DUMPCALLSTACKENABLED |
85 BOINC_DIAG_HEAPCHECKENABLED |
86 BOINC_DIAG_MEMORYLEAKCHECKENABLED |
87 BOINC_DIAG_REDIRECTSTDERR |
88 BOINC_DIAG_REDIRECTSTDOUT |
89 BOINC_DIAG_TRACETOSTDERR
92 cerr << utility::timestamp() <<
" :: BOINC:: Initializing ... ok." << std::endl;
93 if ( boinc_init() ) exit( EXIT_FAILURE );
94 cerr << utility::timestamp() <<
" :: BOINC :: boinc_init()" << endl;
98 boinc_resolve_filename(
"stdout.txt", filename, 256);
99 freopen(filename,
"a", stdout);
101 boinc_fraction_done(0.00);
103 #ifdef BOINC_GRAPHICS
108 cerr <<
"BOINC:: Setting up shared resources ... ok." << std::endl;
110 create_shared_memory();
112 cerr <<
"BOINC:: Setting up semaphores ... ok." << std::endl;
116 cerr <<
"BOINC:: Updating status ... ok." << std::endl;
119 update_status_shmem();
121 cerr <<
"BOINC:: Registering timer callback... ok." << std::endl;
123 boinc_register_timer_callback(update_status_shmem);
128 cerr <<
"BOINC:: Worker initialized successfully. " << std::endl;
163 APP_INIT_DATA app_init_data;
164 boinc_get_init_data(app_init_data);
165 if (!app_init_data.project_preferences)
return;
167 double max_gfx_fpstmp = 0.0;
168 double max_gfx_cputmp = 0.0;
169 int cpu_run_timetmp = 0;
170 parse_double(app_init_data.project_preferences,
"<max_fps>", max_gfx_fpstmp);
172 parse_double(app_init_data.project_preferences,
"<max_cpu>", max_gfx_cputmp);
174 parse_int(app_init_data.project_preferences,
"<cpu_run_time>", cpu_run_timetmp);
196 using namespace basic::options;
197 int cpu_run_timeout = option[ OptionKeys::boinc::cpu_run_timeout ]();
200 if( ( estimated_wu_length -
cpu_time_ ) < 10*60 ) estimated_wu_length =
cpu_time_ + 10*60;
201 double new_frac =
cpu_time_ / ( estimated_wu_length );
221 if ( ( !boinc_is_standalone() ) &&
225 std::cerr <<
"Too many restarts with no progress. Keep application in memory while preempted." << std::endl;
236 #ifdef BOINC_GRAPHICS
238 shmem_->model_count = total_nstruct + 1;
239 shmem_->total_mc_trial_count = 0;
240 if (shmem_->low_energy) {
241 shmem_->model_low_energy = shmem_->low_energy;
242 if (shmem_->native_pose_exists) {
247 if (shmem_->low_energy_pose_exists) {
258 if (total_nstruct <= 0)
return false;
260 using namespace basic::options;
265 time_left <
cpu_time_/
double(total_nstruct) ||
267 total_nstruct >= option[ OptionKeys::boinc::max_nstruct ]
273 #ifdef BOINC_GRAPHICS
274 update_status_shmem();
282 std::cerr <<
"BOINC:: Worker startup. " << std::endl;
283 using namespace basic::options;
285 utility_exit_with_message(
"Must initialize Boinc before calling startup." );
287 if ( option[ OptionKeys::boinc::frame_rate ].user() )
289 if ( option[ OptionKeys::boinc::cpu_frac].user() )
291 if ( option[ OptionKeys::boinc::cpu_run_time].user() )
303 if ( chckptcnt_istream ) {
305 chckptcnt_istream.close();
306 chckptcnt_istream.clear();
311 int prev_initcnt = 0;
312 int prev_chckptcnt = 0;
314 if ( initcnt_istream ) {
315 initcnt_istream >> prev_initcnt >> prev_chckptcnt;
316 initcnt_istream.close();
317 initcnt_istream.clear();
324 if ( initcnt_ostream ) {
326 initcnt_ostream.close();
327 initcnt_ostream.clear();
340 #ifdef BOINC_GRAPHICS
341 update_status_shmem();
352 std::cerr <<
"BOINC :: BOINC support services shutting down cleanly ..." << std::endl;
358 using namespace ObjexxFCL::fmt;
361 int decoy_cnt = (num_decoys > 0) ? num_decoys-1 : num_decoys;
362 int attempt_cnt = (attempted_decoys > 0) ? attempted_decoys-1 : attempted_decoys;
363 double cputime = 0.0;
364 boinc_wu_cpu_time(cputime);
366 if(cputime < 1200 ) cputime = 1201;
368 std::cerr <<
"======================================================" << std::endl;
369 std::cerr <<
"DONE ::" << I( 6, std::min( decoy_cnt, std::max(starting_structs,1) ) ) <<
370 " starting structures " << I( 8, cputime ) <<
" cpu seconds" << std::endl;
371 std::cerr <<
"This process generated " <<
372 I( 6, decoy_cnt ) <<
" decoys from " << I( 7, attempt_cnt ) <<
373 " attempts" << std::endl;
374 std::cerr <<
"======================================================" << std::endl;
388 if ( chckptcnt_ostream ) {
389 chckptcnt_ostream << checkpointcount;
390 chckptcnt_ostream.close();
391 chckptcnt_ostream.clear();
393 boinc_checkpoint_completed();
408 #ifdef BOINC_GRAPHICS
415 void Boinc::set_wu_desc() {
416 using namespace basic::options;
418 static bool init =
false;
422 if ( option[ OptionKeys::boinc::description_file ].user() ) {
423 std::string description_file = option[ OptionKeys::boinc::description_file ];
424 utility::io::izstream desc_stream( description_file );
426 std::vector<std::string> wu_desc_rows;
428 while (desc_stream && !desc_stream.eof()) {
429 desc_stream.getline( tmpstr );
430 utility::trim( tmpstr );
431 if ( tmpstr.length() > 0)
432 wu_desc_rows.push_back( tmpstr );
437 shmem_->wu_desc_exists = 1;
450 const int Boinc::attach_graphics_current_pose_observer(
core::pose::Pose & pose ) {
451 if (!shmem_)
return 0;
453 bpo->attach_to( pose );
460 if (!shmem_)
return 0;
462 boinc_begin_critical_section();
465 shmem_->native_pose_exists = 1;
466 boinc_end_critical_section();
472 void Boinc::update_mc_trial_info(
const int & trial_cnt,
const std::string & mover_type ) {
478 shmem_->mover_mc_trial_count = trial_cnt;
479 shmem_->total_mc_trial_count++;
497 boinc_begin_critical_section();
501 shmem_->current_pose_exists = 1;
503 boinc_end_critical_section();
512 static bool persist =
false;
513 if (update_mode == RESET) {
515 }
else if (update_mode == PERSIST) {
526 if (!shmem_ || (persist && update_mode == DEFAULT))
return;
528 boinc_begin_critical_section();
529 shmem_->low_energy = low_energy;
532 shmem_->low_energy_update_cnt++;
533 shmem_->low_energy_pose_exists = 1;
534 boinc_end_critical_section();
552 boinc_begin_critical_section();
553 shmem_->last_accepted_energy = last_accepted_energy;
556 shmem_->last_accepted_pose_exists = 1;
557 boinc_end_critical_section();
563 void Boinc::create_shared_memory() {
564 if (shmem_ == NULL) {
565 shmem_ = (BoincSharedMemory*)boinc_graphics_make_shmem(BOINC_SHMEM_NAME,
sizeof(BoincSharedMemory));
567 std::cerr <<
"failed to create shared mem segment: " << BOINC_SHMEM_NAME <<
" Size: " <<
sizeof(BoincSharedMemory) << std::endl;
569 std::cout <<
"Created shared memory segment " << std::endl;
574 void Boinc::attach_shared_memory() {
575 if (shmem_ == NULL) {
587 std::cout <<
"Attached shared memory segment " << std::endl;
591 std::cerr <<
"failed to attach shared mem segment " << std::endl;
595 BoincSharedMemory* Boinc::get_shmem() {
return shmem_; }
597 void Boinc::update_status_shmem() {
602 shmem_->update_time = dtime();
603 boinc_get_status(&shmem_->status);
615 #ifndef USE_SYSV_SEMAPHORE
620 int retval = boinc_get_init_data(aid);
621 if (retval) aid.slot = 0;
622 sprintf(name,
"boinc_minirosetta_sema_%d", aid.slot);
627 const key_t Boinc::get_sema_key() {
630 if (sema_key)
return sema_key;
632 int retval = boinc_get_init_data(aid);
633 if (retval) aid.slot = 0;
634 sema_key = SEMA_KEY_PREFIX + aid.slot;
638 const int Boinc::destroy_semaphore() {
639 int id = semget(get_sema_key(), 0, 0);
640 if (
id < 0)
return 0;
641 if (semctl(
id, 1, IPC_RMID, 0))
return 0;
646 #endif // USE_SYSV_SEMAPHORE
656 CloseHandle(sem_des_);
668 PSID pEveryoneSID = NULL;
670 PSECURITY_DESCRIPTOR pSD = NULL;
672 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
673 SECURITY_ATTRIBUTES
sa;
675 char global_sema_name[256];
677 osvi.dwOSVersionInfoSize =
sizeof(osvi);
679 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
680 sem_des_ = CreateSemaphore(NULL,1,1, name);
683 if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
688 std::cerr <<
"CreateSemaphore failure: AllocateAndInitializeSid Error " << GetLastError() << std::endl;
694 ZeroMemory(&ea,
sizeof(EXPLICIT_ACCESS));
695 ea.grfAccessPermissions = SEMAPHORE_ALL_ACCESS;
696 ea.grfAccessMode = SET_ACCESS;
697 ea.grfInheritance= NO_INHERITANCE;
698 ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
699 ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
700 ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID;
703 dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
704 if (ERROR_SUCCESS != dwRes) {
705 std::cerr <<
"CreateSemaphore failure: SetEntriesInAcl " << GetLastError() << std::endl;
710 pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
712 std::cerr <<
"CreateSemaphore failure: LocalAlloc Error " << GetLastError() << std::endl;
716 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
717 std::cerr <<
"CreateSemaphore failure: InitializeSecurityDescriptor Error " << GetLastError() << std::endl;
722 if (!SetSecurityDescriptorDacl(pSD,
727 std::cerr <<
"CreateSemaphore failure: SetSecurityDescriptorDacl Error " << GetLastError() << std::endl;
732 sa.nLength =
sizeof (SECURITY_ATTRIBUTES);
733 sa.lpSecurityDescriptor = pSD;
734 sa.bInheritHandle = FALSE;
744 bool try_global =
true;
746 sprintf(global_sema_name,
"Global\\%s", name);
747 sem_des_ = CreateSemaphore(&sa, 1, 1, global_sema_name);
748 dwError = GetLastError();
749 if (!sem_des_ && (ERROR_ACCESS_DENIED == dwError)) {
755 sem_des_ = CreateSemaphore(&sa, 1, 1, name);
756 dwError = GetLastError();
761 if (GetLastError() == ERROR_ALREADY_EXISTS) {
762 CloseHandle(sem_des_);
768 std::cerr <<
"CreateSemaphore failure! Cannot create semaphore!" << std::endl;
771 std::cout <<
"Created semaphore" << std::endl;
777 if (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
779 FreeSid(pEveryoneSID);
789 #ifndef USE_SYSV_SEMAPHORE
797 sem_des_ = sem_open(name, O_CREAT|O_EXCL, 0777, 1);
798 if(sem_des_ == (
void*)-1) {
799 std::cerr <<
"sem_open create failure! Cannot create semaphore!" << std::endl;
802 std::cout <<
"Created semaphore" << std::endl;
815 struct semid_ds *buf;
816 unsigned short *array;
820 int semid = semget(get_sema_key(), 1, IPC_CREAT|IPC_EXCL|0777);
822 std::cerr <<
"semget failure! Cannot create semaphore!" << std::endl;
825 if( semctl(semid, 0, SETVAL, arg) < 0) {
826 std::cerr <<
"semctl failure! Cannot set semaphore value!" << std::endl;
830 std::cout <<
"Created semaphore" << std::endl;
833 #endif // USE_SYSV_SEMAPHORE
842 if (sem_des_)
return 1;
847 char global_sema_name[256];
853 sprintf(global_sema_name,
"Global\\%s", name);
854 sem_des_ = OpenSemaphore(SEMAPHORE_ALL_ACCESS, NULL, global_sema_name);
859 sem_des_ = OpenSemaphore(SEMAPHORE_ALL_ACCESS, NULL, name);
862 std::cerr <<
"OpenSemaphore failure" << std::endl;
865 std::cerr <<
"Opened semaphore" << std::endl;
868 #ifndef USE_SYSV_SEMAPHORE
871 if (sem_des_)
return 1;
875 sem_des_ = sem_open(name, 0, 0777, 0);
876 if(sem_des_ == (
void*) -1){
877 std::cerr <<
"sem_open failure" << std::endl;
880 std::cout <<
"Opened semaphore" << std::endl;
883 if (sem_id_)
return 1;
885 int semid = semget(get_sema_key(), 0, 0);
887 std::cerr <<
"semget failure! Cannot open semaphore!" << std::endl;
891 std::cout <<
"Opened semaphore" << std::endl;
893 #endif // USE_SYSV_SEMAPHORE
899 if (WaitForSingleObject(sem_des_, INFINITE) == WAIT_OBJECT_0)
return 0;
902 #ifndef USE_SYSV_SEMAPHORE
903 return sem_wait(sem_des_);
905 if (sem_id_ <= 0)
return 1;
906 struct sembuf ops[] = {{0, -1, 0}};
907 if (semop(sem_id_, ops, 1))
return 1;
909 #endif // USE_SYSV_SEMAPHORE
915 if (WaitForSingleObject(sem_des_, 0) == WAIT_OBJECT_0)
return 0;
918 #ifndef USE_SYSV_SEMAPHORE
919 return sem_trywait(sem_des_);
921 if (sem_id_ <= 0)
return 1;
922 struct sembuf ops[] = {{0, -1, IPC_NOWAIT}};
923 if (semop(sem_id_, ops, 1))
return 1;
925 #endif // USE_SYSV_SEMAPHORE
932 if (ReleaseSemaphore(sem_des_, 1, NULL))
return 0;
935 #ifndef USE_SYSV_SEMAPHORE
936 return sem_post(sem_des_);
938 if (sem_id_ <= 0)
return 1;
939 struct sembuf ops[] = {{0, 1, 0}};
940 if (semop(sem_id_, ops, 1))
return 1;
942 #endif // USE_SYSV_SEMAPHORE
947 HANDLE Boinc::sem_des_ = NULL;
949 #ifndef USE_SYSV_SEMAPHORE
950 sem_t* Boinc::sem_des_ = NULL;
953 #endif // USE_SYSV_SEMAPHORE
958 BoincSharedMemory* Boinc::shmem_ = NULL;
960 #endif // BOINC_GRAPHICS