Пример #1
0
int queue_dequeue(volatile void *q, void *elt, int timeout)
{
	volatile struct generic_queue *gq = q;

	if (queue_is_empty(q)) {
		if (-1 == timeout) {
			while (queue_is_empty(q)) {
				yield(NULL);
			}
		} else {
			const int expiration_time = get_system_time() + timeout;

			while (queue_is_empty(q) && (get_system_time() < expiration_time)) {
				yield(NULL);
			}

			/* If the queue is still full, return an error */
			if (queue_is_empty(gq)) {
				return -1;
			}
		}
	}

	memcpy(elt, (void*)gq->head, gq->item_size);

	if (QUEUE_HEAD_WRAP(gq)) {
		gq->head = gq->memory;
	} else if (gq->len > 1) {
		gq->head = (uint8_t *)gq->head + gq->item_size;
	}
	gq->len--;
	return 0;
}
Пример #2
0
/* get-current_time -- get time as 60 bit 100ns ticks since whenever.
   Compensate for the fact that real clock resolution is less than 100ns. */
static void get_current_time(uuid_time_t * timestamp)
{
    uuid_time_t         time_now;
    static uuid_time_t  time_last;
    static unsigned16   uuids_this_tick;
    static int          inited = 0;
    
    if (!inited) {
        get_system_time(&time_now);
        uuids_this_tick = UUIDS_PER_TICK;
        inited = 1;
    };
	
    while (1) {
	get_system_time(&time_now);
        
	/* if clock reading changed since last UUID generated... */
	if (time_last != time_now) {
	    /* reset count of uuids gen'd with this clock reading */
	    uuids_this_tick = 0;
	    break;
	};
	if (uuids_this_tick < UUIDS_PER_TICK) {
	    uuids_this_tick++;
	    break;
	};        /* going too fast for our clock; spin */
    };    /* add the count of uuids to low order bits of the clock reading */

    *timestamp = time_now + uuids_this_tick;
    time_last = time_now;
}
Пример #3
0
s32 sceKernelWaitEventFlag(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat, vm::ptr<u32> pTimeout)
{
	sceLibKernel.Error("sceKernelWaitEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout);

	const u64 start_time = pTimeout ? get_system_time() : 0;
	const u32 timeout = pTimeout ? pTimeout->value() : 0;

	const auto evf = idm::get<psv_event_flag_t>(evfId);

	if (!evf)
	{
		return SCE_KERNEL_ERROR_INVALID_UID;
	}

	std::unique_lock<std::mutex> lock(evf->mutex);

	const u32 result = evf->pattern.atomic_op(event_flag_try_poll, bitPattern, waitMode);

	if (event_flag_test(result, bitPattern, waitMode))
	{
		if (pResultPat) *pResultPat = result;

		return SCE_OK;
	}

	// fixup register values for external use
	context.GPR[1] = bitPattern;
	context.GPR[2] = waitMode;

	// add waiter; attributes are ignored in current implementation
	sleep_queue_entry_t waiter(context, evf->sq);

	while (!context.unsignal())
	{
		CHECK_EMU_STATUS;

		if (pTimeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				context.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT;
				context.GPR[1] = evf->pattern;
				break;
			}

			context.cv.wait_for(lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			context.cv.wait(lock);
		}
	}

	if (pResultPat) *pResultPat = context.GPR[1];
	if (pTimeout) *pTimeout = static_cast<u32>(std::max<s64>(0, timeout - (get_system_time() - start_time)));

	return context.GPR[0];
}
Пример #4
0
int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, mem32_t platinumId)
{
	sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=%d, handle=%d, trophyId=%d, platinumId_addr=0x%x)",
		context, handle, trophyId, platinumId.GetAddr());
	
	if (!s_npTrophyInstance.m_bInitialized)
		return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
	if (!platinumId.IsGood())
		return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
	// TODO: There are other possible errors

	sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
	if (trophyId >= ctxt.tropusr->GetTrophiesCount())
		return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
	if (ctxt.tropusr->GetTrophyUnlockState(trophyId))
		return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;

	u64 timestamp1 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
	u64 timestamp2 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
	ctxt.tropusr->UnlockTrophy(trophyId, timestamp1, timestamp2);
	std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPUSR.DAT";
	ctxt.tropusr->Save(trophyPath);

	platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
	return CELL_OK;
}
Пример #5
0
bool
mutex::timed_lock( system_time const& abs_time)
{
	if ( abs_time.is_infinity() )
	{
		lock();
		return true;
	}

	if ( get_system_time() >= abs_time)
		return false;

	for (;;)
	{
		if ( try_lock() ) break;

		if ( get_system_time() >= abs_time)
			return false;

		this_thread::interruption_point();
		if ( this_task::runs_in_pool() )
			this_task::yield();
		else
			this_thread::yield();	
		this_thread::interruption_point();
	}

	return true;
}
Пример #6
0
s32 sys_timer_sleep(u32 sleep_time)
{
	sys_timer.trace("sys_timer_sleep(sleep_time=%d)", sleep_time);

	const u64 start_time = get_system_time();

	const u64 useconds = sleep_time * 1000000ull;

	u64 passed;

	while (useconds > (passed = get_system_time() - start_time) + 1000)
	{
		CHECK_EMU_STATUS;

		std::this_thread::sleep_for(1ms);
	}
	
	if (useconds > passed)
	{
		std::this_thread::sleep_for(std::chrono::microseconds(useconds - passed));
	}

	CHECK_EMU_STATUS;
	return CELL_OK;
}
Пример #7
0
	VkResult wait_for_event(VkEvent event, u64 timeout)
	{
		u64 t = 0;
		while (true)
		{
			switch (const auto status = vkGetEventStatus(*g_current_renderer, event))
			{
			case VK_EVENT_SET:
				return VK_SUCCESS;
			case VK_EVENT_RESET:
				break;
			default:
				die_with_error(HERE, status);
				return status;
			}

			if (timeout)
			{
				if (!t)
				{
					t = get_system_time();
					continue;
				}

				if ((get_system_time() - t) > timeout)
				{
					LOG_ERROR(RSX, "[vulkan] vk::wait_for_event has timed out!");
					return VK_TIMEOUT;
				}
			}

			//std::this_thread::yield();
			_mm_pause();
		}
	}
