Talvos  0.1
SPIR-V interpreter and dynamic analysis framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Queue.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018 the Talvos developers. All rights reserved.
2 //
3 // This file is distributed under a three-clause BSD license. For full license
4 // terms please see the LICENSE file distributed with this source code.
5 
8 
9 #include <cassert>
10 
11 #include "talvos/Commands.h"
12 #include "talvos/Device.h"
13 #include "talvos/Queue.h"
14 
15 namespace talvos
16 {
17 
18 Queue::Queue(Device &Dev) : Dev(Dev)
19 {
20  Running = true;
21  Thread = std::thread(&Queue::run, this);
22 }
23 
25 {
26  // Clear commands and signal thread to exit.
27  Mutex.lock();
28  Running = false;
29  while (!Commands.empty())
30  Commands.pop();
31  StateChanged.notify_all();
32  Mutex.unlock();
33 
34  Thread.join();
35 }
36 
37 void Queue::submit(const std::vector<Command *> &NewCommands,
38  volatile bool *Fence)
39 {
40  std::lock_guard<std::mutex> Lock(Mutex);
41 
42  // Add commands to queue.
43  for (auto Cmd : NewCommands)
44  Commands.push(Cmd);
45 
46  if (Fence)
47  {
48  // Add fence to queue.
49  assert(Fences.count(Fence) == 0);
50  Fences.insert(Fence);
51  Commands.push((Command *)Fence);
52  }
53 
54  // Signal that queue state has changed.
55  StateChanged.notify_all();
56 }
57 
58 void Queue::run()
59 {
60  while (Running)
61  {
62  Command *Cmd = nullptr;
63 
64  // Get the next command (waiting for one to arrive if necessary).
65  {
66  std::unique_lock<std::mutex> Lock(Mutex);
67 
68  // If there are no available commands, wait until some are added.
69  if (Commands.empty() && Running)
70  StateChanged.wait(Lock);
71 
72  // If there are still no commands, go round again (probably exiting).
73  if (Commands.empty())
74  continue;
75 
76  // Get the next command.
77  Cmd = Commands.front();
78 
79  // Check if command is actually a fence.
80  if (Fences.count((bool *)Cmd))
81  {
82  // Signal fence, remove it, and continue.
83  *((bool *)Cmd) = true;
84  Fences.erase((bool *)Cmd);
85  Commands.pop();
86  StateChanged.notify_all();
88  continue;
89  }
90  }
91 
92  // Run command.
93  assert(Cmd);
94  Cmd->run(Dev);
95 
96  // Remove command from queue.
97  Mutex.lock();
98  Commands.pop();
99  StateChanged.notify_all();
100  Mutex.unlock();
101  }
102 }
103 
105 {
106  // Loop until no pending commands.
107  while (true)
108  {
109  std::unique_lock<std::mutex> Lock(Mutex);
110 
111  // If queue is already empty, just return.
112  if (Commands.empty())
113  return;
114 
115  // Wait until the queue state changes before trying again.
116  StateChanged.wait(Lock);
117  }
118 }
119 
120 } // namespace talvos
void run(Device &Dev) const
Run this command on Dev.
Definition: Commands.cpp:23
void submit(const std::vector< Command * > &NewCommands, volatile bool *Fence=nullptr)
Submit a batch of commands to the queue.
Definition: Queue.cpp:37
std::condition_variable StateChanged
Condition variable to signal when queue state has changed.
Definition: Queue.h:66
This file declares the Device class.
Device & Dev
The device that this queue will execute work on.
Definition: Queue.h:51
std::queue< Command * > Commands
The queue of pending commands.
Definition: Queue.h:54
void notifyFenceSignaled()
Notify the device that a fence was signaled.
Definition: Device.cpp:140
volatile bool Running
Flag to signal whether the queue thread is active.
Definition: Queue.h:69
~Queue()
Destroy the queue.
Definition: Queue.cpp:24
std::thread Thread
Definition: Queue.h:60
This class is a base class for all commands.
Definition: Commands.h:31
void run()
Entry point for background queue thread.
Definition: Queue.cpp:58
void waitIdle()
Wait until all commands in the queue have completed.
Definition: Queue.cpp:104
This file declares the Queue class.
A Device instance encapsulates properties and state for the virtual device.
Definition: Device.h:29
std::set< volatile bool * > Fences
A set of pending fences.
Definition: Queue.h:57
This file declares the Command base class and its subclasses.
std::mutex Mutex
Mutex used to guard queue updates.
Definition: Queue.h:63
Queue(Device &Dev)
Create a queue for the specified device.
Definition: Queue.cpp:18