address_arbiter.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. ResultVal<bool> WaitSynchronization() override {
  20. // TODO(bunnei): ImplementMe
  21. ERROR_LOG(OSHLE, "(UNIMPLEMENTED)");
  22. return UnimplementedFunction(ErrorModule::OS);
  23. }
  24. };
  25. ////////////////////////////////////////////////////////////////////////////////////////////////////
  26. /// Arbitrate an address
  27. ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
  28. switch (type) {
  29. // Signal thread(s) waiting for arbitrate address...
  30. case ArbitrationType::Signal:
  31. // Negative value means resume all threads
  32. if (value < 0) {
  33. ArbitrateAllThreads(handle, address);
  34. } else {
  35. // Resume first N threads
  36. for(int i = 0; i < value; i++)
  37. ArbitrateHighestPriorityThread(handle, address);
  38. }
  39. break;
  40. // Wait current thread (acquire the arbiter)...
  41. case ArbitrationType::WaitIfLessThan:
  42. if ((s32)Memory::Read32(address) <= value) {
  43. Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address);
  44. HLE::Reschedule(__func__);
  45. }
  46. break;
  47. default:
  48. ERROR_LOG(KERNEL, "unknown type=%d", type);
  49. return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, ErrorSummary::WrongArgument, ErrorLevel::Usage);
  50. }
  51. return RESULT_SUCCESS;
  52. }
  53. /// Create an address arbiter
  54. AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) {
  55. AddressArbiter* address_arbiter = new AddressArbiter;
  56. handle = Kernel::g_object_pool.Create(address_arbiter);
  57. address_arbiter->name = name;
  58. return address_arbiter;
  59. }
  60. /// Create an address arbiter
  61. Handle CreateAddressArbiter(const std::string& name) {
  62. Handle handle;
  63. CreateAddressArbiter(handle, name);
  64. return handle;
  65. }
  66. } // namespace Kernel