Пример #8
0
s32 _sys_lwcond_queue_wait(PPUThread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 timeout)
{
	sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto cond = idm::get<lv2_lwcond_t>(lwcond_id);
	const auto mutex = idm::get<lv2_lwmutex_t>(lwmutex_id);

	if (!cond || !mutex)
	{
		return CELL_ESRCH;
	}

	// finalize unlocking the mutex
	mutex->unlock(lv2_lock);

	// add waiter; protocol is ignored in current implementation
	sleep_queue_entry_t waiter(ppu, cond->sq);

	// potential mutex waiter (not added immediately)
	sleep_queue_entry_t mutex_waiter(ppu, cond->sq, defer_sleep);

	while (!ppu.unsignal())
	{
		CHECK_EMU_STATUS;

		if (timeout && waiter)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				// try to reown the mutex if timed out
				if (mutex->signaled)
				{
					mutex->signaled--;

					return CELL_EDEADLK;
				}
				else
				{
					return CELL_ETIMEDOUT;
				}
			}

			ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			ppu.cv.wait(lv2_lock);
		}
	}

	// return cause
	return ppu.GPR[3] ? CELL_EBUSY : CELL_OK;
}
Пример #9
0
s32 sys_rwlock_rlock(PPUThread& ppu, u32 rw_lock_id, u64 timeout)
{
	sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=0x%x, timeout=0x%llx)", rw_lock_id, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto rwlock = idm::get<lv2_rwlock_t>(rw_lock_id);

	if (!rwlock)
	{
		return CELL_ESRCH;
	}

	if (!rwlock->writer && rwlock->wsq.empty())
	{
		if (!++rwlock->readers)
		{
			throw EXCEPTION("Too many readers");
		}

		return CELL_OK;
	}

	// add waiter; protocol is ignored in current implementation
	sleep_queue_entry_t waiter(ppu, rwlock->rsq);

	while (!ppu.unsignal())
	{
		CHECK_EMU_STATUS;

		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				return CELL_ETIMEDOUT;
			}

			ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			ppu.cv.wait(lv2_lock);
		}
	}

	if (rwlock->writer || !rwlock->readers)
	{
		throw EXCEPTION("Unexpected");
	}

	return CELL_OK;
}
Пример #10
0
s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout)
{
	sys_event.Log("sys_event_queue_receive(equeue_id=0x%x, event=*0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto queue = Emu.GetIdManager().get<lv2_event_queue_t>(equeue_id);

	if (!queue)
	{
		return CELL_ESRCH;
	}

	if (queue->type != SYS_PPU_QUEUE)
	{
		return CELL_EINVAL;
	}

	// protocol is ignored in current implementation
	queue->waiters++;

	while (queue->events.empty())
	{
		CHECK_EMU_STATUS;

		if (queue->cancelled)
		{
			return CELL_ECANCELED;
		}

		if (timeout && get_system_time() - start_time > timeout)
		{
			queue->waiters--;
			return CELL_ETIMEDOUT;
		}

		queue->cv.wait_for(lv2_lock, std::chrono::milliseconds(1));
	}

	// event data is returned in registers (second arg is not used)
	auto& event = queue->events.front();
	CPU.GPR[4] = event.source;
	CPU.GPR[5] = event.data1;
	CPU.GPR[6] = event.data2;
	CPU.GPR[7] = event.data3;

	queue->events.pop_front();
	queue->waiters--;

	return CELL_OK;
}
Пример #11
0
s32 sys_semaphore_wait(u32 sem_id, u64 timeout)
{
	sys_semaphore.Log("sys_semaphore_wait(sem_id=%d, timeout=%lld)", sem_id, timeout);

	Semaphore* sem;
	if (!Emu.GetIdManager().GetIDData(sem_id, sem))
	{
		return CELL_ESRCH;
	}

	const u32 tid = GetCurrentPPUThread().GetId();
	const u64 start_time = get_system_time();

	{
		std::lock_guard<std::mutex> lock(sem->m_mutex);
		if (sem->m_value > 0)
		{
			sem->m_value--;
			return CELL_OK;
		}
		sem->m_queue.push(tid);
	}

	while (true)
	{
		if (Emu.IsStopped())
		{
			sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem_id);
			return CELL_OK;
		}

		if (timeout && get_system_time() - start_time > timeout)
		{
			sem->m_queue.invalidate(tid);
			return CELL_ETIMEDOUT;
		}

		if (tid == sem->signal)
		{
			std::lock_guard<std::mutex> lock(sem->m_mutex);

			if (tid != sem->signal)
			{
				continue;
			}
			sem->signal = 0;
			// TODO: notify signaler
			return CELL_OK;
		}

		SM_Sleep();
	}
}
Пример #12
0
s32 sys_semaphore_wait(PPUThread& ppu, u32 sem_id, u64 timeout)
{
	sys_semaphore.Log("sys_semaphore_wait(sem_id=0x%x, timeout=0x%llx)", sem_id, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto sem = idm::get<lv2_sema_t>(sem_id);

	if (!sem)
	{
		return CELL_ESRCH;
	}

	if (sem->value > 0)
	{
		sem->value--;
		
		return CELL_OK;
	}

	// add waiter; protocol is ignored in current implementation
	sleep_queue_entry_t waiter(ppu, sem->sq);

	while (!ppu.unsignal())
	{
		CHECK_EMU_STATUS;

		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				return CELL_ETIMEDOUT;
			}

			ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			ppu.cv.wait(lv2_lock);
		}
	}

	return CELL_OK;
}
Пример #13
0
s32 _sys_lwmutex_lock(PPUThread& ppu, u32 lwmutex_id, u64 timeout)
{
	sys_lwmutex.Log("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto mutex = idm::get<lv2_lwmutex_t>(lwmutex_id);

	if (!mutex)
	{
		return CELL_ESRCH;
	}

	if (mutex->signaled)
	{
		mutex->signaled--;

		return CELL_OK;
	}

	// add waiter; protocol is ignored in current implementation
	sleep_queue_entry_t waiter(ppu, mutex->sq);

	while (!ppu.unsignal())
	{
		CHECK_EMU_STATUS;

		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				return CELL_ETIMEDOUT;
			}

			ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			ppu.cv.wait(lv2_lock);
		}
	}

	return CELL_OK;
}
Пример #14
0
s32 sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
{
	sys_semaphore.trace("sys_semaphore_wait(sem_id=0x%x, timeout=0x%llx)", sem_id, timeout);

	const u64 start_time = get_system_time();

	LV2_LOCK;

	const auto sem = idm::get<lv2_sema_t>(sem_id);

	if (!sem)
	{
		return CELL_ESRCH;
	}

	if (sem->value > 0)
	{
		sem->value--;
		
		return CELL_OK;
	}

	// add waiter; protocol is ignored in current implementation
	sleep_entry<cpu_thread> waiter(sem->sq, ppu);

	while (!ppu.state.test_and_reset(cpu_state::signal))
	{
		CHECK_EMU_STATUS;

		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				return CELL_ETIMEDOUT;
			}

			get_current_thread_cv().wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
		}
		else
		{
			get_current_thread_cv().wait(lv2_lock);
		}
	}

	return CELL_OK;
}
Пример #15
0
void Emulator::Resume()
{
	// Get pause start time
	const u64 time = m_pause_start_time.exchange(0);

	// Try to increment summary pause time
	if (time)
	{
		m_pause_amend_time += get_system_time() - time;
	}

	// Try to resume
	if (!m_status.compare_and_swap_test(Paused, Running))
	{
		return;
	}

	if (!time)
	{
		LOG_ERROR(GENERAL, "Emulator::Resume() error: concurrent access");
	}

	SendDbgCommand(DID_RESUME_EMU);

	for (auto& thread : get_all_cpu_threads())
	{
		thread->state -= cpu_state::dbg_global_pause;
		thread->safe_notify();
	}

	rpcs3::on_resume()();

	SendDbgCommand(DID_RESUMED_EMU);
}
Пример #16
0
static void
print_mem_stats(process_info_t *pi, char reschar, int version)
{
    WCHAR qual_name[MAX_CMDLINE];
    int cpu = -1, user = -1;
    LONGLONG wallclock_time = get_system_time() - pi->CreateTime.QuadPart;
    LONGLONG scheduled_time = pi->UserTime.QuadPart + pi->KernelTime.QuadPart;
    static LONGLONG firstproc_time = 0;
    if (wallclock_time != (LONGLONG) 0) {
        cpu = (int) ((100 * scheduled_time) / wallclock_time);
    }
    if (scheduled_time != (LONGLONG) 0) {
        user = (int) ((100 * pi->UserTime.QuadPart) / scheduled_time);
    }

    /* Total user and kernel time scheduled for all processes.  Don't include idle
     * process, and if -skip option is specified don't include DRview.exe */
    if (wcsicmp(pi->ProcessName, L"") != 0
        && (wcsicmp(pi->ProcessName, L"drview.exe") != 0 || !skip)) {
        total_user   += pi->UserTime.QuadPart;
        total_kernel += pi->KernelTime.QuadPart;
    }

    /* CreateTime.QuadPart is a counter since 1916.  Both idle process and
     * System have create time of 0, so report create time, in ms, relative to
     * smss.exe */
    if (wcsicmp(pi->ProcessName, L"") == 0
        || wcsicmp(pi->ProcessName, L"system") == 0
        || wcsicmp(pi->ProcessName, L"smss.exe") == 0) {
        firstproc_time = pi->CreateTime.QuadPart;
    }

    generate_process_name(pi, qual_name, BUFFER_SIZE_ELEMENTS(qual_name));

    /* single line best so can line up columns and process output easily */
    fprintf(fp, "%-23.23S %5d %c %5d %2d%% %3d%% %5d %3d %7d %7d %8d %7d %7d %7d %7d %5d %5d %5d %5d %5d",
            qual_name, pi->ProcessID, reschar, version,
            cpu, user,
            pi->HandleCount, pi->ThreadCount,
            pi->VmCounters.PeakVirtualSize/1024,
            pi->VmCounters.VirtualSize/1024,
            pi->VmCounters.PeakPagefileUsage/1024,
            pi->VmCounters.PagefileUsage/1024, /* aka Private */
            pi->VmCounters.PeakWorkingSetSize/1024,
            pi->VmCounters.WorkingSetSize/1024,
            pi->VmCounters.PageFaultCount,
            pi->VmCounters.QuotaPeakPagedPoolUsage/1024,
            pi->VmCounters.QuotaPagedPoolUsage/1024,
            pi->VmCounters.QuotaPeakNonPagedPoolUsage/1024,
            pi->VmCounters.QuotaNonPagedPoolUsage/1024,
            pi->InheritedFromProcessID);
    if (showtime) {
        /* QuadPart is in ticks 1 tick = 100 nano secs. In ms = n * 100/(1000*1000) */
        fprintf(fp, " %15I64d %15I64d %15I64d",
                    (pi->UserTime.QuadPart/10000),
                    (pi->KernelTime.QuadPart/10000),
                    ((pi->CreateTime.QuadPart - firstproc_time)/10000));
    }
    fprintf(fp, "\n");
}
Пример #17
0
forceinline void update_time_and_tick(lm_time_param_t* pm)
{
    lm_time_t*      pt = pm->pt;

    /** update system time, every 32 milliseconds
        update tick time when the tick_zero_time be set
    */
    if((pm->count & 0x1f) == 0)
    {
        int64_t btime = pt->system_time;
        get_system_time(&pt->system_time);
        if(pt->tick_zero_time != 0)
        {
            pt->tick_time += pt->tick_rate*(pt->system_time - btime);
        }
    }
    else
    {
        pt->system_time += 10000LL * (int64_t)pm->wTimerDelay;

        if(pt->tick_zero_time != 0)
        {
            pt->tick_time += pt->tick_rate * (int64_t)pm->wTimerDelay;
        }
    }

    pm->count ++;
}
Пример #18
0
bool Emulator::Pause()
{
	const u64 start = get_system_time();

	// Try to pause
	if (!m_state.compare_and_swap_test(system_state::running, system_state::paused))
	{
		return m_state.compare_and_swap_test(system_state::ready, system_state::paused);
	}

	GetCallbacks().on_pause();

	// Update pause start time
	if (m_pause_start_time.exchange(start))
	{
		LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access");
	}

	auto on_select = [](u32, cpu_thread& cpu)
	{
		cpu.state += cpu_flag::dbg_global_pause;
	};

	idm::select<ppu_thread>(on_select);
	idm::select<ARMv7Thread>(on_select);
	idm::select<RawSPUThread>(on_select);
	idm::select<SPUThread>(on_select);

	if (auto mfc = fxm::check<mfc_thread>())
	{
		on_select(0, *mfc);
	}

	return true;
}
Пример #19
0
bool Emulator::Pause()
{
	const u64 start = get_system_time();

	// Try to pause
	if (!m_status.compare_and_swap_test(Running, Paused))
	{
		return false;
	}

	rpcs3::on_pause()();

	// Update pause start time
	if (m_pause_start_time.exchange(start))
	{
		LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access");
	}

	SendDbgCommand(DID_PAUSE_EMU);

	for (auto& thread : get_all_cpu_threads())
	{
		thread->state += cpu_state::dbg_global_pause;
	}

	SendDbgCommand(DID_PAUSED_EMU);

	return true;
}
Пример #20
0
void update_ui_comms (void)
{

static int
		update_ticks = 0;

	if (update_ticks < get_system_time ())
	{

		data_exchange ();

		update_ticks = get_system_time () + (ONE_SECOND / command_line_max_game_update_rate);

		set_delta_time ();
	}
}
void log_lprint(const int level, const char *fmt, ...)
{
    char *buf = NULL;
    static int log_index = 0;
    va_list ap;
    char systime[32];
    if (level > global_level) {
        return;
    }
    va_start(ap, fmt);
    vasprintf(&buf, fmt, ap);
    va_end(ap);

    if (log_fd > 0) {
        char sbuf[16];
        check_file_size();
        get_system_time(systime);
        sprintf(sbuf, "[%d]: ", log_index++);
        write(log_fd, sbuf, strlen(sbuf));
        write(log_fd, systime, strlen(systime));
        write(log_fd, buf, strlen(buf));
        write(log_fd, "\n", 1);
        fsync(log_fd);
    } else {
        fprintf(stdout, "%s", buf);
        fflush(stdout);
    }
    if (buf) {
        free(buf);
    }
}
Пример #22
0
void _arch_irq_task_switch(void * _cpu_state) {
  
  if(run_queue) {

    spinlock_lock(&run_queue->spinlock);

    get_system_time(&run_queue->sched_time);

    struct kthread * c = run_queue_current();
    struct kthread * n = run_queue_next();
		
    spinlock_unlock(&run_queue->spinlock);

    _BUG_ON(!n);
    _BUG_ON(!c);

    if(stack_check(&(c->stack))<0)
      _BUG(); // TASK WE JUST PUT TO SLEEP BLEW ITS STACK!
    
    _switch(c,n,_cpu_state);
    
    // schedule next switch.
    _sched_next_task(NULL);
  }
}
Пример #23
0
void Emulator::Resume()
{
	// Get pause start time
	const u64 time = m_pause_start_time.exchange(0);

	// Try to increment summary pause time
	if (time)
	{
		m_pause_amend_time += get_system_time() - time;
	}

	// Try to resume
	if (!m_status.compare_and_swap_test(Paused, Running))
	{
		return;
	}

	if (!time)
	{
		LOG_ERROR(GENERAL, "Emulator::Resume() error: concurrent access");
	}

	SendDbgCommand(DID_RESUME_EMU);

	idm::select<ppu_thread, SPUThread, RawSPUThread, ARMv7Thread>([](u32, cpu_thread& cpu)
	{
		cpu.state -= cpu_state::dbg_global_pause;
		cpu.lock_notify();
	});

	rpcs3::on_resume()();

	SendDbgCommand(DID_RESUMED_EMU);
}
Пример #24
0
bool Emulator::Pause()
{
	const u64 start = get_system_time();

	// Try to pause
	if (!m_status.compare_and_swap_test(Running, Paused))
	{
		return false;
	}

	rpcs3::on_pause()();

	// Update pause start time
	if (m_pause_start_time.exchange(start))
	{
		LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access");
	}

	SendDbgCommand(DID_PAUSE_EMU);

	idm::select<ppu_thread, SPUThread, RawSPUThread, ARMv7Thread>([](u32, cpu_thread& cpu)
	{
		cpu.state += cpu_state::dbg_global_pause;
	});

	SendDbgCommand(DID_PAUSED_EMU);

	return true;
}
Пример #25
0
us hf_clock::get_microsec()
{
    #if defined(_MSC_VER)
        return static_cast<us>(get_system_time() / static_cast<double>(get_system_freq()) * 1.e6);
    #else
        return get_hw_clock().get_microsec();
    #endif
}
Пример #26
0
float hf_clock::get_sec()
{
    #if defined(_MSC_VER)
        return get_system_time() / static_cast<float>(get_system_freq());
    #else
        return get_hw_clock().get_sec();
    #endif
}
Пример #27
0
int queue_enqueue(volatile void *q, const void *elt, int timeout)
{
	volatile struct generic_queue *gq = q;

	if (queue_is_empty(q)) {
		/* Empty queue, just push something into the front */
		gq->head = gq->memory;
		gq->tail = gq->memory;
	} else {
		if (queue_is_full(q)) {
			/* Full queue, if we have a timeout, keep trying to
			 * insert until we're successful, or the timeout
			 * expires. If not, just yield forever */
			if (-1 == timeout) {
				while(queue_is_full(q)) {
					yield(NULL);
				}
			} else {

				const int expiration_time = get_system_time() + timeout;

				while (queue_is_full(q) && (get_system_time() < expiration_time)) {
					yield(NULL);
				}

				/* If the queue is still full, return an error */
				if (queue_is_full(gq)) {
					return -1;
				}
			}

		}

		if (QUEUE_TAIL_WRAP(gq)) {
			gq->tail = gq->memory;
		} else {
			gq->tail = (uint8_t *)gq->tail + gq->item_size;
		}
	}

	memcpy((void*)gq->tail, elt, gq->item_size);
	gq->len++;

	return 0;
}
Пример #28
0
/*
	Start.
	Start decoding playlist.
*/
bool	CContentDecoder::Start()
{
	if( m_spPlaylist == NULL )
	{
		g_Log->Warning( "No playlist..." );
		return false;
	}
	
	//abs is a protection against malicious negative numbers giving large integer when converted to uint32
    m_LoopIterations = static_cast<uint32>(g_Settings()->Get( "settings.player.LoopIterations", 2 ));

	//	Start by opening, so we have a context to work with.
	m_bStop = false;

	m_pNextSheepThread = new thread( bind( &CContentDecoder::CalculateNextSheep, this ) );
	
#ifdef WIN32
	SetThreadPriority( (HANDLE)m_pNextSheepThread->native_handle(), THREAD_PRIORITY_BELOW_NORMAL );
	SetThreadPriorityBoost( (HANDLE)m_pNextSheepThread->native_handle(), TRUE );
#else
	struct sched_param sp;
	sp.sched_priority = 8; //Foreground NORMAL_PRIORITY_CLASS - THREAD_PRIORITY_BELOW_NORMAL
	pthread_setschedparam( (pthread_t)m_pNextSheepThread->native_handle(), SCHED_RR, &sp );
#endif

	while ( Initialized() == false )
		thread::sleep( get_system_time() + posix_time::milliseconds(100) );
		
	m_pDecoderThread = new thread( bind( &CContentDecoder::ReadPackets, this ) );
	
	int retry = 0;
	
	CVideoFrame *tmp = NULL;
   
	while ( retry < 10 && !m_FrameQueue.peek( tmp, false ) && !m_bStop)
	{
		thread::sleep( get_system_time() + posix_time::milliseconds(100) );
		retry++;
	}

	if (tmp == NULL)
		return false;

	return true;
}
Пример #29
0
static inline void
logging_get_date_and_time (char buf[])
{
    struct tm tm = get_system_time();

    snprintf(buf, MAX_TIME_LENGTH, logging_date_and_time_fmt,
	     month_num2alpha[tm.tm_mon], tm.tm_mday,
	     tm.tm_hour, tm.tm_min, tm.tm_sec);
}
Пример #30
0
inline int xtime_get(struct xtime* xtp, int clock_type)
{
    if (clock_type == TIME_UTC)
    {
        *xtp=get_xtime(get_system_time());
        return clock_type;
    }
    return 0;
}