コード例 #1
0
ファイル: ramchain_main.c プロジェクト: apitests/libjl777
int32_t ramchain_idle(struct plugin_info *plugin)
{
    int32_t i,flag = 0;
    struct coin777 *coin; struct ramchain *ramchain;
    for (i=0; i<COINS.num; i++)
    {
        if ( (coin= COINS.LIST[i]) != 0 )
        {
            ramchain = &coin->ramchain;
            if ( ramchain->readyflag != 0 && (SUPERNET.gatewayid >= 0 || milliseconds() > ramchain->lastupdate+6000) )
            {
                flag += ramchain_update(coin,ramchain);
                ramchain->lastupdate = milliseconds();
            }
        }
    }
    return(flag);
}
コード例 #2
0
ファイル: SoundRecorder.cpp プロジェクト: krruzic/cpp3ds
SoundRecorder::SoundRecorder() :
m_thread            (&SoundRecorder::record, this),
m_sampleRate        (0),
m_processingInterval(milliseconds(100)),
m_isCapturing       (false)
{
    // Set the device name to the default device
    m_deviceName = getDefaultDevice();
}
コード例 #3
0
ファイル: connection_queue.cpp プロジェクト: BlackYoup/medusa
	void connection_queue::on_timeout(error_code const& e)
	{
		mutex_t::scoped_lock l(m_mutex);

		INVARIANT_CHECK;
#ifdef TORRENT_DEBUG
		function_guard guard_(m_in_timeout_function);
#endif

		TORRENT_ASSERT(!e || e == asio::error::operation_aborted);
		if (e) return;

		ptime next_expire = max_time();
		ptime now = time_now_hires() + milliseconds(100);
		std::list<entry> timed_out;
		for (std::list<entry>::iterator i = m_queue.begin();
			!m_queue.empty() && i != m_queue.end();)
		{
			if (i->connecting && i->expires < now)
			{
				std::list<entry>::iterator j = i;
				++i;
				timed_out.splice(timed_out.end(), m_queue, j, i);
				--m_num_connecting;
				continue;
			}
			if (i->expires < next_expire)
				next_expire = i->expires;
			++i;
		}

		// we don't want to call the timeout callback while we're locked
		// since that is a recepie for dead-locks
		l.unlock();

		for (std::list<entry>::iterator i = timed_out.begin()
			, end(timed_out.end()); i != end; ++i)
		{
#ifndef BOOST_NO_EXCEPTIONS
			try {
#endif
				i->on_timeout();
#ifndef BOOST_NO_EXCEPTIONS
			} catch (std::exception&) {}
#endif
		}
		
		l.lock();
		
		if (next_expire < max_time())
		{
			error_code ec;
			m_timer.expires_at(next_expire, ec);
			m_timer.async_wait(boost::bind(&connection_queue::on_timeout, this, _1));
		}
		try_connect(l);
	}
コード例 #4
0
ファイル: SoundRecorder.cpp プロジェクト: JackLinMaker/SFML
SoundRecorder::SoundRecorder() :
m_thread            (&SoundRecorder::record, this),
m_sampleRate        (0),
m_processingInterval(milliseconds(100)),
m_isCapturing       (false),
m_deviceName        (getDefaultDevice())
{

}
コード例 #5
0
void ScheduledTickQueue::AddTickAt(const ServerTime& serverTimePoint, ScheduledTick* scheduledTick)
{
    ASSERT_DEBUG(scheduledTick!=nullptr);
    ASSERT_DEBUG(scheduledTick->GetScheduledTime() == milliseconds(0) );
    
    scheduledTick->SetScheduledTime(serverTimePoint);
    
    m_Queue.push(scheduledTick);
}
コード例 #6
0
ファイル: Bullet.cpp プロジェクト: chmod96/Kurs_SFML
Bullet::Bullet(bool can, int f,bool inf)
{
	can_hurt_player = can;

	color = Color::White;
	frequency = milliseconds(f);

	infinite = inf;
	ammunition = 500;
}
コード例 #7
0
ファイル: ThreadManager.cpp プロジェクト: oreh07/Ewe
  void ThreadManager::start() {
    // don't replace to for(auto c : _subjects)
    for (auto c = _subjects.begin(); c != _subjects.end(); c++) {
      auto value = *c;
      _threads.push_back(thread([&value]() { value->start(); }));

      auto a = milliseconds(threadManagerSleep);
      sleep_for(a);
    }
  }
