Open FFBoard
Open source force feedback firmware
cworkqueue.cpp
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * Copyright (c) 2017, Michael Becker (michael.f.becker@gmail.com)
4 *
5 * This file is part of the FreeRTOS Add-ons project.
6 *
7 * Source Code:
8 * https://github.com/michaelbecker/freertos-addons
9 *
10 * Project Page:
11 * http://michaelbecker.github.io/freertos-addons/
12 *
13 * On-line Documentation:
14 * http://michaelbecker.github.io/freertos-addons/docs/html/index.html
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files
18 * (the "Software"), to deal in the Software without restriction, including
19 * without limitation the rights to use, copy, modify, merge, publish,
20 * distribute, sublicense, and/or sell copies of the Software, and to
21 * permit persons to whom the Software is furnished to do so,subject to the
22 * following conditions:
23 *
24 * + The above copyright notice and this permission notice shall be included
25 * in all copies or substantial portions of the Software.
26 * + Credit is appreciated, but not required, if you find this project
27 * useful enough to include in your application, product, device, etc.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
33 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
34 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 *
37 ***************************************************************************/
38
39#include "FreeRTOS.h"
40#include <workqueue.hpp>
41
42
43using namespace cpp_freertos;
44
45
46WorkItem::WorkItem(bool freeAfterComplete)
47 : FreeItemAfterCompleted(freeAfterComplete)
48{
49}
50
51
53{
54}
55
56
58{
60}
61
62
63WorkQueue::WorkQueue( const char * const Name,
64 uint16_t StackDepth,
65 UBaseType_t Priority,
66 UBaseType_t maxWorkItems)
67{
68 //
69 // Build the Queue first, since the Thread is going to access
70 // it as soon as it can, maybe before we leave this ctor.
71 //
72 WorkItemQueue = new Queue(maxWorkItems, sizeof(WorkItem *));
74 WorkerThread = new CWorkerThread(Name, StackDepth, Priority, this);
75 //
76 // Our ctor chain is complete, we can start.
77 //
79}
80
81
82WorkQueue::WorkQueue( uint16_t StackDepth,
83 UBaseType_t Priority,
84 UBaseType_t maxWorkItems)
85{
86 //
87 // Build the Queue first, since the Thread is going to access
88 // it as soon as it can, maybe before we leave this ctor.
89 //
90 WorkItemQueue = new Queue(maxWorkItems, sizeof(WorkItem *));
92 WorkerThread = new CWorkerThread(StackDepth, Priority, this);
93 //
94 // Our ctor chain is complete, we can start.
95 //
97}
98
99
100#if (INCLUDE_vTaskDelete == 1)
101
103{
104 //
105 // This dtor is tricky, because of the multiple objects in
106 // play, and the multithreaded nature of this specific object.
107 //
108
109 //
110 // Note that we cannot flush the queue. If there are items
111 // in the queue maked freeAfterComplete, we would leak the
112 // memory.
113 //
114
115 //
116 // Send a message that it's time to cleanup.
117 //
118 WorkItem *work = NULL;
119 WorkItemQueue->Enqueue(&work);
120
121 //
122 // Wait until the thread has run enough to signal that it's done.
123 //
125
126 //
127 // Then delete the queue and thread. Order doesn't matter here.
128 //
129 delete WorkItemQueue;
130 delete WorkerThread;
131 delete ThreadComplete;
132}
133
134#endif
135
136
138{
139 return WorkItemQueue->Enqueue(&work);
140}
141
142
144 uint16_t StackDepth,
145 UBaseType_t Priority,
146 WorkQueue *Parent)
147 : Thread(Name, StackDepth, Priority), ParentWorkQueue(Parent)
148{
149}
150
151
153 UBaseType_t Priority,
154 WorkQueue *Parent)
155 : Thread(StackDepth, Priority), ParentWorkQueue(Parent)
156{
157}
158
159
161{
162}
163
164
166{
167 while (true) {
168
169 WorkItem *work;
170
171 //
172 // Wait forever for work.
173 //
174 ParentWorkQueue->WorkItemQueue->Dequeue(&work);
175
176 //
177 // If we dequeue a NULL item, its our sign to exit.
178 // We are being deconstructed.
179 //
180 if (work == NULL) {
181 //
182 // Exit the task loop.
183 //
184 break;
185 }
186
187 //
188 // Else we have an item, run it.
189 //
190 work->Run();
191
192 //
193 // If this was a dynamic, fire and forget item and we were
194 // requested to clean it up, do so.
195 //
196 if (work->FreeAfterRun()) {
197 delete work;
198 }
199 }
200
201 //
202 // Signal the dtor that the thread is exiting.
203 //
204 ParentWorkQueue->ThreadComplete->Give();
205}
206
207
virtual bool Enqueue(void *item)
Definition: cqueue.cpp:66
bool Take(TickType_t Timeout=portMAX_DELAY)
Definition: csemaphore.cpp:46
virtual void Run()=0
const bool FreeItemAfterCompleted
Definition: workqueue.hpp:117
CWorkerThread(const char *const Name, uint16_t StackDepth, UBaseType_t Priority, WorkQueue *Parent)
Definition: cworkqueue.cpp:143
BinarySemaphore * ThreadComplete
Definition: workqueue.hpp:240
WorkQueue(const char *const Name, uint16_t StackDepth=DEFAULT_WORK_QUEUE_STACK_SIZE, UBaseType_t Priority=DEFAULT_WORK_QUEUE_PRIORITY, UBaseType_t MaxWorkItems=DEFAULT_MAX_WORK_ITEMS)
Definition: cworkqueue.cpp:63
bool QueueWork(WorkItem *work)
Definition: cworkqueue.cpp:137
CWorkerThread * WorkerThread
Definition: workqueue.hpp:230