WorkQueue.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers.
  3. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <Kernel/Arch/Processor.h>
  8. #include <Kernel/Process.h>
  9. #include <Kernel/Sections.h>
  10. #include <Kernel/WaitQueue.h>
  11. #include <Kernel/WorkQueue.h>
  12. namespace Kernel {
  13. WorkQueue* g_io_work;
  14. WorkQueue* g_ata_work;
  15. UNMAP_AFTER_INIT void WorkQueue::initialize()
  16. {
  17. g_io_work = new WorkQueue("IO WorkQueue Task"sv);
  18. g_ata_work = new WorkQueue("ATA WorkQueue Task"sv);
  19. }
  20. UNMAP_AFTER_INIT WorkQueue::WorkQueue(StringView name)
  21. {
  22. auto name_kstring = KString::try_create(name);
  23. if (name_kstring.is_error())
  24. TODO();
  25. auto [_, thread] = Process::create_kernel_process(name_kstring.release_value(), [this] {
  26. #if ARCH(AARCH64)
  27. // FIXME: This function expects to be executed with interrupts disabled, however on
  28. // aarch64 we spawn (kernel) threads with interrupts enabled, so we need to disable them.
  29. // This code should be written in a way that it is able to be executed with interrupts enabled.
  30. Processor::disable_interrupts();
  31. #endif
  32. for (;;) {
  33. WorkItem* item;
  34. bool have_more;
  35. m_items.with([&](auto& items) {
  36. item = items.take_first();
  37. have_more = !items.is_empty();
  38. });
  39. if (item) {
  40. item->function();
  41. delete item;
  42. if (have_more)
  43. continue;
  44. }
  45. [[maybe_unused]] auto result = m_wait_queue.wait_on({});
  46. }
  47. }).release_value_but_fixme_should_propagate_errors();
  48. m_thread = move(thread);
  49. }
  50. void WorkQueue::do_queue(WorkItem& item)
  51. {
  52. m_items.with([&](auto& items) {
  53. items.append(item);
  54. });
  55. m_wait_queue.wake_one();
  56. }
  57. }