示例#1
0
void Sound::detach() {
    
    // Ignore if we are not attached to any source
    if (!source)
        return;
    
    // Unqueue all buffers and detach source
    if(isStream())
        unqueue();

    source = nullptr;
}
示例#2
0
void Sound::update() {
    
    // Buffered sound does not need any update
    if (!sampler)
        return;
    
    // Unattached streamed sound, neither
    if (!source)
        return;
    
    // Update queue
    unqueue();
    queue();
}
示例#3
0
error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout)
{
	sys_event.trace("sys_event_queue_receive(equeue_id=0x%x, *0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout);

	const auto queue = idm::get<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
	{
		if (queue.type != SYS_PPU_QUEUE)
		{
			return CELL_EINVAL;
		}

		semaphore_lock lock(queue.mutex);
		
		if (queue.events.empty())
		{
			queue.sq.emplace_back(&ppu);
			queue.sleep(ppu, timeout);
			return CELL_EBUSY;
		}

		std::tie(ppu.gpr[4], ppu.gpr[5], ppu.gpr[6], ppu.gpr[7]) = queue.events.front();
		queue.events.pop_front();
		return {};
	});

	if (!queue)
	{
		return CELL_ESRCH;
	}

	if (queue.ret)
	{
		if (queue.ret != CELL_EBUSY)
		{
			return queue.ret;
		}
	}
	else
	{
		return CELL_OK;
	}

	// If cancelled, gpr[3] will be non-zero. Other registers must contain event data.
	ppu.gpr[3] = 0;

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (timeout)
		{
			const u64 passed = get_system_time() - ppu.start_time;

			if (passed >= timeout)
			{
				semaphore_lock lock(queue->mutex);

				if (!queue->unqueue(queue->sq, &ppu))
				{
					timeout = 0;
					continue;
				}

				ppu.gpr[3] = CELL_ETIMEDOUT;
				break;
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	return not_an_error(ppu.gpr[3]);
}
示例#4
0
int main() {

  struct nodo * pila;
  struct nodo * cola;
  struct nodo * lista;
  struct nodo nodo1;
  struct nodo nodo2;
  struct nodo nodo3;
  struct nodo nodo4;

  struct nodo * aux;

  nodo1.val=1;
  nodo2.val=2;
  nodo3.val=3;
  nodo4.val=4;

  //pila
  printf("-- pila --\n");
  init(&pila);
  push(&pila, &nodo1);
  push(&pila, &nodo2);
  push(&pila, &nodo3);

  while(aux=pop(&pila))
    printf("%i\n",(*aux).val);

  //cola
  printf("-- cola --\n");
  init(&cola);
  push(&cola, &nodo1);
  push(&cola, &nodo2);
  push(&cola, &nodo3);

  while(aux=unqueue(&cola))
    printf("%i\n",(*aux).val);

  //lista
  printf("-- lista --\n");
  init(&lista);
  agregar(&lista,&nodo1,0);
  agregar(&lista,&nodo3,1);
  agregar(&lista,&nodo2,1);

  aux=quitar(&lista,1);
  printf("%i\n",(*aux).val);
  while(aux=quitar(&lista,0))
    printf("%i\n",(*aux).val);

  //lista misc
  printf("-- lista misc --\n");
  init(&lista);
  agregar(&lista,&nodo1,0);
  agregar(&lista,&nodo3,1);
  agregar(&lista,&nodo2,1);
  agregar(&lista,&nodo4,3);
  intercambiar(&lista, 1, 3);
  printf("la lista tiene %i items\n",len(&lista));
  while(aux=pop(&lista))
    printf("%i\n",(*aux).val);
  printf("la lista tiene %i items\n",len(&lista));

  //lista misc
  printf("-- lista ordenar --\n");
  init(&lista);
  push(&lista, &nodo3);
  push(&lista, &nodo1);
  push(&lista, &nodo4);
  push(&lista, &nodo2);
  printf("burbuja\n");
  ordenar_burbujeo(&lista);
  mostrar(&lista);

  return 0;
}
示例#5
0
error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
{
	sys_lwmutex.trace("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);

	const auto mutex = idm::get<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex)
	{
		if (mutex.signaled.try_dec())
		{
			return true;
		}

		std::lock_guard lock(mutex.mutex);

		if (mutex.signaled.try_dec())
		{
			return true;
		}

		mutex.sq.emplace_back(&ppu);
		mutex.sleep(ppu, timeout);
		return false;
	});

	if (!mutex)
	{
		return CELL_ESRCH;
	}

	if (mutex.ret)
	{
		return CELL_OK;
	}

	ppu.gpr[3] = CELL_OK;

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (ppu.is_stopped())
		{
			return 0;
		}

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

			if (passed >= timeout)
			{
				std::lock_guard lock(mutex->mutex);

				if (!mutex->unqueue(mutex->sq, &ppu))
				{
					timeout = 0;
					continue;
				}

				ppu.gpr[3] = CELL_ETIMEDOUT;
				break;
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	return not_an_error(ppu.gpr[3]);
}
示例#6
0
error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode)
{
	sys_lwcond.trace("_sys_lwcond_signal(lwcond_id=0x%x, lwmutex_id=0x%x, ppu_thread_id=0x%x, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode);

	// Mode 1: lwmutex was initially owned by the calling thread
	// Mode 2: lwmutex was not owned by the calling thread and waiter hasn't been increased
	// Mode 3: lwmutex was forcefully owned by the calling thread

	if (mode < 1 || mode > 3)
	{
		fmt::throw_exception("Unknown mode (%d)" HERE, mode);
	}

	lv2_lwmutex* mutex = nullptr;

	const auto cond = idm::check<lv2_obj, lv2_lwcond>(lwcond_id, [&](lv2_lwcond& cond) -> cpu_thread*
	{
		mutex = idm::check_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);

		if (cond.waiters)
		{
			std::lock_guard lock(cond.mutex);

			cpu_thread* result = nullptr;

			if (ppu_thread_id != -1)
			{
				for (auto cpu : cond.sq)
				{
					if (cpu->id == ppu_thread_id)
					{
						verify(HERE), cond.unqueue(cond.sq, cpu);
						result = cpu;
						break;
					}
				}
			}
			else
			{
				result = cond.schedule<ppu_thread>(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK);
			}

			if (result)
			{
				cond.waiters--;

				if (mode == 2)
				{
					static_cast<ppu_thread*>(result)->gpr[3] = CELL_EBUSY;
				}

				if (mode == 1)
				{
					verify(HERE), !mutex->signaled;
					std::lock_guard lock(mutex->mutex);
					mutex->sq.emplace_back(result);
					result = nullptr;
					mode = 2; // Enforce CELL_OK
				}

				return result;
			}
		}

		return nullptr;
	});

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

	if (cond.ret)
	{
		cond->awake(*cond.ret);
	}
	else if (mode == 2)
	{
		return CELL_OK;
	}
	else if (mode == 1 || ppu_thread_id == -1)
	{
		return not_an_error(CELL_EPERM);
	}
	else
	{
		return not_an_error(CELL_ENOENT);
	}

	return CELL_OK;
}
示例#7
0
error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 timeout)
{
	sys_lwcond.trace("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);

	std::shared_ptr<lv2_lwmutex> mutex;

	const auto cond = idm::get<lv2_obj, lv2_lwcond>(lwcond_id, [&](lv2_lwcond& cond) -> cpu_thread*
	{
		mutex = idm::get_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);

		if (!mutex)
		{
			return nullptr;
		}

		std::lock_guard lock(cond.mutex);

		// Add a waiter
		cond.waiters++;
		cond.sq.emplace_back(&ppu);
		cond.sleep(ppu, timeout);

		std::lock_guard lock2(mutex->mutex);

		// Process lwmutex sleep queue
		if (const auto cpu = mutex->schedule<ppu_thread>(mutex->sq, mutex->protocol))
		{
			return cpu;
		}

		mutex->signaled++;
		return nullptr;
	});

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

	if (cond.ret)
	{
		cond->awake(*cond.ret);
	}

	ppu.gpr[3] = CELL_OK;

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (ppu.is_stopped())
		{
			return 0;
		}

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

			if (passed >= timeout)
			{
				std::lock_guard lock(cond->mutex);

				if (!cond->unqueue(cond->sq, &ppu))
				{
					timeout = 0;
					continue;
				}

				cond->waiters--;

				if (mutex->signaled.try_dec())
				{
					ppu.gpr[3] = CELL_EDEADLK;
					break;
				}

				ppu.gpr[3] = CELL_ETIMEDOUT;
				break;
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	// Return cause
	return not_an_error(ppu.gpr[3]);
}
示例#8
0
void Source::unqueue(lost::shared_ptr<Buffer> buffer)
{
  unqueue(buffer->buffer);
}
示例#9
0
文件: sys_lwcond.cpp 项目: O1L/rpcs3
error_code _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode)
{
	sys_lwcond.trace("_sys_lwcond_signal(lwcond_id=0x%x, lwmutex_id=0x%x, ppu_thread_id=0x%x, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode);

	// Mode 1: lwmutex was initially owned by the calling thread
	// Mode 2: lwmutex was not owned by the calling thread and waiter hasn't been increased
	// Mode 3: lwmutex was forcefully owned by the calling thread

	if (mode < 1 || mode > 3)
	{
		fmt::throw_exception("Unknown mode (%d)" HERE, mode);
	}

	lv2_lwmutex* mutex = nullptr;

	const auto cond = idm::check<lv2_obj, lv2_lwcond>(lwcond_id, [&](lv2_lwcond& cond) -> cpu_thread*
	{
		mutex = idm::check_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);

		if (mutex && cond.waiters)
		{
			semaphore_lock lock(mutex->mutex);

			cpu_thread* result = nullptr;

			if (ppu_thread_id != -1)
			{
				for (auto cpu : cond.sq)
				{
					if (cpu->id == ppu_thread_id)
					{
						verify(HERE), cond.unqueue(cond.sq, cpu);
						result = cpu;
						break;
					}
				}
			}
			else
			{
				result = cond.schedule<ppu_thread>(cond.sq, mutex->protocol);
			}

			if (result)
			{
				cond.waiters--;

				static_cast<ppu_thread*>(result)->gpr[3] = mode == 2;

				if (mode != 2 && !mutex->signaled.fetch_op([](u32& v) { if (v) v--; }))
				{
					mutex->sq.emplace_back(result);
					result = nullptr;
					mode = 2; // Enforce CELL_OK
				}

				return result;
			}
		}

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

	if (cond.ret)
	{
		cond.ret->set_signal();
	}
	else if (mode == 2)
	{
		return CELL_OK;
	}
	else if (mode == 1 || ppu_thread_id == -1)
	{
		return not_an_error(CELL_EPERM);
	}
	else
	{
		return not_an_error(CELL_ENOENT);
	}

	return CELL_OK;
}
示例#10
0
文件: sys_lwcond.cpp 项目: O1L/rpcs3
error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 timeout)
{
	sys_lwcond.trace("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);

	const u64 start_time = ppu.gpr[10] = get_system_time();

	std::shared_ptr<lv2_lwmutex> mutex;

	const auto cond = idm::get<lv2_obj, lv2_lwcond>(lwcond_id, [&](lv2_lwcond& cond) -> cpu_thread*
	{
		mutex = idm::get_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);

		if (!mutex)
		{
			return nullptr;
		}

		semaphore_lock lock(mutex->mutex);

		// Add a waiter
		cond.waiters++;
		cond.sq.emplace_back(&ppu);

		// Process lwmutex sleep queue
		if (const auto cpu = mutex->schedule<ppu_thread>(mutex->sq, mutex->protocol))
		{
			return cpu;
		}

		mutex->signaled++;
		return nullptr;
	});

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

	if (cond.ret)
	{
		cond.ret->set_signal();
	}

	// SLEEP

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				semaphore_lock lock(mutex->mutex);

				if (!cond->unqueue(cond->sq, &ppu))
				{
					timeout = 0;
					continue;
				}

				cond->waiters--;

				if (mutex->signaled.fetch_op([](u32& v) { if (v) v--; }))
				{
					return not_an_error(CELL_EDEADLK);
				}

				return not_an_error(CELL_ETIMEDOUT);
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	// Return cause
	return not_an_error(ppu.gpr[3] ? CELL_EBUSY : CELL_OK);
}
示例#11
0
error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
{
	sys_mutex.trace("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout);

	const auto mutex = idm::get<lv2_obj, lv2_mutex>(mutex_id, [&](lv2_mutex& mutex)
	{
		CellError result = mutex.try_lock(ppu.id);

		if (result == CELL_EBUSY)
		{
			std::lock_guard lock(mutex.mutex);

			if (mutex.try_own(ppu, ppu.id))
			{
				result = {};
			}
			else
			{
				mutex.sleep(ppu, timeout);
			}
		}

		return result;
	});

	if (!mutex)
	{
		return CELL_ESRCH;
	}

	if (mutex.ret)
	{
		if (mutex.ret != CELL_EBUSY)
		{
			return mutex.ret;
		}
	}
	else
	{
		return CELL_OK;
	}

	ppu.gpr[3] = CELL_OK;

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (ppu.is_stopped())
		{
			return 0;
		}

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

			if (passed >= timeout)
			{
				std::lock_guard lock(mutex->mutex);

				if (!mutex->unqueue(mutex->sq, &ppu))
				{
					timeout = 0;
					continue;
				}

				ppu.gpr[3] = CELL_ETIMEDOUT;
				break;
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	return not_an_error(ppu.gpr[3]);
}
示例#12
0
error_code 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 = ppu.gpr[10] = get_system_time();

	const auto sem = idm::get<lv2_obj, lv2_sema>(sem_id, [&](lv2_sema& sema)
	{
		const s32 val = sema.val;
		
		if (val > 0)
		{
			if (sema.val.compare_and_swap_test(val, val - 1))
			{
				return true;
			}
		}

		semaphore_lock lock(sema.mutex);

		if (sema.val-- <= 0)
		{
			sema.sq.emplace_back(&ppu);
			sema.sleep(ppu, start_time, timeout);
			return false;
		}

		return true;
	});

	if (!sem)
	{
		return CELL_ESRCH;
	}

	if (sem.ret)
	{
		return CELL_OK;
	}

	ppu.gpr[3] = CELL_OK;

	while (!ppu.state.test_and_reset(cpu_flag::signal))
	{
		if (timeout)
		{
			const u64 passed = get_system_time() - start_time;

			if (passed >= timeout)
			{
				semaphore_lock lock(sem->mutex);

				const s32 val = sem->val.fetch_op([](s32& val)
				{
					if (val < 0)
					{
						val++;
					}
				});

				if (val >= 0)
				{
					timeout = 0;
					continue;
				}

				verify(HERE), sem->unqueue(sem->sq, &ppu);
				ppu.gpr[3] = CELL_ETIMEDOUT;
				break;
			}

			thread_ctrl::wait_for(timeout - passed);
		}
		else
		{
			thread_ctrl::wait();
		}
	}

	ppu.check_state();
	return not_an_error(ppu.gpr[3]);
}