📄 wytimespec.cpp
字号:
};bool WyTimeSpec::operator >=(const WyTimeSpec &rhs) const WY__TSPC(){ if(_tspc.tv_sec>rhs._tspc.tv_sec) { return true; } else if(_tspc.tv_sec<rhs._tspc.tv_sec) { return false; } else {} if(_tspc.tv_nsec>=rhs._tspc.tv_nsec) { return true; } else { return false; }};bool WyTimeSpec::operator <(const WyTimeSpec &rhs) const WY__TSPC(){ if(_tspc.tv_sec<rhs._tspc.tv_sec) { return true; } else if(_tspc.tv_sec>rhs._tspc.tv_sec) { return false; } else {} if(_tspc.tv_nsec<rhs._tspc.tv_nsec) { return true; } else { return false; }};bool WyTimeSpec::operator <=(const WyTimeSpec &rhs) const WY__TSPC(){ if(_tspc.tv_sec<rhs._tspc.tv_sec) { return true; } else if(_tspc.tv_sec>rhs._tspc.tv_sec) { return false; } else {} if(_tspc.tv_nsec<=rhs._tspc.tv_nsec) { return true; } else { return false; }};const WyTimeSpec WyTimeSpec::abs(void) const WY__TSPC(Reply){ WyTimeSpec v; if(_tspc.tv_sec>0) { v._tspc.tv_sec=_tspc.tv_sec; v._tspc.tv_nsec=_tspc.tv_nsec; } else if(_tspc.tv_sec<0) { if(wy__sub_ovf(std::time_t(0),_tspc.tv_sec)) { WY_THROW( Reply(Wym_EMATHNEG) ); } v._tspc.tv_sec=-_tspc.tv_sec; v._tspc.tv_nsec=-_tspc.tv_nsec; } else { // v.tv_sec=0; already 0 if(_tspc.tv_nsec>=0) { v._tspc.tv_nsec=_tspc.tv_nsec; } else { v._tspc.tv_nsec=-_tspc.tv_nsec; } } return(v);};WyRet WyTimeSpec::add(Wy_Second sec, Wy_Nano nsec) WY__TSPC(){ WyRet r( _normalize(sec,nsec) ); if(r!=Ok) { WY_RETURN(r); } if(wy__add_ovf(_tspc.tv_sec,sec)) { WY_RETURN(Wym_ERANGE); } WyTimeSpec v(*this); v._tspc.tv_sec+=sec; v._tspc.tv_nsec+=nsec; if((r=_normalize(v._tspc.tv_sec,v._tspc.tv_nsec))!=Ok) { WY_RETURN(r); } _tspc=v._tspc; return(Ok);};WyRet WyTimeSpec::sub(Wy_Second sec, Wy_Nano nsec) WY__TSPC(){ WyRet r( _normalize(sec,nsec) ); if(r!=Ok) { WY_RETURN(r); } if(wy__sub_ovf(_tspc.tv_sec,sec)) { WY_RETURN(Wym_ERANGE); } WyTimeSpec v(*this); v._tspc.tv_sec-=sec; v._tspc.tv_nsec-=nsec; if((r=_normalize(v._tspc.tv_sec,v._tspc.tv_nsec))!=Ok) { WY_RETURN(r); } _tspc=v._tspc; return(Ok);};WyRet WyTimeSpec::mul(long int n) WY__TSPC(){ long long ll((long long)_tspc.tv_sec*n); if( (ll>(long long)std::numeric_limits<Wy_Second>::max()) ||(ll<(long long)std::numeric_limits<Wy_Second>::min())) { WY_RETURN( Wym_ERANGE ); } std::lldiv_t dt=std::lldiv((long long)_tspc.tv_nsec*n,_Giga); ll+=dt.quot; if( (ll>(long long)std::numeric_limits<Wy_Second>::max()) ||(ll<(long long)std::numeric_limits<Wy_Second>::min())) { WY_RETURN( Wym_ERANGE ); } _tspc.tv_sec=static_cast<Wy_Second>(ll); _tspc.tv_nsec=static_cast<Wy_Nano>(dt.rem); return(Ok);};WyRet WyTimeSpec::mul(const WyTimeSpec& n) WY__TSPC(){ long long llnano((long long)_tspc.tv_nsec*n._tspc.tv_nsec); std::lldiv_t dt=std::lldiv((long long)llnano,(long long)WY_CONST_GIGA); llnano=(dt.quot); long long tmp((long long)_tspc.tv_sec*n._tspc.tv_nsec); dt=std::lldiv(tmp,(long long)WY_CONST_GIGA); long long llsec(dt.quot); llnano+=dt.rem; tmp=(long long)_tspc.tv_nsec*n._tspc.tv_sec; dt=std::lldiv(tmp,(long long)WY_CONST_GIGA); llsec+=dt.quot; llnano+=dt.rem; dt=std::lldiv(llnano,(long long)WY_CONST_GIGA); llnano=dt.rem; llsec+=dt.quot; tmp=(long long)_tspc.tv_sec*n._tspc.tv_sec; if(wy__add_ovf(tmp,llsec)) { WY_RETURN(Wym_ERANGE); // result not representable } llsec+=tmp; if( (tmp>(long long)std::numeric_limits<Wy_Second>::max()) ||(tmp<(long long)std::numeric_limits<Wy_Second>::min())) { WY_RETURN( Wym_ERANGE ); } _tspc.tv_sec = llsec; _tspc.tv_nsec= llnano; return(Ok);};WyRet WyTimeSpec::div(long n) WY__TSPC(){ if(n==0) { WY_RETURN( Wym_EDIVZERO ); } const std::ldiv_t dt=std::ldiv(_tspc.tv_sec,n); _tspc.tv_sec=dt.quot; _tspc.tv_nsec= (((long long)dt.rem*(long long)_Giga)+_tspc.tv_nsec)/n; return(Ok);};/*#include <iostream>WyRet WyTimeSpec::div(const WyTimeSpec& n) WY__TSPC(){ if((n._tspc.tv_sec==0)&&(n._tspc.tv_nsec==0)) { WY_RETURN( Wym_EDIVZERO ); } const long long Dvr((long long)n._tspc.tv_sec*(long long)_Giga+n._tspc.tv_nsec); std::lldiv_t dt=std::lldiv( (long long)_tspc.tv_sec*(long long)_Giga +_tspc.tv_nsec, Dvr); long long wn(dt.quot); // whole number //std::cerr << wn << '/' << Dvr << "= " << dt.quot << ", " << dt.rem << '\n'; dt=std::lldiv(dt.rem,Dvr); // r -> quot[Dvr]+rem (rem<Dvr) long long t2(dt.quot*_Giga); long long t3(dt.rem*_Giga); std::lldiv_t dt2=std::lldiv((long long)_Giga,Dvr); _tspc.tv_sec = wn; _tspc.tv_nsec= dt.quot; return(Ok);};*///-------------------------------------WyTimeSpec Wy::now(void)try {#ifdef _POSIX_TIMERS struct timespec tm_now; if(::clock_gettime(CLOCK_REALTIME,&tm_now)!=0) { // man. only EINVAL which should not happen here. WY_THROW( WyRet(WyReply(errno)) ); } // // note: WyTimeSpec ctor is assumed not to throw in this condition // return WyTimeSpec(tm_now.tv_sec,tm_now.tv_nsec);#else struct ::timeval tm_now; WyRet r; if((r=wy__cmtx.lock())!=Ok) { WY_THROW(r); } // // guess this function is not thread-safe, so a mutex supplied. // if(::gettimeofday(&tm_now,0)!=0) { // // man indicates all errors are associated with time zone, which is not // used int time(), so it is not supposed to happen here. // const int v=errno; wy__cmtx.unlock(); // not check the error, for result is the same. WY_THROW( WyRet(WyReply(v)) ); } if((r=wy__cmtx.unlock())!=Ok) { WY_THROW(r); } // // note: WyTimeSpec ctor is assumed not to throw in this condition // return WyTimeSpec(tm_now.tv_sec,tm_now.tv_usec*1000);#endif}catch(const WyTimeSpec::Reply& e) { WY_THROW( WyRet(e) );}catch(const WyRet& e) { WY_THROW( WyRet(e) );};WyRet Wy::set_systime(const WyTimeSpec& tm){#ifdef _POSIX_TIMERS if(::clock_settime(CLOCK_REALTIME,&tm.wy_timespec())!=0) { const int v=errno; switch(v) { case EPERM: WY_RETURN(Wym_EPERM); case EINVAL: WY_RETURN(Wym_ERANGE); // guess this reply case EFAULT: WY_THROW(WyRet(Wym_EFAULT)); // should not happen default: WY_RETURN( WyRet(WyReply(v)) ); }; } return(Ok);#else WyRet r; struct timeval tm_now; if((r=wy__cmtx.lock())!=Ok) { WY_THROW(r); } tm_now.tv_sec=wytm.second(); tm_now.tv_usec=static_cast<long>(wytm.nano()/1000); // guess this function is not thread-safe, so a mutex supplied const int en=(::settimeofday(&tm_now,0)==0)? 0:errno; if((r=wy__cmtx.unlock())!=Ok) { WY_THROW(r); } switch(en) { case 0: return(Ok); case EPERM: WY_RETURN(Wym_EPERM); case EINVAL: // FALL_THROUGH case EFAULT: WY_THROW(WyRet(Wym_EFAULT)); // should not happen default: WY_RETURN( WyRet(WyReply(en)) ); };#endif};//----------------------------------------------------------------------------//WyRet Wy::sleep(WyTimeSpec tsp){ WY__CANCEL_POINT; const int v( ::nanosleep(&tsp.wy_timespec(),NULL) ); WY__CANCEL_POINT; if(v!=0) { WY_RETURN(errno); } return(Ok);};WyRet Wy::sleep(WyTimeSpec req, WyTimeSpec& rem){ WY__CANCEL_POINT; const int v( ::nanosleep(&req.wy_timespec(),&rem.wy_timespec()) ); WY__CANCEL_POINT; if(v!=0) { WY_RETURN(errno); } return(Ok);};// [Interna] Dedicated for sleep_till// Unlock mtx and destroy mtx/cond//void static wy__sleep_till_cleanup(::pthread_cond_t& cond, ::pthread_mutex_t& mtx){ ::pthread_mutex_unlock(&mtx); ::pthread_mutex_destroy(&mtx); ::pthread_cond_destroy(&cond);};WyRet Wy::sleep_till(WyTimeSpec wtm){ ::pthread_cond_t cond; ::pthread_mutex_t mtx; ::pthread_mutex_init(&mtx,NULL); // manual: always ok const int v=::pthread_mutex_lock(&mtx); if(v!=0) { ::pthread_mutex_destroy(&mtx); WY_THROW( WyRet(WyReply(v)) ); // internal error } ::pthread_cond_init(&cond,NULL); // manual: always ok Wy_AtDestroy2<void,::pthread_cond_t&,::pthread_mutex_t&> rrid(wy__sleep_till_cleanup,cond,mtx); WY_RETURN( WyReply(::pthread_cond_timedwait(&cond,&mtx,&wtm.wy_timespec())));};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -