From 74df7785f5779a6878932f2141a6a2db9e1d903e Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 6 Mar 2023 08:17:19 -0800 Subject: [PATCH] pyqueue: add internal queue data structure --- Include/cpython/pyqueue.h | 18 +++++++++ Include/internal/pycore_pyqueue.h | 61 ++++++++++++++++++++++++++++++ Makefile.pre.in | 1 + PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 ++ 5 files changed, 84 insertions(+) create mode 100644 Include/cpython/pyqueue.h create mode 100644 Include/internal/pycore_pyqueue.h diff --git a/Include/cpython/pyqueue.h b/Include/cpython/pyqueue.h new file mode 100644 index 0000000000..2f6a034698 --- /dev/null +++ b/Include/cpython/pyqueue.h @@ -0,0 +1,18 @@ +#ifndef Py_PYQUEUE_H +#define Py_PYQUEUE_H +/* Header excluded from the stable API */ +#ifndef Py_LIMITED_API + +// See pycore_pyqueue.h for the implementation of the queue API. + +struct _Py_queue_node { + struct _Py_queue_node *next; +}; + +struct _Py_queue_head { + struct _Py_queue_node first; + struct _Py_queue_node *tail; +}; + +#endif /* !defined(Py_LIMITED_API) */ +#endif /* !Py_PYQUEUE_H */ diff --git a/Include/internal/pycore_pyqueue.h b/Include/internal/pycore_pyqueue.h new file mode 100644 index 0000000000..2a56497b00 --- /dev/null +++ b/Include/internal/pycore_pyqueue.h @@ -0,0 +1,61 @@ +#ifndef Py_INTERNAL_PYQUEUE_H +#define Py_INTERNAL_PYQUEUE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +// Implementation of a queue that uses a singly linked list of +// struct _Py_queue_node pointers. The queue is represented by a +// struct _Py_queue_head which contains pointers to the first and +// last node in the queue. + +static inline void +_Py_queue_init(struct _Py_queue_head *head) +{ + head->first.next = head->tail = &head->first; +} + +static inline bool +_Py_queue_is_empty(struct _Py_queue_head *head) +{ + return head->first.next == &head->first; +} + +static inline void +_Py_queue_enqeue(struct _Py_queue_head *head, struct _Py_queue_node *node) +{ + node->next = &head->first; + head->tail->next = node; + head->tail = node; +} + +static inline struct _Py_queue_node * +_Py_queue_dequeue(struct _Py_queue_head *head) +{ + if (_Py_queue_is_empty(head)) { + return NULL; + } + struct _Py_queue_node *node = head->first.next; + head->first.next = node->next; + if (node->next == &head->first) { + head->tail = &head->first; + } + return node; +} + +#define _Py_queue_data(node, type, member) \ + (type*)((char*)node - offsetof(type, member)) + +#define _Py_queue_first(head, type, member) (_Py_queue_data(((head)->first.next), type, member)) + +#define _Py_queue_last(head, type, member) (_Py_queue_data(((head)->tail), type, member)) + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_PYQUEUE_H diff --git a/Makefile.pre.in b/Makefile.pre.in index f00a82a809..cb6f5e8b9c 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1706,6 +1706,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ $(srcdir)/Include/internal/pycore_pymem_init.h \ + $(srcdir)/Include/internal/pycore_pyqueue.h \ $(srcdir)/Include/internal/pycore_pystate.h \ $(srcdir)/Include/internal/pycore_pythread.h \ $(srcdir)/Include/internal/pycore_range.h \ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 0b6b3a96be..6c44f7be24 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -251,6 +251,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 71ac510d2a..9b4b4dcc31 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -663,6 +663,9 @@ Include\internal + + Include\internal + Include\internal