void Set_Floating_Point_Exception_Handling(const bool enable,const bool division_by_zero,const bool invalid_operation,const bool overflow,const bool underflow,const bool inexact_result) { static bool have_original_action=false; static struct sigaction original_action; if(!have_original_action){ // initialize with original action sigaction(SIGFPE,0,&original_action);} if(enable){ int exceptions=0; if(division_by_zero) exceptions|=FE_DIVBYZERO; if(invalid_operation) exceptions|=FE_INVALID; if(overflow) exceptions|=FE_OVERFLOW; if(underflow) exceptions|=FE_UNDERFLOW; if(inexact_result) exceptions|=FE_INEXACT; // avoid catching delayed exceptions caused by external code fedisableexcept(FE_ALL_EXCEPT); feclearexcept(exceptions); // install new handler struct sigaction action; action.sa_flags=SA_SIGINFO; action.sa_sigaction=Floating_Point_Exception_Handler; sigemptyset(&action.sa_mask); if(sigaction(SIGFPE,&action,0)) PHYSBAM_FATAL_ERROR("Could not register FPE signal handler"); feenableexcept(exceptions);} else{ if(sigaction(SIGFPE,&original_action,0)) PHYSBAM_FATAL_ERROR("Could not restore FPE signal handler"); fedisableexcept(FE_ALL_EXCEPT);} }
//##################################################################### // Function MOV_WRTER //##################################################################### template<class T> MOV_WRITER<T>:: MOV_WRITER(const std::string& filename,const int frames_per_second) :frames_per_second(frames_per_second),width(0),height(0) { fp=fopen(filename.c_str(),"wb"); if(!fp) PHYSBAM_FATAL_ERROR(STRING_UTILITIES::string_sprintf("Failed to open %s for writing",filename.c_str())); current_mov=new QT_ATOM(fp,"mdat"); }
void Set_Backtrace(const bool enable) { if(enable){ struct sigaction action; action.sa_flags=SA_SIGINFO; action.sa_sigaction=Backtrace_And_Abort; sigemptyset(&action.sa_mask); for(int *i=physbam_catch_signals;*i!=0;i++) sigaddset(&action.sa_mask,*i); for(int *i=physbam_catch_signals;*i!=0;i++) if(sigaction(*i,&action,0)) PHYSBAM_FATAL_ERROR("Failed to install backtrace handler.");} else for(int *i=physbam_catch_signals;*i!=0;i++) signal(*i,SIG_DFL); }
void Block_Interrupt_Signal(const bool block) { static bool have_original_action=false; static struct sigaction original_action; if(block){ if(have_original_action) PHYSBAM_FATAL_ERROR("Nested call to Block_Interrupt_Signal(true)."); struct sigaction action; action.sa_flags=0; action.sa_handler=Interrupt_Signal_Handler; sigemptyset(&action.sa_mask); if(sigaction(SIGINT,&action,&original_action)) PHYSBAM_FATAL_ERROR("Could not block interrupt signal."); have_original_action=true;} else{ if(!have_original_action) PHYSBAM_FATAL_ERROR("Call to Block_Interrupt_Signal(false) before Block_Interrupt_Signal(true)."); if(sigaction(SIGINT,&original_action,0)) PHYSBAM_FATAL_ERROR("Could not unblock interrupt signal."); if(caught_interrupt_signal){ LOG::cerr<<"Caught delayed interrupt signal."<<std::endl; raise(SIGINT);} have_original_action=false;} }
//##################################################################### // Function Print //##################################################################### template<class RW> void Read_Write<ARRAY_COLLECTION,RW>:: Print(std::ostream& output,const ARRAY_COLLECTION& object,const int p) { if(p<1 || p>object.number) throw INDEX_ERROR("Index out of range"); for(ATTRIBUTE_INDEX i(1);i<=object.arrays.m;i++){ const ARRAY_COLLECTION_ELEMENT_BASE* entry=object.arrays(i); const READ_WRITE_ARRAY_COLLECTION_FUNCTIONS* read_write_functions=Read_Write_Array_Collection_Registry().Get_Pointer(Type_Only(entry->Hashed_Id())); if(!read_write_functions || !read_write_functions->Print) PHYSBAM_FATAL_ERROR(STRING_UTILITIES::string_sprintf("No print registered for id %i (type %s)\n",Value(entry->id),typeid(*entry).name())); read_write_functions->Print(output,*entry,p);} }
static void Floating_Point_Exception_Handler(int sig_number,siginfo_t* info,void *data) { if(sig_number!=SIGFPE) PHYSBAM_FATAL_ERROR(); LOG::cerr<<"** ERROR: SIGNAL "<<"SIGFPE ("<<sig_number<<") **"<<std::endl; LOG::cerr<<"Floating point exception: reason "<<info->si_code<<" = \""<< (info->si_code==FPE_INTDIV?"integer divide by zero":info->si_code==FPE_INTOVF?"integer overflow": info->si_code==FPE_FLTDIV?"FP divide by zero":info->si_code==FPE_FLTOVF?"FP overflow": info->si_code==FPE_FLTUND?"FP underflow":info->si_code==FPE_FLTRES?"FP inexact result": info->si_code==FPE_FLTINV?"FP invalid operation":info->si_code==FPE_FLTSUB?"subscript out of range":"unknown") << "\", from address 0x"<<std::hex<<(unsigned long)info->si_addr<<std::endl; Backtrace(); LOG::Finish_Logging(); exit(sig_number); }
//##################################################################### // Function Write_Arrays //##################################################################### template<class RW> void Read_Write<ARRAY_COLLECTION,RW>:: Write_Arrays(std::ostream& output,const ARRAY_COLLECTION& object) { Write_Binary<RW>(output,object.number,object.arrays.m); for(ATTRIBUTE_INDEX i(1);i<=object.arrays.m;i++){ const ARRAY_COLLECTION_ELEMENT_BASE* entry=object.arrays(i); const READ_WRITE_ARRAY_COLLECTION_FUNCTIONS* read_write_functions=Read_Write_Array_Collection_Registry().Get_Pointer(Type_Only(entry->Hashed_Id())); if(!read_write_functions || !read_write_functions->Write || !read_write_functions->Write_Size) PHYSBAM_FATAL_ERROR(STRING_UTILITIES::string_sprintf("No write registered for id %i (type %s)\n",Value(entry->id),typeid(*entry).name())); int calculated_write_size=read_write_functions->Write_Size(*entry); Write_Binary<RW>(output,entry->Typed_Hashed_Id(RW()),calculated_write_size); if(calculated_write_size) read_write_functions->Write(output,*entry);} }
//##################################################################### // Function Read_Arrays //##################################################################### template<class RW> void Read_Write<ARRAY_COLLECTION,RW>:: Read_Arrays(std::istream& input,ARRAY_COLLECTION& object) { int size; ATTRIBUTE_INDEX num_attributes; Read_Binary<RW>(input,size,num_attributes); object.Resize(size); for(ATTRIBUTE_INDEX i(1);i<=num_attributes;i++){ ATTRIBUTE_ID hashed_id;int read_size; Read_Binary<RW>(input,hashed_id,read_size); READ_WRITE_ARRAY_COLLECTION_FUNCTIONS* read_write_functions=Read_Write_Array_Collection_Registry().Get_Pointer(Type_Only(hashed_id)); if(!read_write_functions){input.ignore(read_size);continue;} if(!read_write_functions->Read && read_write_functions->sample_attribute) PHYSBAM_FATAL_ERROR(STRING_UTILITIES::string_sprintf("No read registered for id %i\n",Value(hashed_id))); ATTRIBUTE_INDEX index=object.Get_Attribute_Index(Id_Only(hashed_id)); if(!index) index=object.Add_Array(Id_Only(hashed_id),read_write_functions->sample_attribute->Clone_Default()); // TODO: this really ought to know whether we're running in float or double else read_write_functions=Read_Write_Array_Collection_Registry().Get_Pointer(Type_Only(object.arrays(index)->Hashed_Id())); read_write_functions->Read(input,*object.arrays(index)); object.arrays(index)->id=Id_Only(hashed_id);} }
//##################################################################### // Function Find_Or_Read_Structure //##################################################################### template<class TV> bool RIGID_GEOMETRY_COLLECTION<TV>:: Find_Or_Read_Structure(const STREAM_TYPE stream_type,ARRAY<int>& structure_ids,const std::string& filename,const T scaling_factor,const TV& center) { int id; if(!FILE_UTILITIES::File_Exists(filename)) return false; std::string hashname=STRING_UTILITIES::string_sprintf("%s@%.6f",filename.c_str(),scaling_factor); // mangle hash name if(!always_create_structure&&structure_hash.Get(hashname,id)){ // already read in if(!structure_list.Is_Active(id)) PHYSBAM_FATAL_ERROR();} // // only works if the referenced geometry is still in memory else{ // read in for the first time STRUCTURE<TV>* structure=0; if(!stream_type.use_doubles) structure=Read_Write<STRUCTURE<TV>,float>::Create_From_File(filename); #ifndef COMPILE_WITHOUT_DOUBLE_SUPPORT else structure=Read_Write<STRUCTURE<TV>,double>::Create_From_File(filename); #endif if(scaling_factor!=1){ Wrap_Structure_Helper(structure,center); structure->Rescale(scaling_factor);} id=structure_list.Add_Element(structure); if(!always_create_structure) structure_hash.Insert(hashname,id);} structure_ids.Append(id); return true; }
template<> void OPENGL_SCALAR_FIELD_2D<double,int>:: Set_Scale_Range(const int range_min,const int range_max) {PHYSBAM_FATAL_ERROR();}
template<> void OPENGL_SCALAR_FIELD_2D<float,bool>:: Set_Scale_Range(const bool range_min,const bool range_max) {PHYSBAM_FATAL_ERROR();}