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);}
}
示例#2
0
//#####################################################################
// 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();}