summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-07-13 20:15:17 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-13 20:15:17 +0200
commitdcfa93e71f09ca3a6992529790ec8981ce5452f0 (patch)
tree63bafddfadda0377db5c7c2d4ae8de40deca7279
parent54e79a46407518c9d1b5079e297a316ed278951c (diff)
downloadserenity-dcfa93e71f09ca3a6992529790ec8981ce5452f0.zip
SB16: Use a snooze alarm to block the current thread while playing.
-rw-r--r--Kernel/Devices/SB16.cpp17
-rw-r--r--Kernel/Devices/SB16.h19
2 files changed, 29 insertions, 7 deletions
diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp
index 1e6bc45163..141f01ade3 100644
--- a/Kernel/Devices/SB16.cpp
+++ b/Kernel/Devices/SB16.cpp
@@ -1,5 +1,6 @@
-#include "SB16.h"
-#include "IO.h"
+#include <Kernel/Devices/SB16.h>
+#include <Kernel/IO.h>
+#include <Kernel/Thread.h>
#include <Kernel/VM/MemoryManager.h>
//#define SB16_DEBUG
@@ -48,6 +49,7 @@ static SB16* s_the;
SB16::SB16()
: IRQHandler(5)
, CharacterDevice(42, 42) // ### ?
+ , m_interrupt_alarm(*this)
{
s_the = this;
initialize();
@@ -141,11 +143,7 @@ void SB16::wait_for_irq()
#ifdef SB16_DEBUG
kprintf("SB16: waiting for interrupt...\n");
#endif
- // FIXME: Add timeout.
- while (!m_interrupted) {
- // FIXME: Put this process into a Blocked state instead, it's stupid to wake up just to check a flag.
- Scheduler::yield();
- }
+ current->snooze_until(m_interrupt_alarm);
#ifdef SB16_DEBUG
kprintf("SB16: got interrupt!\n");
#endif
@@ -196,3 +194,8 @@ ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length)
wait_for_irq();
return length;
}
+
+bool SB16InterruptAlarm::is_ringing() const
+{
+ return m_device.got_interrupt({});
+}
diff --git a/Kernel/Devices/SB16.h b/Kernel/Devices/SB16.h
index 20bbb8f6ed..bef47f5f07 100644
--- a/Kernel/Devices/SB16.h
+++ b/Kernel/Devices/SB16.h
@@ -1,11 +1,26 @@
#pragma once
#include <AK/CircularQueue.h>
+#include <Kernel/Alarm.h>
#include <Kernel/Devices/CharacterDevice.h>
#include <Kernel/IRQHandler.h>
#include <Kernel/VM/PhysicalAddress.h>
#include <Kernel/VM/PhysicalPage.h>
+class SB16;
+
+class SB16InterruptAlarm final : public Alarm {
+public:
+ SB16InterruptAlarm(SB16& device)
+ : m_device(device)
+ {
+ }
+ virtual bool is_ringing() const override;
+
+private:
+ SB16& m_device;
+};
+
class SB16 final : public IRQHandler
, public CharacterDevice {
public:
@@ -20,6 +35,8 @@ public:
virtual ssize_t write(FileDescription&, const u8*, ssize_t) override;
virtual bool can_write(FileDescription&) const override { return true; }
+ bool got_interrupt(Badge<SB16InterruptAlarm>) const { return m_interrupted; }
+
private:
// ^IRQHandler
virtual void handle_irq() override;
@@ -37,4 +54,6 @@ private:
RefPtr<PhysicalPage> m_dma_buffer_page;
bool m_interrupted { false };
int m_major_version { 0 };
+
+ SB16InterruptAlarm m_interrupt_alarm;
};