address_arbiter.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include "common/common_types.h"
  5. #include "core/mem_map.h"
  6. #include "core/hle/hle.h"
  7. #include "core/hle/kernel/address_arbiter.h"
  8. #include "core/hle/kernel/thread.h"
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // Kernel namespace
  11. namespace Kernel {
  12. class AddressArbiter : public Object {
  13. public:
  14. std::string GetTypeName() const override { return "Arbiter"; }
  15. std::string GetName() const override { return name; }
  16. static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; }
  17. Kernel::HandleType GetHandleType() const override { return HandleType::AddressArbiter; }
  18. std::string name; ///< Name of address arbiter object (optional)
  19. /**
  20. * Wait for kernel object to synchronize
  21. * @param wait Boolean wait set if current thread should wait as a result of sync operation
  22. * @return Result of operation, 0 on success, otherwise error code
  23. */
  24. ResultVal<bool> WaitSynchronization() override {
  25. // TODO(bunnei): ImplementMe
  26. ERROR_LOG(OSHLE, "(UNIMPLEMENTED)");
  27. return UnimplementedFunction(ErrorModule::OS);
  28. }
  29. };
  30. ////////////////////////////////////////////////////////////////////////////////////////////////////
  31. /// Arbitrate an address
  32. ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
  33. switch (type) {
  34. // Signal thread(s) waiting for arbitrate address...
  35. case ArbitrationType::Signal:
  36. // Negative value means resume all threads
  37. if (value < 0) {
  38. ArbitrateAllThreads(handle, address);
  39. } else {
  40. // Resume first N threads
  41. for(int i = 0; i < value; i++)
  42. ArbitrateHighestPriorityThread(handle, address);
  43. }
  44. break;
  45. // Wait current thread (acquire the arbiter)...
  46. case ArbitrationType::WaitIfLessThan:
  47. if ((s32)Memory::Read32(address) <= value) {
  48. Kernel::WaitCurrentThread(WAITTYPE_ARB, handle);
  49. HLE::Reschedule(__func__);
  50. }
  51. break;
  52. default:
  53. ERROR_LOG(KERNEL, "unknown type=%d", type);
  54. return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, ErrorSummary::WrongArgument, ErrorLevel::Usage);
  55. }
  56. return RESULT_SUCCESS;
  57. }
  58. /// Create an address arbiter
  59. AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) {
  60. AddressArbiter* address_arbiter = new AddressArbiter;
  61. handle = Kernel::g_object_pool.Create(address_arbiter);
  62. address_arbiter->name = name;
  63. return address_arbiter;
  64. }
  65. /// Create an address arbiter
  66. Handle CreateAddressArbiter(const std::string& name) {
  67. Handle handle;
  68. CreateAddressArbiter(handle, name);
  69. return handle;
  70. }
  71. } // namespace Kernel