Skip to content

Commit 51483f6

Browse files
committed
include: Move QemuLockCnt APIs to their own header
Currently the QemuLockCnt data structure and associated functions are in the include/qemu/thread.h header. Move them to their own qemu/lockcnt.h. The main reason for doing this is that it means we can autogenerate the documentation comments into the docs/devel documentation. The copyright/author in the new header is drawn from lockcnt.c, since the header changes were added in the same commit as lockcnt.c; since neither thread.h nor lockcnt.c state an explicit license, the standard default of GPL-2-or-later applies. We include the new header (and the .c file, which was accidentally omitted previously) in the "RCU" part of MAINTAINERS, since that is where the lockcnt.rst documentation is categorized. Signed-off-by: Peter Maydell <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Acked-by: Paolo Bonzini <[email protected]> Message-id: [email protected]
1 parent 90655d8 commit 51483f6

File tree

13 files changed

+142
-112
lines changed

13 files changed

+142
-112
lines changed

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,8 +3061,10 @@ S: Maintained
30613061
F: docs/devel/lockcnt.rst
30623062
F: docs/devel/rcu.rst
30633063
F: include/qemu/rcu*.h
3064+
F: include/qemu/lockcnt.h
30643065
F: tests/unit/rcutorture.c
30653066
F: tests/unit/test-rcu-*.c
3067+
F: util/lockcnt.c
30663068
F: util/rcu.c
30673069

30683070
Human Monitor (HMP)

accel/accel-blocker.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626

2727
#include "qemu/osdep.h"
28+
#include "qemu/lockcnt.h"
2829
#include "qemu/thread.h"
2930
#include "qemu/main-loop.h"
3031
#include "hw/core/cpu.h"

docs/devel/lockcnt.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ three instructions in the critical path, two assignments and a ``smp_wmb()``.
175175
``QemuLockCnt`` API
176176
-------------------
177177

178-
The ``QemuLockCnt`` API is described in ``include/qemu/thread.h``.
178+
The ``QemuLockCnt`` API is described in ``include/qemu/lockcnt.h``.
179179

180180

181181
``QemuLockCnt`` usage

hw/core/cpu-common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "sysemu/hw_accel.h"
2525
#include "qemu/log.h"
2626
#include "qemu/main-loop.h"
27+
#include "qemu/lockcnt.h"
2728
#include "exec/log.h"
2829
#include "exec/gdbstub.h"
2930
#include "sysemu/tcg.h"

include/block/aio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "qemu/coroutine-core.h"
2121
#include "qemu/queue.h"
2222
#include "qemu/event_notifier.h"
23+
#include "qemu/lockcnt.h"
2324
#include "qemu/thread.h"
2425
#include "qemu/timer.h"
2526
#include "block/graph-lock.h"

include/hw/core/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "qemu/bitmap.h"
3434
#include "qemu/rcu_queue.h"
3535
#include "qemu/queue.h"
36+
#include "qemu/lockcnt.h"
3637
#include "qemu/thread.h"
3738
#include "qom/object.h"
3839

