Skip to content

Commit 7dabc6f

Browse files
GUIDINGLIxiaoxiang781216
authored andcommitted
sched/wdog: Change sq to list
Before wdog module refactoring, we change the sq to double linked list. Signed-off-by: ligd <[email protected]>
1 parent 16df0db commit 7dabc6f

File tree

7 files changed

+66
-101
lines changed

7 files changed

+66
-101
lines changed

include/nuttx/list.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090
} \
9191
while (0)
9292

93+
#define list_is_head(list, item) ((list)->next == (item))
94+
#define list_is_tail(list, item) ((list)->prev == (item))
9395
#define list_peek_head(list) ((list)->next != (list) ? (list)->next : NULL)
9496
#define list_peek_tail(list) ((list)->prev != (list) ? (list)->prev : NULL)
9597

include/nuttx/wdog.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ typedef uint32_t wdparm_t;
6060

6161
typedef CODE void (*wdentry_t)(wdparm_t arg);
6262

63+
/* Avoid the inclusion of nuttx/list.h */
64+
65+
struct wdlist_node
66+
{
67+
FAR struct wdlist_node *prev;
68+
FAR struct wdlist_node *next;
69+
};
70+
6371
/* This is the internal representation of the watchdog timer structure.
6472
* Notice !!!
6573
* Carefully with the struct wdog_s order, you may not directly modify
@@ -69,7 +77,7 @@ typedef CODE void (*wdentry_t)(wdparm_t arg);
6977

7078
struct wdog_s
7179
{
72-
FAR struct wdog_s *next; /* Support for singly linked lists. */
80+
struct wdlist_node node; /* Supports a doubly linked list */
7381
wdparm_t arg; /* Callback argument */
7482
wdentry_t func; /* Function to execute when delay expires */
7583
#ifdef CONFIG_PIC

sched/wdog/wd_cancel.c

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@
5757

