示例#1
0
void Threading::Semaphore::Post(int multiple)
{
	for (int i = 0; i < multiple; ++i) {
		MACH_CHECK(semaphore_signal(m_sema));
	}
	__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
}
示例#2
0
Threading::Semaphore::Semaphore()
{
	// other platforms explicitly make a thread-private (unshared) semaphore
	// here. But it seems Mach doesn't support that.
	MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
	__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
示例#3
0
int32 ReadReg (uint32 pa, int32 lnt)
{
struct reglink *p;

for (p = &regtable[0]; p->low != 0; p++) {
    if ((pa >= p->low) && (pa < p->high) && p->read)
        return p->read (pa);
    }
MACH_CHECK (MCHK_READ);
}
示例#4
0
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
{
	// This method is the reason why there has to be a special Darwin
	// implementation of Semaphore. Note that semaphore_timedwait() is prone
	// to returning with KERN_ABORTED, which basically signifies that some
	// signal has worken it up. The best official "documentation" for
	// semaphore_timedwait() is the way it's used in Grand Central Dispatch,
	// which is open-source.

	// on x86 platforms, mach_absolute_time() returns nanoseconds
	// TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary
	u64 const kOneThousand = 1000;
	u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand;
	u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand);
	mach_timespec_t ts;
	kern_return_t kr = KERN_ABORTED;
	for (u64 now = mach_absolute_time(), deadline = now + delta;
		kr == KERN_ABORTED; now = mach_absolute_time()) {
		if (now > deadline) {
			// timed out by definition
			return false;
		}

		u64 timeleft = deadline - now;
		ts.tv_sec = timeleft / kOneBillion;
		ts.tv_nsec = timeleft % kOneBillion;

		// possible return values of semaphore_timedwait() (from XNU sources):
		// internal kernel val -> return value
		// THREAD_INTERRUPTED  -> KERN_ABORTED
		// THREAD_TIMED_OUT    -> KERN_OPERATION_TIMED_OUT
		// THREAD_AWAKENED     -> KERN_SUCCESS
		// THREAD_RESTART      -> KERN_TERMINATED
		// default             -> KERN_FAILURE
		kr = semaphore_timedwait(m_sema, ts);
	}

	if (kr == KERN_OPERATION_TIMED_OUT) {
		return false;
	}

	// while it's entirely possible to have KERN_FAILURE here, we should
	// probably assert so we can study and correct the actual error here
	// (the thread dying while someone is wainting for it).
	MACH_CHECK(kr);

	__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
	return true;
}
示例#5
0
void Threading::Semaphore::WaitWithoutYield()
{
	pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread.  Please use Wait() instead.");
	MACH_CHECK(semaphore_wait(m_sema));
	__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
示例#6
0
void Threading::Semaphore::Post()
{
	MACH_CHECK(semaphore_signal(m_sema));
	__atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
示例#7
0
void Threading::Semaphore::Reset()
{
	MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
	MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *) &m_sema, SYNC_POLICY_FIFO, 0));
	__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
示例#8
0
Threading::Semaphore::~Semaphore() throw()
{
	MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
	__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}