include/qemu/lockcnt.h

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* QemuLockCnt implementation
4+
*
5+
* Copyright Red Hat, Inc. 2017
6+
*
7+
* Author:
8+
* Paolo Bonzini <[email protected]>
9+
*
10+
*/
11+
12+
#ifndef QEMU_LOCKCNT_H
13+
#define QEMU_LOCKCNT_H
14+
15+
#include "qemu/thread.h"
16+
17+
typedef struct QemuLockCnt QemuLockCnt;
18+
19+
struct QemuLockCnt {
20+
#ifndef CONFIG_LINUX
21+
QemuMutex mutex;
22+
#endif
23+
unsigned count;
24+
};
25+
26+
/**
27+
* qemu_lockcnt_init: initialize a QemuLockcnt
28+
* @lockcnt: the lockcnt to initialize
29+
*
30+
* Initialize lockcnt's counter to zero and prepare its mutex
31+
* for usage.
32+
*/
33+
void qemu_lockcnt_init(QemuLockCnt *lockcnt);
34+
35+
/**
36+
* qemu_lockcnt_destroy: destroy a QemuLockcnt
37+
* @lockcnt: the lockcnt to destruct
38+
*
39+
* Destroy lockcnt's mutex.
40+
*/
41+
void qemu_lockcnt_destroy(QemuLockCnt *lockcnt);
42+
43+
/**
44+
* qemu_lockcnt_inc: increment a QemuLockCnt's counter
45+
* @lockcnt: the lockcnt to operate on
46+
*
47+
* If the lockcnt's count is zero, wait for critical sections
48+
* to finish and increment lockcnt's count to 1. If the count
49+
* is not zero, just increment it.
50+
*
51+
* Because this function can wait on the mutex, it must not be
52+
* called while the lockcnt's mutex is held by the current thread.
53+
* For the same reason, qemu_lockcnt_inc can also contribute to
54+
* AB-BA deadlocks. This is a sample deadlock scenario:
55+
*
56+
* thread 1 thread 2
57+
* -------------------------------------------------------
58+
* qemu_lockcnt_lock(&lc1);
59+
* qemu_lockcnt_lock(&lc2);
60+
* qemu_lockcnt_inc(&lc2);
61+
* qemu_lockcnt_inc(&lc1);
62+
*/
63+
void qemu_lockcnt_inc(QemuLockCnt *lockcnt);
64+
65+
/**
66+
* qemu_lockcnt_dec: decrement a QemuLockCnt's counter
67+
* @lockcnt: the lockcnt to operate on
68+
*/
69+
void qemu_lockcnt_dec(QemuLockCnt *lockcnt);
70+
71+
/**
72+
* qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and
73+
* possibly lock it.
74+
* @lockcnt: the lockcnt to operate on
75+
*
76+
* Decrement lockcnt's count. If the new count is zero, lock
77+
* the mutex and return true. Otherwise, return false.
78+
*/
79+
bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt);
80+
81+
/**
82+
* qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and
83+
* lock it.
84+
* @lockcnt: the lockcnt to operate on
85+
*
86+
* If the count is 1, decrement the count to zero, lock
87+
* the mutex and return true. Otherwise, return false.
88+
*/
89+
bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt);
90+
91+
/**
92+
* qemu_lockcnt_lock: lock a QemuLockCnt's mutex.
93+
* @lockcnt: the lockcnt to operate on
94+
*
95+
* Remember that concurrent visits are not blocked unless the count is
96+
* also zero. You can use qemu_lockcnt_count to check for this inside a
97+
* critical section.
98+
*/
99+
void qemu_lockcnt_lock(QemuLockCnt *lockcnt);
100+
101+
/**
102+
* qemu_lockcnt_unlock: release a QemuLockCnt's mutex.
103+
* @lockcnt: the lockcnt to operate on.
104+
*/
105+
void qemu_lockcnt_unlock(QemuLockCnt *lockcnt);
106+
107+
/**
108+
* qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt.
109+
* @lockcnt: the lockcnt to operate on.
110+
*
111+
* This is the same as
112+
*
113+
* qemu_lockcnt_unlock(lockcnt);
114+
* qemu_lockcnt_inc(lockcnt);
115+
*
116+
* but more efficient.
117+
*/
118+
void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt);
119+
120+
/**
121+
* qemu_lockcnt_count: query a LockCnt's count.
122+
* @lockcnt: the lockcnt to query.
123+
*
124+
* Note that the count can change at any time. Still, while the
125+
* lockcnt is locked, one can usefully check whether the count
126+
* is non-zero.
127+
*/
128+
unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt);
129+
130+
#endif

include/qemu/thread.h

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -293,115 +293,4 @@ static inline void qemu_spin_unlock(QemuSpin *spin)
293293
#endif
294294
}
295295