コード例 #8
0
ファイル: System.cpp プロジェクト: Khrylx/3DInnerCarving
bool NAMESPACE::Time::Every::expired()
{
  t_time now = milliseconds();
  if (now - m_TmStart > m_Delay) {
    m_TmStart = now;
    return (true);
  } else {
    return (false);
  }
}
コード例 #9
0
void ScheduledTickQueue::AddTickAfter(const milliseconds& timeDelay, ScheduledTick* scheduledTick)
{
    ASSERT_DEBUG(scheduledTick!=nullptr);
    ASSERT_DEBUG(scheduledTick->GetScheduledTime() == milliseconds(0) );
    
    const ServerTime scheduledTime = m_SharedTimer.Check()+timeDelay;
    scheduledTick->SetScheduledTime(scheduledTime);

    m_Queue.push(scheduledTick);
}
コード例 #10
0
// Check if we should abort.
bool should_abort_check() {
  tics++;
  if ((tics & ABORT_CHECK_PERIOD) == 0) {
    if (milliseconds() >= timeout) {
      abortf = true;
      return true;
    }
  }
  return false;
}
コード例 #11
0
// must be called with mLock and cblk.lock held. Callers must also hold strong references on
// the IAudioRecord and IMemory in case they are recreated here.
// If the IAudioRecord is successfully restored, the cblk pointer is updated
status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
{
    status_t result;

    if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
        LOGW("dead IAudioRecord, creating a new one");
        // signal old cblk condition so that other threads waiting for available buffers stop
        // waiting now
        cblk->cv.broadcast();
        cblk->lock.unlock();

        // if the new IAudioRecord is created, openRecord_l() will modify the
        // following member variables: mAudioRecord, mCblkMemory and mCblk.
        // It will also delete the strong references on previous IAudioRecord and IMemory
        result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
                mFrameCount, mFlags, getInput_l());
        if (result == NO_ERROR) {
            result = mAudioRecord->start();
        }
        if (result != NO_ERROR) {
            mActive = false;
        }

        // signal old cblk condition for other threads waiting for restore completion
        android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
        cblk->cv.broadcast();
    } else {
        if (!(cblk->flags & CBLK_RESTORED_MSK)) {
            LOGW("dead IAudioRecord, waiting for a new one to be created");
            mLock.unlock();
            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
            cblk->lock.unlock();
            mLock.lock();
        } else {
            LOGW("dead IAudioRecord, already restored");
            result = NO_ERROR;
            cblk->lock.unlock();
        }
        if (result != NO_ERROR || mActive == 0) {
            result = status_t(STOPPED);
        }
    }
    LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
         result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);

    if (result == NO_ERROR) {
        // from now on we switch to the newly created cblk
        cblk = mCblk;
    }
    cblk->lock.lock();

    LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);

    return result;
}
コード例 #12
0
void RenderingTaskWorkerRoutine::Run(const INT64 timeslice)
{
    SystemTimer& clientTimer = GooRoomVirtualClient::Instance().GetClientTimer();
    const ServerTime startTime = clientTimer.Check();
    const milliseconds timeSliceMil = milliseconds(timeslice);
    ServerTime availableTimeSlice = timeSliceMil - (clientTimer.Check()-startTime);
    
//    CFConnectionList& cfConnectionList = GooRoomVirtualClient::Instance().GetTemporaryCFConnectionList();
//    for(int i = 0; i < cfConnectionList.size(); ++i)
//    {
//        CFConnectionPointer connection = cfConnectionList[i];
//        
//        if(connection->CanBeDeleted())
//        {
//            GooRoomVirtualClient::Instance().RemoveTemporaryCFConnection(connection.get());
//        }
//    }
    
    if( m_IsPaused )
    {
        return;
    }
    Task* task = m_TaskQueue.Pop();
    while( task != nullptr )
    {
        task->Execute();
        delete task;
        task = nullptr;
        
        availableTimeSlice = timeSliceMil - (clientTimer.Check()-startTime);
        if( availableTimeSlice <= milliseconds(0) )
        {
            return;
        }
        
        if( m_IsPaused )
        {
            return;
        }
        task = m_TaskQueue.Pop();
    }
}
コード例 #13
0
bool PortMapping::UPnP::check(String &host)
{
	LogDebug("PortMapping::UPnP", "Trying UPnP...");
	
	Address addr;
	addr.set("239.255.255.250", 1900, AF_INET, SOCK_DGRAM);
	
	String message;
	message << "M-SEARCH * HTTP/1.1\r\n";
	message << "HOST: "<<addr<<"\r\n";
	message << "MAN: ssdp:discover\r\n";
	message << "MX: 10\r\n";
	message << "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n";
	
	int attempts = 3;
	duration timeout = milliseconds(250.);
	for(int i=0; i<attempts; ++i)
	{
		BinaryString dgram(message);
		mSock.write(dgram, addr);
		
		using clock = std::chrono::steady_clock;
		std::chrono::time_point<clock> end = clock::now() + std::chrono::duration_cast<clock::duration>(timeout);
		
		while(clock::now() < end)
		{
			Address sender;
			duration left = end - clock::now();
			if(!mSock.read(dgram, sender, left)) break;
			
			if(!sender.isPrivate()) continue;
			
			LogDebug("PortMapping::UPnP", String("Got response from ") + sender.toString());
			try {
				if(parse(dgram))
				{
					LogDebug("PortMapping::UPnP", "UPnP is available");
					mGatewayAddr = sender;
					host = mExternalHost;
					return true;
				}
			}
			catch(const Exception &e)
			{
				// Nothing to do
			}
		}
		
		timeout*= 2;
	}
	
	//LogDebug("PortMapping::UPnP", "UPnP is not available");
	return false;
}
コード例 #14
0
void AsyncTaskNonPeriodic::_OnComplete(bool aSuccess)
{
	timer_clock::time_point now = mpGroup->GetUTC();
	if(aSuccess) {
		mIsComplete = true;
		mNextRunTime = timer_clock::time_point::max();
	}
	else {
		mNextRunTime = now + milliseconds(mRetryDelay);
	}
}
コード例 #15
0
ファイル: hgs-jni.cpp プロジェクト: hyz/cpp-snippets
static void _TRACE_PRINT_RATE() {
    tc[0].tp = Clock::now();
    unsigned ms = milliseconds(tc[0].tp - tc[1].tp);
    if (ms > 3000) {
        LOGD("F-rate: %.2f/%.2f, %u%+d%+d"
                , (tc[0].ns.nfr - tc[1].ns.nfr)*1000.0/ms
                , (tc[0].ns.out - tc[1].ns.out)*1000.0/ms
                , tc[0].ns.nfr, -int(tc[0].ns.nfr-tc[0].ns.dec), -int(tc[0].ns.dec-tc[0].ns.out));
        tc[1] = tc[0];
    }
}
コード例 #16
0
void idle2()
{
    static double lastmilli;
    uint32_t NXTblock;
    while ( INSTANTDEX.readyflag == 0 )
        sleep(1);
    while ( 1 )
    {
        if ( milliseconds() < (lastmilli + 5000) )
            msleep(100);
        NXTblock = _get_NXTheight(0);
        if ( 1 && NXTblock != prices777_NXTBLOCK )
        {
            prices777_NXTBLOCK = NXTblock;
            InstantDEX_update(SUPERNET.NXTADDR,SUPERNET.NXTACCTSECRET);
            //fprintf(stderr,"done idle NXT\n");
        }
        lastmilli = milliseconds();
    }
}
コード例 #17
0
ファイル: http_connection.cpp プロジェクト: codeboost/libertv
void http_connection::rate_limit(int limit)
{
	if (!m_limiter_timer_active)
	{
		m_limiter_timer_active = true;
		m_limiter_timer.expires_from_now(milliseconds(250));
		m_limiter_timer.async_wait(bind(&http_connection::on_assign_bandwidth
			, shared_from_this(), _1));
	}
	m_rate_limit = limit;
}
コード例 #18
0
ファイル: system777.c プロジェクト: destenson/jl777--btcd
double estimate_completion(double startmilli,int32_t processed,int32_t numleft)
{
    double elapsed,rate;
    if ( processed <= 0 )
        return(0.);
    elapsed = (milliseconds() - startmilli);
    rate = (elapsed / processed);
    if ( rate <= 0. )
        return(0.);
    //printf("numleft %d rate %f\n",numleft,rate);
    return(numleft * rate);
}
コード例 #19
0
bool PhysicalLayerMonitor::WaitForShutdown(millis_t aTimeout)
{
	std::unique_lock<std::mutex> lock(mMutex);
	while(!mFinalShutdown) {
		if(aTimeout >= 0) {
			mCondition.wait_for(lock, milliseconds(aTimeout));
			break;
		}
		else mCondition.wait(lock);
	}
	return mFinalShutdown;
}
コード例 #20
0
ファイル: relays777.c プロジェクト: satindergrewal/btcd
void calc_nonces(char *destpoint)
{
    char buf[8192],*str; int32_t n = 0; double endmilli = milliseconds() + 60000;
    //printf("calc_nonces.(%s)\n",destpoint);
    memset(SUPERNET.nonces,0,sizeof(SUPERNET.nonces));
    SUPERNET.numnonces = 0;
    while ( milliseconds() < endmilli && n < sizeof(SUPERNET.nonces)/sizeof(*SUPERNET.nonces) )
    {
        sprintf(buf,"{\"plugin\":\"relay\",\"counter\":\"%d\",\"destplugin\":\"relay\",\"method\":\"nonce\",\"broadcast\":\"8\",\"lbendpoint\":\"%s\",\"relaypoint\":\"%s\",\"globalpoint\":\"%s\",\"destpoint\":\"%s\",\"NXT\":\"%s\"}",n,SUPERNET.lbendpoint,SUPERNET.relayendpoint,SUPERNET.globalendpoint,destpoint,SUPERNET.NXTADDR);
        if ( (str= busdata_sync(&SUPERNET.nonces[n],buf,"8",0)) != 0 )
        {
            //fprintf(stderr,"send.(%s)\n",buf);
            free(str);
            n++;
        }
    }
    SUPERNET.numnonces = n;
    SUPERNET.noncing = 0;
    printf("finished noncing for (%s)\n",destpoint);
    free(destpoint);
}
コード例 #21
0
ファイル: VtoRouter.cpp プロジェクト: AlanMarshall/dnp3
VtoRouter::VtoRouter(const VtoRouterSettings& arSettings, Logger* apLogger, IVtoWriter* apWriter, IPhysicalLayerAsync* apPhysLayer) :
	Loggable(apLogger),
	PhysicalLayerMonitor(apLogger, apPhysLayer, milliseconds(arSettings.MIN_OPEN_RETRY_MS), milliseconds(arSettings.MAX_OPEN_RETRY_MS)),
	IVtoCallbacks(arSettings.CHANNEL_ID),
	mpVtoWriter(apWriter),
	mReadBuffer(1024),
	mWriteData(0)
{
	assert(apLogger != NULL);
	assert(apWriter != NULL);
	assert(apPhysLayer != NULL);
}
コード例 #22
0
ファイル: System.cpp プロジェクト: Khrylx/3DInnerCarving
t_time NAMESPACE::Time::Timings::measure(const char *name)
{
  t_time now = milliseconds();
  t_time tm  = now - m_TmStart;
  t_time h   = ( tm/(1000*60*60));
  t_time m   = ((tm/(1000*60)) % 60);
  t_time s   = ((tm/1000)      % 60);
  t_time ms  = tm % 1000;
  std::cerr << LibSL::CppHelpers::sprint("%s:(%s) %2d hours %2d min %2ds %4d ms (+ %4d ms)\n",m_Name,name,(int)h,(int)m,(int)s,(int)ms,uint(now - m_TmLast));
  m_TmLast = now;
  return tm;
}
コード例 #23
0
ファイル: fpga_event.cpp プロジェクト: tomaszkapela/opae-sdk
fpga_event::poll_result fpga_event::poll(int timeout_msec)
{
    struct epoll_event events[1];
    if (epollfd_ == -1)
    {
        return poll_result::error;
    }
    if (cancel_) return poll_result::canceled;
    int num_events = 0;
    auto begin = high_resolution_clock::now();
    bool timedout = false;
    int fd = -1;

    while(!cancel_ && !timedout && num_events == 0)
    {
        num_events = epoll_wait(epollfd_, events, 1, 0);
        if (timeout_msec > 0)
        {
            timedout = high_resolution_clock::now() - begin > milliseconds(timeout_msec) &&
                       num_events == 0;
        }

        if (!timedout)
        {
            std::this_thread::sleep_for(microseconds(100));
        }
    }

    if (cancel_) return poll_result::canceled;

    if (timedout)
    {
        return poll_result::timeout;
    }

    if (num_events < 0)
    {
        return errno == EINTR ? poll_result::canceled : poll_result::error;
    }

    if(fpgaGetOSObjectFromEventHandle(handle_, &fd) != 0)
    {
        return poll_result::error;
    }

    if (num_events == 1 && events[0].data.fd == fd)
    {
        return poll_result::triggered;
    }

    return poll_result::unknown;
}
コード例 #24
0
ファイル: hgs-jni.cpp プロジェクト: hyz/cpp-snippets
    void run()
    {
        if (!args_->setup_ok_) {
            ERR_MSG("Main thread: setup fail");
            return;
        }
        LOGD("Main thread");

        auto& a = *args_;
        unsigned nF = 0;
        while (!thread.stopped) {
            Image img = {}; // OMX_BUFFERHEADERTYPE bh;
            if (!a.vdec.outpoll(img, &thread.stopped)) {
                ERR_MSG("%d !vdec:poll", (int)thread.stopped);
                break;
            }
            ++nF;

            static Image copy = img;
            auto tp = Clock::now();
            if (copy.pdata == img.pdata) {
                copy.porg = copy.pdata = (uint8_t*)malloc(img.size);//(img.pdata,  img.size);
            }
            if (copy.size >= img.size) {
                copy.size = img.size;
                memcpy(copy.pdata, img.pdata, img.size);
            }
            LOGD("copy mills %u", milliseconds(Clock::now()-tp));

            if (a.renderer_ok_) {
                auto tp = Clock::now();
                a.vgl.renderFrame(&img);
                LOGD("renderFrame %u", milliseconds(Clock::now()-tp));
            }
        }

        LOGD("Main End: nF %u, stopped %d", nF, int(thread.stopped));
    }
