resource_limit.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "core/hle/kernel/errors.h"
  5. #include "core/hle/kernel/resource_limit.h"
  6. #include "core/hle/result.h"
  7. namespace Kernel {
  8. namespace {
  9. constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
  10. return static_cast<std::size_t>(type);
  11. }
  12. } // Anonymous namespace
  13. ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
  14. ResourceLimit::~ResourceLimit() = default;
  15. bool ResourceLimit::Reserve(ResourceType resource, s64 amount) {
  16. return Reserve(resource, amount, 10000000000);
  17. }
  18. bool ResourceLimit::Reserve(ResourceType resource, s64 amount, u64 timeout) {
  19. const std::size_t index{ResourceTypeToIndex(resource)};
  20. s64 new_value = current[index] + amount;
  21. while (new_value > limit[index] && available[index] + amount <= limit[index]) {
  22. // TODO(bunnei): This is wrong for multicore, we should wait the calling thread for timeout
  23. new_value = current[index] + amount;
  24. if (timeout >= 0) {
  25. break;
  26. }
  27. }
  28. if (new_value <= limit[index]) {
  29. current[index] = new_value;
  30. return true;
  31. }
  32. return false;
  33. }
  34. void ResourceLimit::Release(ResourceType resource, u64 amount) {
  35. Release(resource, amount, amount);
  36. }
  37. void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) {
  38. const std::size_t index{ResourceTypeToIndex(resource)};
  39. current[index] -= used_amount;
  40. available[index] -= available_amount;
  41. }
  42. std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
  43. return std::make_shared<ResourceLimit>(kernel);
  44. }
  45. s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
  46. return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource));
  47. }
  48. s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
  49. return limit.at(ResourceTypeToIndex(resource));
  50. }
  51. ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
  52. const std::size_t index{ResourceTypeToIndex(resource)};
  53. if (current[index] <= value) {
  54. limit[index] = value;
  55. return RESULT_SUCCESS;
  56. } else {
  57. return ERR_INVALID_STATE;
  58. }
  59. }
  60. } // namespace Kernel