296-
struct QemuLockCnt {
297-
#ifndef CONFIG_LINUX
298-
QemuMutex mutex;
299-
#endif
300-
unsigned count;
301-
};
302-
303-
/**
304-
* qemu_lockcnt_init: initialize a QemuLockcnt
305-
* @lockcnt: the lockcnt to initialize
306-
*
307-
* Initialize lockcnt's counter to zero and prepare its mutex
308-
* for usage.
309-
*/
310-
void qemu_lockcnt_init(QemuLockCnt *lockcnt);
311-
312-
/**
313-
* qemu_lockcnt_destroy: destroy a QemuLockcnt
314-
* @lockcnt: the lockcnt to destruct
315-
*
316-
* Destroy lockcnt's mutex.
317-
*/
318-
void qemu_lockcnt_destroy(QemuLockCnt *lockcnt);
319-
320-
/**
321-
* qemu_lockcnt_inc: increment a QemuLockCnt's counter
322-
* @lockcnt: the lockcnt to operate on
323-
*
324-
* If the lockcnt's count is zero, wait for critical sections
325-
* to finish and increment lockcnt's count to 1. If the count
326-
* is not zero, just increment it.
327-
*
328-
* Because this function can wait on the mutex, it must not be
329-
* called while the lockcnt's mutex is held by the current thread.
330-
* For the same reason, qemu_lockcnt_inc can also contribute to
331-
* AB-BA deadlocks. This is a sample deadlock scenario:
332-
*
333-
* thread 1 thread 2
334-
* -------------------------------------------------------
335-
* qemu_lockcnt_lock(&lc1);
336-
* qemu_lockcnt_lock(&lc2);
337-
* qemu_lockcnt_inc(&lc2);
338-
* qemu_lockcnt_inc(&lc1);
339-
*/
340-
void qemu_lockcnt_inc(QemuLockCnt *lockcnt);
341-
342-
/**
343-
* qemu_lockcnt_dec: decrement a QemuLockCnt's counter
344-
* @lockcnt: the lockcnt to operate on
345-
*/
346-
void qemu_lockcnt_dec(QemuLockCnt *lockcnt);
347-
348-
/**
349-
* qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and
350-
* possibly lock it.
351-
* @lockcnt: the lockcnt to operate on
352-
*
353-
* Decrement lockcnt's count. If the new count is zero, lock
354-
* the mutex and return true. Otherwise, return false.
355-
*/
356-
bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt);
357-
358-
/**
359-
* qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and
360-
* lock it.
361-
* @lockcnt: the lockcnt to operate on
362-
*
363-
* If the count is 1, decrement the count to zero, lock
364-
* the mutex and return true. Otherwise, return false.
365-
*/
366-
bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt);
367-
368-
/**
369-
* qemu_lockcnt_lock: lock a QemuLockCnt's mutex.
370-
* @lockcnt: the lockcnt to operate on
371-
*
372-
* Remember that concurrent visits are not blocked unless the count is
373-
* also zero. You can use qemu_lockcnt_count to check for this inside a
374-
* critical section.
375-
*/
376-
void qemu_lockcnt_lock(QemuLockCnt *lockcnt);
377-
378-
/**
379-
* qemu_lockcnt_unlock: release a QemuLockCnt's mutex.
380-
* @lockcnt: the lockcnt to operate on.
381-
*/
382-
void qemu_lockcnt_unlock(QemuLockCnt *lockcnt);
383-
384-
/**
385-
* qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt.
386-
* @lockcnt: the lockcnt to operate on.
387-
*
388-
* This is the same as
389-
*
390-
* qemu_lockcnt_unlock(lockcnt);
391-
* qemu_lockcnt_inc(lockcnt);
392-
*
393-
* but more efficient.
394-
*/
395-
void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt);
396-
397-
/**
398-
* qemu_lockcnt_count: query a LockCnt's count.
399-
* @lockcnt: the lockcnt to query.
400-
*
401-
* Note that the count can change at any time. Still, while the
402-
* lockcnt is locked, one can usefully check whether the count
403-
* is non-zero.
404-
*/
405-
unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt);
406-
407296
#endif

util/aio-posix.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "block/block.h"
1818
#include "block/thread-pool.h"
1919
#include "qemu/main-loop.h"
20+
#include "qemu/lockcnt.h"
2021
#include "qemu/rcu.h"
2122
#include "qemu/rcu_queue.h"
2223
#include "qemu/sockets.h"

util/aio-win32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "qemu/osdep.h"
1919
#include "block/block.h"
2020
#include "qemu/main-loop.h"
21+
#include "qemu/lockcnt.h"
2122
#include "qemu/queue.h"
2223
#include "qemu/sockets.h"
2324
#include "qapi/error.h"

0 commit comments

Comments
 (0)