コード例 #25
0
	std::string UnifiedTime::toHumanReadableStringFromEpoch() const
	{
		std::ostringstream oss;
		Value seconds(value / 1000);
		Value milliseconds(value % 1000);
		time_t t(seconds);
		char *timeString = ctime(&t);
		timeString[strlen(timeString) - 1] = 0;
		oss << "[";
		oss << timeString << " ";
		oss << std::setfill('0') << std::setw(3) << milliseconds;
		oss << "]";
		return oss.str();
	}
コード例 #26
0
ファイル: AK.cpp プロジェクト: Altez/Zombie-Defence
AK::AK()
{
	dmg = 50;
	maxAmmo = 30;
	currentAmmo = maxAmmo;
	reloadingTime = seconds(1.5);
	fireSpeed = milliseconds(100);

	weaponPicture.loadFromFile("files/AK.png");
	shootSoundBuffer.loadFromFile("files/AKShootSound.wav");
	shootSound.setBuffer(shootSoundBuffer);
	reloadSoundBuffer.loadFromFile("files/AKReloadSound.wav");
	reloadSound.setBuffer(reloadSoundBuffer);
}
コード例 #27
0
ファイル: teleport777.c プロジェクト: Bitcoinsulting/libjl777
int32_t teleport_idle(struct plugin_info *plugin)
{
    int32_t pmlen; char *pmstr,*decoded; cJSON *decodedjson; uint64_t r;
    if ( TELEPORT.availablemilli == 0 )
    {
        randombytes((void *)&r,sizeof(r));
        TELEPORT.availablemilli = (uint64_t)(milliseconds() + SUPERNET.telepathicdelay + (r % SUPERNET.telepathicdelay));
    }
    if ( milliseconds() > TELEPORT.availablemilli && (pmstr= queue_dequeue(&TelepathyQ,1)) != 0 )
    {
        if ( is_hexstr(pmstr) != 0 )
        {
            pmlen = (int32_t)strlen(pmstr);
            decoded = malloc((pmlen >> 1) + 1);
            decode_hex((void *)decoded,pmlen,pmstr);
            decoded[pmlen] = 0;
            if ( (decodedjson= cJSON_Parse(decoded)) != 0 )
            {
                telepathic_remotejson(decodedjson);
                free_json(decodedjson);
            } else telepathic_remotebinary(pmstr,decoded,pmlen);
            free(decoded);
        } else telepathic_remotestr(pmstr);
コード例 #28
0
ファイル: Timeout.cpp プロジェクト: FaddliLWibowo/BtEmbedded
bool Timeout::check() {
   if (mTimedOut) {
      return true;
   }

   uint32_t up = milliseconds() - mStart;
   //BT_LOG(DEBUG) << "timeout check - " << up << " > " << mMilliseconds;
   if (up > mMilliseconds) {
      mTimedOut = true;
      return true;
   }

   return false;
}
コード例 #29
0
void FlowPortTest::Execute(void)
{
    cout << "Executing FlowPortTest" << endl;
    Simulator::Init(L"ExteriorLight.ernest");
    Simulator::SetDuration(seconds(10));

    BinaryTraceRecorder trace_recorder("ExteriorLight.ernest.bt1");
    trace_recorder.AddEventMapping("ExteriorLight.ernest#//@structureModel.0/@modules.23/@ports.3", 0);
    Simulator::SetTraceRecorder(&trace_recorder);

    //
    // Building the hardware topology
    //

    // Create ECU
    Ecu ecu1("ECU1");
    Ecu ecu2("ECU2");

    // Create the bus
    SimpleBus bus("SimpleBus");

    // Adding bus interfaces to ecus
    SimpleBusInterface *ecu1BusInterface = ecu1.AddHardware<SimpleBusInterface>();
    SimpleBusInterface *ecu2BusInterface = ecu2.AddHardware<SimpleBusInterface>();

    // Attaching the interfaces to the bus
    bus.AttachInterface(ecu1BusInterface);
    bus.AttachInterface(ecu2BusInterface);

    //
    // Configuring the software system
    //

    // Set scheduler
    OsekOS *os1 = ecu1.GetService<OsekOS>();
    OsekOS *os2 = ecu2.GetService<OsekOS>();

    os1->SetScheduler<RoundRobin>();
    os2->SetScheduler<RoundRobin>();

    // Create one task with two SWF
    Task* t1 = os1->DeclareTask<SwfA>(0,
                                      milliseconds(0),
                                      milliseconds(40),
                                      new WorstCaseExecutionSpecification(milliseconds(20)));
    Task* t2 = os2->DeclareTask<SwfB>(0,
                                      milliseconds(10),
                                      milliseconds(40),
                                      new WorstCaseExecutionSpecification(milliseconds(20)));

    SwfA* swfA = dynamic_cast<SwfA*>(t1->GetSwf());
    SwfB* swfB = dynamic_cast<SwfB*>(t2->GetSwf());

    connect_ports(swfA->src_counter, swfB->counter);

    Simulator::Start();
}
コード例 #30
0
ファイル: apic_timer.cpp プロジェクト: tanisman/IncludeOS
  void APIC_Timer::calibrate()
  {
    init();

    if (ticks_per_micro != 0) {
      // make sure timers are delay-initalized
      const auto irq = LAPIC_IRQ_TIMER;
      Events::get().subscribe(irq, start_timers);
      // soft-trigger IRQ immediately
      Events::get().trigger_event(irq);
      return;
    }

    // start timer (unmask)
    INFO("APIC", "Measuring APIC timer...");

    auto& lapic = APIC::get();
    // See: Vol3a 10.5.4.1 TSC-Deadline Mode
    // 0xFFFFFFFF --> ~68 seconds
    // 0xFFFFFF   --> ~46 milliseconds
    lapic.timer_begin(0xFFFFFFFF);
    // measure function call and tick read overhead
    uint32_t overhead;
    [&overhead] {
        overhead = APIC::get().timer_diff();
    }();
    // restart counter
    lapic.timer_begin(0xFFFFFFFF);

    /// use PIT to measure <time> in one-shot ///
    PIT::oneshot(milliseconds(CALIBRATION_MS),
    [overhead] {
      uint32_t diff = APIC::get().timer_diff() - overhead;
      assert(ticks_per_micro == 0);
      // measure difference
      ticks_per_micro = diff / CALIBRATION_MS / 1000;
      // stop APIC timer
      APIC::get().timer_interrupt(false);

      //printf("* APIC timer: ticks %ums: %u\t 1mi: %u\n",
      //       CALIBRATION_MS, diff, ticks_per_micro);
      start_timers();

      // with SMP, signal everyone else too (IRQ 1)
      if (SMP::cpu_count() > 1) {
        APIC::get().bcast_ipi(0x21);
      }
    });
  }