5858
int wd_cancel(FAR struct wdog_s *wdog)
5959
{
60-
FAR struct wdog_s *curr;
61-
FAR struct wdog_s *prev;
6260
irqstate_t flags;
6361
int ret = -EINVAL;
6462

@@ -74,60 +72,36 @@ int wd_cancel(FAR struct wdog_s *wdog)
7472

7573
if (wdog != NULL && WDOG_ISACTIVE(wdog))
7674
{
77-
/* Search the g_wdactivelist for the target FCB. We can't use sq_rem
78-
* to do this because there are additional operations that need to be
79-
* done.
80-
*/
81-
82-
prev = NULL;
83-
curr = (FAR struct wdog_s *)g_wdactivelist.head;
84-
85-
while ((curr) && (curr != wdog))
86-
{
87-
prev = curr;
88-
curr = curr->next;
89-
}
90-
91-
/* Check if the watchdog was found in the list. If not, then an OS
92-
* error has occurred because the watchdog is marked active!
93-
*/
94-
95-
DEBUGASSERT(curr);
75+
bool head = list_is_head(&g_wdactivelist, &wdog->node);
76+
FAR struct wdog_s *next = list_next_entry(wdog, struct wdog_s, node);
9677

9778
/* If there is a watchdog in the timer queue after the one that
9879
* is being canceled, then it inherits the remaining ticks.
9980
*/
10081

101-
if (curr->next)
82+
if (next)
10283
{
103-
curr->next->lag += curr->lag;
84+
next->lag += wdog->lag;
10485
}
10586

10687
/* Now, remove the watchdog from the timer queue */
10788

108-
if (prev)
109-
{
110-
/* Remove the watchdog from mid- or end-of-queue */
89+
list_delete(&wdog->node);
11190

112-
sq_remafter((FAR sq_entry_t *)prev, &g_wdactivelist);
113-
}
114-
else
115-
{
116-
/* Remove the watchdog at the head of the queue */
91+
/* Mark the watchdog inactive */
11792

118-
sq_remfirst(&g_wdactivelist);
93+
wdog->func = NULL;
11994

120-
/* Reassess the interval timer that will generate the next
121-
* interval event.
95+
if (head)
96+
{
97+
/* If the watchdog is at the head of the timer queue, then
98+
* we will need to re-adjust the interval timer that will
99+
* generate the next interval event.
122100
*/
123101

124102
nxsched_reassess_timer();
125103
}
126104

127-
/* Mark the watchdog inactive */
128-
129-
wdog->func = NULL;
130-
131105
/* Return success */
132106

133107
ret = OK;

sched/wdog/wd_gettime.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ sclock_t wd_gettime(FAR struct wdog_s *wdog)
6666
FAR struct wdog_s *curr;
6767
sclock_t delay = 0;
6868

69-
for (curr = (FAR struct wdog_s *)g_wdactivelist.head;
70-
curr != NULL;
71-
curr = curr->next)
69+
list_for_every_entry(&g_wdactivelist, curr, struct wdog_s, node)
7270
{
7371
delay += curr->lag;
7472
if (curr == wdog)

sched/wdog/wd_initialize.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
#include <nuttx/config.h>
2626

27-
#include <nuttx/queue.h>
27+
#include <nuttx/list.h>
2828

2929
#include "wdog/wdog.h"
3030

@@ -37,7 +37,7 @@
3737
* this linked list are removed and the function is called.
3838
*/
3939

40-
sq_queue_t g_wdactivelist;
40+
struct list_node g_wdactivelist = LIST_INITIAL_VALUE(g_wdactivelist);
4141

4242
/* This is wdog tickbase, for wd_gettime() may called many times
4343
* between 2 times of wd_timer(), we use it to update wd_gettime().

sched/wdog/wd_start.c

Lines changed: 34 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -91,26 +91,32 @@
9191
static inline void wd_expiration(void)
9292
{
9393
FAR struct wdog_s *wdog;
94+
FAR struct wdog_s *next;
9495
wdentry_t func;
9596

9697
/* Process the watchdog at the head of the list as well as any
9798
* other watchdogs that became ready to run at this time
9899
*/
99100

100-
while (g_wdactivelist.head &&
101-
((FAR struct wdog_s *)g_wdactivelist.head)->lag <= 0)
101+
list_for_every_entry_safe(&g_wdactivelist, wdog,
102+
next, struct wdog_s, node)
102103
{
104+
if (wdog->lag > 0)
105+
{
106+
break;
107+
}
108+
103109
/* Remove the watchdog from the head of the list */
104110

105-
wdog = (FAR struct wdog_s *)sq_remfirst(&g_wdactivelist);
111+
list_delete(&wdog->node);
106112

107113
/* If there is another watchdog behind this one, update its
108114
* its lag (this shouldn't be necessary).
109115
*/
110116

111-
if (g_wdactivelist.head)
117+
if (!list_is_empty(&g_wdactivelist))
112118
{
113-
((FAR struct wdog_s *)g_wdactivelist.head)->lag += wdog->lag;
119+
next->lag += wdog->lag;
114120
}
115121

116122
/* Indicate that the watchdog is no longer active. */
@@ -169,10 +175,8 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
169175
wdentry_t wdentry, wdparm_t arg)
170176
{
171177
FAR struct wdog_s *curr;
172-
FAR struct wdog_s *prev;
173-
FAR struct wdog_s *next;
174-
sclock_t now;
175178
irqstate_t flags;
179+
sclock_t now;
176180

177181
/* Verify the wdog and setup parameters */
178182

@@ -235,7 +239,7 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
235239

236240
/* Do the easy case first -- when the watchdog timer queue is empty. */
237241

238-
if (g_wdactivelist.head == NULL)
242+
if (list_is_empty(&g_wdactivelist))
239243
{
240244
#ifdef CONFIG_SCHED_TICKLESS
241245
/* Update clock tickbase */
@@ -245,31 +249,24 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
245249

246250
/* Add the watchdog to the head == tail of the queue. */
247251

248-
sq_addlast((FAR sq_entry_t *)wdog, &g_wdactivelist);
252+
list_add_tail(&g_wdactivelist, &wdog->node);
249253
}
250254

251255
/* There are other active watchdogs in the timer queue */
252256

253257
else
254258
{
255259
now = 0;
256-
prev = curr = (FAR struct wdog_s *)g_wdactivelist.head;
257-
258-
/* Advance to positive time */
259-
260-
while ((now += curr->lag) < 0 && curr->next)
261-
{
262-
prev = curr;
263-
curr = curr->next;
264-
}
265260

266261
/* Advance past shorter delays */
267262

268-
while (now <= delay && curr->next)
263+
list_for_every_entry(&g_wdactivelist, curr, struct wdog_s, node)
269264
{
270-
prev = curr;
271-
curr = curr->next;
272265
now += curr->lag;
266+
if (now > delay)
267+
{
268+
break;
269+
}
273270
}
274271

275272
/* Check if the new wdog must be inserted before the curr. */
@@ -286,19 +283,7 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
286283

287284
/* Insert the new watchdog in the list */
288285

289-
if (curr == (FAR struct wdog_s *)g_wdactivelist.head)
290-
{
291-
/* Insert the watchdog at the head of the list */
292-
293-
sq_addfirst((FAR sq_entry_t *)wdog, &g_wdactivelist);
294-
}
295-
else
296-
{
297-
/* Insert the watchdog in mid- or end-of-queue */
298-
299-
sq_addafter((FAR sq_entry_t *)prev, (FAR sq_entry_t *)wdog,
300-
&g_wdactivelist);
301-
}
286+
list_add_before(&curr->node, &wdog->node);
302287
}
303288

304289
/* The new watchdog delay time is greater than the curr delay time,
@@ -309,17 +294,8 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
309294
else
310295
{
311296
delay -= now;
312-
if (!curr->next)
313-
{
314-
sq_addlast((FAR sq_entry_t *)wdog, &g_wdactivelist);
315-
}
316-
else
317-
{
318-
next = curr->next;
319-
next->lag -= delay;
320-
sq_addafter((FAR sq_entry_t *)curr, (FAR sq_entry_t *)wdog,
321-
&g_wdactivelist);
322-
}
297+
298+
list_add_tail(&g_wdactivelist, &wdog->node);
323299
}
324300
}
325301

@@ -379,19 +355,21 @@ unsigned int wd_timer(int ticks, bool noswitches)
379355

380356
/* Check if there are any active watchdogs to process */
381357

382-
wdog = (FAR struct wdog_s *)g_wdactivelist.head;
383-
while (wdog != NULL && ticks > 0)
358+
list_for_every_entry(&g_wdactivelist, wdog, struct wdog_s, node)
384359
{
360+
if (ticks <= 0)
361+
{
362+
break;
363+
}
364+
385365
/* Decrement the lag for this watchdog. */
386366

387367
decr = MIN(wdog->lag, ticks);
388368

389369
/* There are. Decrement the lag counter */
390370

391-
wdog->lag -= decr;
392-
ticks -= decr;
393-
394-
wdog = wdog->next;
371+
wdog->lag -= decr;
372+
ticks -= decr;
395373
}
396374

397375
/* Check if the watchdog at the head of the list is ready to run */
@@ -403,8 +381,8 @@ unsigned int wd_timer(int ticks, bool noswitches)
403381

404382
/* Return the delay for the next watchdog to expire */
405383

406-
ret = g_wdactivelist.head ?
407-
MAX(((FAR struct wdog_s *)g_wdactivelist.head)->lag, 1) : 0;
384+
ret = list_is_empty(&g_wdactivelist) ? 0 :
385+
list_first_entry(&g_wdactivelist, struct wdog_s, node)->lag;
408386

409387
/* Return the delay for the next watchdog to expire */
410388

@@ -416,11 +394,11 @@ void wd_timer(void)
416394
{
417395
/* Check if there are any active watchdogs to process */
418396

419-
if (g_wdactivelist.head)
397+
if (!list_is_empty(&g_wdactivelist))
420398
{
421399
/* There are. Decrement the lag counter */
422400

423-
--(((FAR struct wdog_s *)g_wdactivelist.head)->lag);
401+
--(list_first_entry(&g_wdactivelist, struct wdog_s, node)->lag);
424402

425403
/* Check if the watchdog at the head of the list is ready to run */
426404

sched/wdog/wdog.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@
3434
#include <nuttx/clock.h>
3535
#include <nuttx/queue.h>
3636
#include <nuttx/wdog.h>
37+
#include <nuttx/list.h>
3738

3839
/****************************************************************************
3940
* Pre-processor Definitions
4041
****************************************************************************/
4142

43+
/* Redefine to the standard list */
44+
45+
#define list_node wdlist_node
46+
4247
/****************************************************************************
4348
* Name: wd_elapse
4449
*
@@ -73,7 +78,7 @@ extern "C"
7378
* this linked list are removed and the function is called.
7479
*/
7580

76-
extern sq_queue_t g_wdactivelist;
81+
extern struct list_node g_wdactivelist;
7782

7883
/* This is wdog tickbase, for wd_gettime() may called many times
7984
* between 2 times of wd_timer(), we use it to update wd_gettime().

0 commit comments

Comments
 (0)