// Copyright 2003 Regents of the University of California
// SETI_BOINC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2, or (at your option) any later
// version.
// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
// You should have received a copy of the GNU General Public License along
// with SETI_BOINC; see the file COPYING. If not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// In addition, as a special exception, the Regents of the University of
// California give permission to link the code of this program with libraries
// that provide specific optimized fast Fourier transform (FFT) functions and
// distribute a linked executable. You must obey the GNU General Public
// License in all respects for all of the code used other than the FFT library
// itself. Any modification required to support these libraries must be
// distributed in source code form. If you modify this file, you may extend
// this exception to your version of the file, but you are not obligated to
// do so. If you do not wish to do so, delete this exception statement from
// your version.
// worker.C: SETI-independent worker logic
// $Id: worker.cpp,v 1.32.2.13 2007/07/16 15:36:50 korpela Exp $
//
#include "sah_config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifndef _WIN32
#include <dlfcn.h>
#endif
#ifdef BOINC_APP_GRAPHICS
#include "graphics_api.h"
#ifdef DYNAMIC_GRAPHICS
#include "graphics_lib.h"
#endif
#include "sah_gfx.h"
#endif
#include "s_util.h"
#include "seti_header.h"
#include "seti.h"
#include "worker.h"
#include "chirpfft.h"
#include "analyzeFuncs.h"
#include "analyzeReport.h"
#include "filesys.h"
#include "boinc_api.h"
#include "worker.h"
using std::string;
#ifdef BOINC_APP_GRAPHICS
#ifdef DYNAMIC_GRAPHICS
int_func_t f_glut_is_initialized;
get_graphics_t f_get_sah_graphics;
vvfunc_t f_free_sah_graphics;
#define glut_is_initialized f_glut_is_initialized
#define get_sah_graphics f_get_sah_graphics
#define free_sah_graphics f_free_sah_graphics
#endif
SAH_GRAPHICS_BASE *sah_graphics;
#endif
bool verbose;
// this gets called first on all platforms
int common_init() {
#ifdef ALLOW_CFFT_FILE
FILE* f;
f = boinc_fopen(CFFT_FILENAME, "r");
if (f) {
cfft_file = &debug_cfft_file[0];
fclose(f);
}
#endif
return 0;
}
// Do this when start on a work unit for the first time.
// Creates result header file.
static int initialize_for_wu() {
int retval = 0;
FILE* f;
string path;
boinc_resolve_filename_s(OUTFILE_FILENAME, path);
f = boinc_fopen(path.c_str(), "wb");
if (!f) SETIERROR(FOPEN_FAILED,"in initialize_for_wu()");
xml_indent(2);
fprintf(f, "<result>\n");
retval = seti_write_wu_header(f, 1);
fclose(f);
return retval;
}
// parse input and state files
//
static int read_wu_state() {
FILE* f;
int retval=0;
string path;
FORCE_FRAME_POINTER;
boinc_resolve_filename_s(WU_FILENAME, path);
f = boinc_fopen(path.c_str(), "rb");
if (f) {
#ifdef BOINC_APP_GRAPHICS
if (!nographics()) sprintf(sah_graphics->status, "Scanning data file\n");
#endif
retval = seti_parse_wu(f, analysis_state);
fclose(f);
if (retval) SETIERROR(retval,"from seti_parse_wu() in read_wu_state()");
} else {
char msg[1024];
sprintf(msg,"(%s) in read_wu_state() errno=%d\n",path.c_str(),errno);
SETIERROR(FOPEN_FAILED,msg);
}
retval = seti_init_state();
if (retval) SETIERROR(retval,"from seti_init_state() in read_wu_state()");
#ifdef BOINC_APP_GRAPHICS
if (!nographics()) sprintf(sah_graphics->status, "Scanning state file.\n");
#endif
if (boinc_file_exists(STATE_FILENAME)) {
retval = parse_state_file(analysis_state);
} else {
retval = initialize_for_wu();
if (retval) SETIERROR(retval,"from initialize_for_wu() in read_wu_state()");
}
boinc_fraction_done(progress*remaining+(1.0-remaining)*(1.0-remaining));
return 0;
}
void worker() {
int retval=0;
run_stage=POSTINIT;
FORCE_FRAME_POINTER;
#if defined(__GNUC__) && defined (__i386__)
__asm__ __volatile__ ("andl $-16, %esp");
#endif
try {
retval = common_init();
if (retval) SETIERROR(retval,"from common_init() in worker()");
#ifdef BOINC_APP_GRAPHICS
if (!sah_graphics) {
#ifdef DYNAMIC_GRAPHICS
int waited=0;
do {
sleep(1);
waited++;
} while (!graphics_lib_handle && (waited<10));
if (graphics_lib_handle) {
glut_is_initialized=(int_func_t)dlsym(graphics_lib_handle,"xwin_glut_is_initialized");
// fprintf(stderr,"glut_is_initialized() :%x\n",glut_is_initialized);
get_sah_graphics=(get_graphics_t)dlsym(graphics_lib_handle,"get_sah_graphics");
// fprintf(stderr,"get_sah_graphics() :%x\n",get_sah_graphics);
free_sah_graphics=(vvfunc_t)dlsym(graphics_lib_handle,"free_sah_graphics");
// fprintf(stderr,"free_sah_graphics() :%x\n",free_sah_graphics);
fflush(stderr);
}
if (get_sah_graphics) {
sah_graphics=get_sah_graphics();
//fprintf(stderr,"sah_graphics :%x\n",sah_graphics);
fflush(stderr);
}
#else
sah_graphics=get_sah_graphics();
#endif
}
#endif
retval = read_wu_state();
if (retval) SETIERROR(retval,"from read_wu_state() in worker()");
#ifdef BOINC_APP_GRAPHICS
if (!sah_graphics) {
#ifdef DYNAMIC_GRAPHICS
int waited=0;
do {
sleep(1);
waited++;
} while (!graphics_lib_handle && (waited<10));
if (graphics_lib_handle) {
glut_is_initialized=(int_func_t)dlsym(graphics_lib_handle,"xwin_glut_is_initialized");
get_sah_graphics=(get_graphics_t)dlsym(graphics_lib_handle,"get_sah_graphics");
free_sah_graphics=(vvfunc_t)dlsym(graphics_lib_handle,"free_sah_graphics");
}
if (get_sah_graphics) {
sah_graphics=get_sah_graphics();
}
#else
sah_graphics=get_sah_graphics();
#endif
}
#endif
retval = seti_do_work();
if (retval) SETIERROR(retval,"from seti_do_work() in worker()");
boinc_fpops_cumulative((SETUP_FLOPS+analysis_state.FLOP_counter)*LOAD_STORE_ADJUSTMENT);
boinc_finish(retval);
}
catch (seti_error e) {
if (e == RESULT_OVERFLOW) {
fprintf(stderr, "SETI@Home Informational message -9 result_overflow\n");
fprintf(stderr, "NOTE: The number of results detected exceeds the storage space allocated.\n");
final_report(); // add flop and signal counts
progress=1;
remaining=0;
boinc_fraction_done(progress);
checkpoint(true); // force a checkpoint
boinc_fpops_cumulative((SETUP_FLOPS+analysis_state.FLOP_counter)*LOAD_STORE_ADJUSTMENT);
boinc_finish(0);
exit(0); // an overflow is not an app error
} else {
e.print();
exit(static_cast<int>(e));
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1