/* PIP - Platform Independent Primitives Timer Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program 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 3 of the License, or (at your option) any later version. This program 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 this program. If not, see . */ #include "pitimer.h" PITimer::PITimer(TimerEvent slot, void * data_) #ifdef WINDOWS : PIThread() { #else : PIObject() { #endif ret_func = slot; data = data_; #ifndef WINDOWS piMonitor.timers++; ti = -1; running = false; se.sigev_notify = SIGEV_THREAD; se.sigev_value.sival_ptr = this; se.sigev_notify_function = timer_event; se.sigev_notify_attributes = 0; lockRun = false; #endif reset(); /*addEvent("timeout"); addEventHandler(HANDLER(PITimer, start)); addEventHandler(HANDLER(PITimer, stop)); addEventHandler(HANDLER(PITimer, reset));*/ } PITimer::~PITimer() { #ifndef WINDOWS piMonitor.timers--; #endif stop(); } #ifndef WINDOWS void PITimer::start(double msecs) { if (ti == 0 || msecs < 0) return; spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000; spec.it_interval.tv_sec = (time_t)(msecs / 1000); spec.it_value = spec.it_interval; ti = timer_create(CLOCK_REALTIME, &se, &timer); if (ti == -1) { piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl; return; } timer_settime(timer, 0, &spec, 0); running = true; } void PITimer::timer_event(sigval e) { PITimer * ct = (PITimer * )e.sival_ptr; if (!ct->running) return; if (ct->lockRun) ct->lock(); if (ct->ret_func != 0) ct->ret_func(ct->data, 1); raiseEvent(ct, "timeout", ct->data, 1); piForeach (TimerSlot & i, ct->ret_funcs) { if (i.delim > ++(i.tick)) continue; i.tick = 0; if (i.slot != 0) i.slot(ct->data, i.delim); else if (ct->ret_func != 0) ct->ret_func(ct->data, i.delim); raiseEvent(ct, "timeout", ct->data, i.delim); } if (ct->lockRun) ct->unlock(); } bool PITimer::waitForFinish(int timeout_msecs) { if (timeout_msecs < 0) { while (running) msleep(1); return true; } int cnt = 0; while (running && cnt < timeout_msecs) { msleep(1); ++cnt; } return cnt < timeout_msecs; } #else void PITimer::run() { if (!running) return; if (lockRun) lock(); if (ret_func != 0) ret_func(data, 1); raiseEvent(this, "timeout", data, 1); piForeach (TimerSlot & i, ret_funcs) { if (i.delim > ++(i.tick)) continue; i.tick = 0; if (i.slot != 0) i.slot(data, i.delim); else if (ret_func != 0) ret_func(data, i.delim); raiseEvent(this, "timeout", data, i.delim); } if (lockRun) unlock(); } #endif double PITimer::elapsed_n() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (t_cur - t_st) * 1000000.; #else clock_gettime(0, &t_cur); return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec); #endif } double PITimer::elapsed_u() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (t_cur - t_st) * 1000.; #else clock_gettime(0, &t_cur); return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+3; #endif } double PITimer::elapsed_m() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (double)(t_cur - t_st); #else clock_gettime(0, &t_cur); return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+6; #endif } double PITimer::elapsed_s() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (t_cur - t_st) / 1000.; #else clock_gettime(0, &t_cur); return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+9; #endif } double PITimer::reset_time_n() { #ifdef WINDOWS t_cur = GetCurrentTime(); return t_st * 1000000.; #else clock_gettime(0, &t_cur); return t_st.tv_sec * 1.e+9 + t_st.tv_nsec; #endif } double PITimer::reset_time_u() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (t_cur - t_st) * 1000.; #else clock_gettime(0, &t_cur); return t_st.tv_sec * 1.e+6 + t_st.tv_nsec / 1.e+3; #endif } double PITimer::reset_time_m() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (double)(t_cur - t_st); #else clock_gettime(0, &t_cur); return t_st.tv_sec * 1.e+3 + t_st.tv_nsec / 1.e+6; #endif } double PITimer::reset_time_s() { #ifdef WINDOWS t_cur = GetCurrentTime(); return (t_cur - t_st) / 1000.; #else clock_gettime(0, &t_cur); return t_st.tv_sec + t_st.tv_nsec / 1.e+9; #endif } double PITimer::elapsed_system_n() { #ifdef WINDOWS long t_cur = GetCurrentTime(); return (t_cur * 1000000.); #else timespec t_cur; clock_gettime(0, &t_cur); return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec); #endif } double PITimer::elapsed_system_u() { #ifdef WINDOWS long t_cur = GetCurrentTime(); return (t_cur * 1000.); #else timespec t_cur; clock_gettime(0, &t_cur); return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3)); #endif } double PITimer::elapsed_system_m() { #ifdef WINDOWS long t_cur = GetCurrentTime(); return (double)t_cur; #else timespec t_cur; clock_gettime(0, &t_cur); return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6)); #endif } double PITimer::elapsed_system_s() { #ifdef WINDOWS long t_cur = GetCurrentTime(); return (t_cur / 1000.); #else timespec t_cur; clock_gettime(0, &t_cur); return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9)); #endif } PITime currentTime() { time_t rt = time(0); tm * pt = localtime(&rt); PITime t; t.seconds = pt->tm_sec; t.minutes = pt->tm_min; t.hours = pt->tm_hour; return t; } PIDate currentDate() { time_t rt = time(0); tm * pt = localtime(&rt); PIDate d; d.day = pt->tm_mday; d.month = pt->tm_mon + 1; d.year = pt->tm_year + 1900; return d; } PIString PITime::toString(const PIString & format) { PIString ts = format; ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0')); ts.replace("h", PIString::fromNumber(hours)); ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0')); ts.replace("m", PIString::fromNumber(minutes)); ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0')); ts.replace("s", PIString::fromNumber(seconds)); return ts; } PIString PIDate::toString(const PIString & format) { PIString ts = format; ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0')); ts.replace("yy", PIString::fromNumber(year).expandLeftTo(2, '0')); ts.replace("y", PIString::fromNumber(year)); ts.replace("mm", PIString::fromNumber(month).expandLeftTo(2, '0')); ts.replace("m", PIString::fromNumber(month)); ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0')); ts.replace("d", PIString::fromNumber(day)); return ts; } PIString time2string(const PITime & time, const PIString & format) { PIString ts = format; ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0')); ts.replace("h", PIString::fromNumber(time.hours)); ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0')); ts.replace("m", PIString::fromNumber(time.minutes)); ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0')); ts.replace("s", PIString::fromNumber(time.seconds)); return ts; } PIString date2string(const PIDate & date, const PIString & format) { PIString ts = format; ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0')); ts.replace("yy", PIString::fromNumber(date.year).expandLeftTo(2, '0')); ts.replace("y", PIString::fromNumber(date.year)); ts.replace("mm", PIString::fromNumber(date.month).expandLeftTo(2, '0')); ts.replace("m", PIString::fromNumber(date.month)); ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0')); ts.replace("d", PIString::fromNumber(date.day)); return ts; }