VirtualBox

source: vbox/trunk/include/iprt/queueatomic.h@ 99739

Last change on this file since 99739 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.8 KB
Line 
1/** @file
2 * IPRT - Generic Work Queue with concurrent atomic access.
3 */
4
5/*
6 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_queueatomic_h
37#define IPRT_INCLUDED_queueatomic_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/types.h>
43#include <iprt/asm.h>
44
45/** @defgroup grp_rt_queueatomic RTQueueAtomic - Generic Work Queue
46 * @ingroup grp_rt
47 *
48 * Implementation of a lockless work queue for threaded environments.
49 * @{
50 */
51
52RT_C_DECLS_BEGIN
53
54/**
55 * A work item
56 */
57typedef struct RTQUEUEATOMICITEM
58{
59 /** Pointer to the next work item in the list. */
60 struct RTQUEUEATOMICITEM * volatile pNext;
61} RTQUEUEATOMICITEM;
62/** Pointer to a work item. */
63typedef RTQUEUEATOMICITEM *PRTQUEUEATOMICITEM;
64/** Pointer to a work item pointer. */
65typedef PRTQUEUEATOMICITEM *PPRTQUEUEATOMICITEM;
66
67/**
68 * Work queue.
69 */
70typedef struct RTQUEUEATOMIC
71{
72 /* Head of the work queue. */
73 volatile PRTQUEUEATOMICITEM pHead;
74} RTQUEUEATOMIC;
75/** Pointer to a work queue. */
76typedef RTQUEUEATOMIC *PRTQUEUEATOMIC;
77
78/**
79 * Initialize a work queue.
80 *
81 * @param pWorkQueue Pointer to an unitialised work queue.
82 */
83DECLINLINE(void) RTQueueAtomicInit(PRTQUEUEATOMIC pWorkQueue)
84{
85 ASMAtomicWriteNullPtr(&pWorkQueue->pHead);
86}
87
88/**
89 * Insert a new item into the work queue.
90 *
91 * @param pWorkQueue The work queue to insert into.
92 * @param pItem The item to insert.
93 */
94DECLINLINE(void) RTQueueAtomicInsert(PRTQUEUEATOMIC pWorkQueue, PRTQUEUEATOMICITEM pItem)
95{
96 PRTQUEUEATOMICITEM pNext = ASMAtomicUoReadPtrT(&pWorkQueue->pHead, PRTQUEUEATOMICITEM);
97 PRTQUEUEATOMICITEM pHeadOld;
98 pItem->pNext = pNext;
99 while (!ASMAtomicCmpXchgExPtr(&pWorkQueue->pHead, pItem, pNext, &pHeadOld))
100 {
101 pNext = pHeadOld;
102 Assert(pNext != pItem);
103 pItem->pNext = pNext;
104 ASMNopPause();
105 }
106}
107
108/**
109 * Remove all items from the given work queue and return them in the inserted order.
110 *
111 * @returns Pointer to the first item.
112 * @param pWorkQueue The work queue.
113 */
114DECLINLINE(PRTQUEUEATOMICITEM) RTQueueAtomicRemoveAll(PRTQUEUEATOMIC pWorkQueue)
115{
116 PRTQUEUEATOMICITEM pHead = ASMAtomicXchgPtrT(&pWorkQueue->pHead, NULL, PRTQUEUEATOMICITEM);
117
118 /* Reverse it. */
119 PRTQUEUEATOMICITEM pCur = pHead;
120 pHead = NULL;
121 while (pCur)
122 {
123 PRTQUEUEATOMICITEM pInsert = pCur;
124 pCur = pCur->pNext;
125 pInsert->pNext = pHead;
126 pHead = pInsert;
127 }
128
129 return pHead;
130}
131
132RT_C_DECLS_END
133
134/** @} */
135
136#endif /* !IPRT_INCLUDED_queueatomic_h */
137
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette