Scheduler.hh 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #ifndef SCHEDULER_HH
  2. #define SCHEDULER_HH
  3. #include "EmuTime.hh"
  4. #include "SchedulerQueue.hh"
  5. #include "likely.hh"
  6. #include <vector>
  7. namespace openmsx {
  8. class Schedulable;
  9. class MSXCPU;
  10. class SynchronizationPoint
  11. {
  12. public:
  13. SynchronizationPoint(EmuTime::param time, Schedulable* dev)
  14. : timeStamp(time), device(dev) {}
  15. SynchronizationPoint()
  16. : timeStamp(EmuTime::zero), device(nullptr) {}
  17. EmuTime::param getTime() const { return timeStamp; }
  18. void setTime(EmuTime::param time) { timeStamp = time; }
  19. Schedulable* getDevice() const { return device; }
  20. template <typename Archive>
  21. void serialize(Archive& ar, unsigned version);
  22. private:
  23. EmuTime timeStamp;
  24. Schedulable* device;
  25. };
  26. class Scheduler
  27. {
  28. public:
  29. using SyncPoints = std::vector<SynchronizationPoint>;
  30. Scheduler();
  31. ~Scheduler();
  32. void setCPU(MSXCPU* cpu_)
  33. {
  34. cpu = cpu_;
  35. }
  36. /**
  37. * Get the current scheduler time.
  38. */
  39. EmuTime::param getCurrentTime() const;
  40. /**
  41. * TODO
  42. */
  43. inline EmuTime::param getNext() const
  44. {
  45. return queue.front().getTime();
  46. }
  47. /**
  48. * Schedule till a certain moment in time.
  49. */
  50. inline void schedule(EmuTime::param limit)
  51. {
  52. EmuTime next = getNext();
  53. if (unlikely(limit >= next)) {
  54. scheduleHelper(limit, next); // slow path not inlined
  55. }
  56. scheduleTime = limit;
  57. }
  58. template <typename Archive>
  59. void serialize(Archive& ar, unsigned version);
  60. private: // -> intended for Schedulable
  61. friend class Schedulable;
  62. /**
  63. * Register a syncPoint. When the emulation reaches "timestamp",
  64. * the executeUntil() method of "device" gets called.
  65. * SyncPoints are ordered: smaller EmuTime -> scheduled
  66. * earlier.
  67. * The supplied EmuTime may not be smaller than the current CPU
  68. * time.
  69. * A device may register several syncPoints.
  70. */
  71. void setSyncPoint(EmuTime::param timestamp, Schedulable& device);
  72. SyncPoints getSyncPoints(const Schedulable& device) const;
  73. /**
  74. * Removes a syncPoint of a given device.
  75. * If there is more than one match only one will be removed,
  76. * there is no guarantee that the earliest syncPoint is
  77. * removed.
  78. * Returns false <=> if there was no match (so nothing removed)
  79. */
  80. bool removeSyncPoint(Schedulable& device);
  81. /** Remove all syncpoints for the given device.
  82. */
  83. void removeSyncPoints(Schedulable& device);
  84. /**
  85. * Is there a pending syncPoint for this device?
  86. */
  87. bool pendingSyncPoint(const Schedulable& device, EmuTime& result) const;
  88. private:
  89. void scheduleHelper(EmuTime::param limit, EmuTime next);
  90. /** Vector used as heap, not a priority queue because that
  91. * doesn't allow removal of non-top element.
  92. */
  93. SchedulerQueue<SynchronizationPoint> queue;
  94. EmuTime scheduleTime;
  95. MSXCPU* cpu;
  96. bool scheduleInProgress;
  97. };
  98. } // namespace openmsx
  99. #endif