Skip to content

Commit

Permalink
pyqueue: add internal queue data structure
Browse files Browse the repository at this point in the history
  • Loading branch information
colesbury committed Apr 23, 2023
1 parent 86efa7d commit 74df778
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Include/cpython/pyqueue.h
Original file line number Diff line number Diff line change
@@ -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 */
61 changes: 61 additions & 0 deletions Include/internal/pycore_pyqueue.h
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions PCbuild/pythoncore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
<ClInclude Include="..\Include\internal\pycore_pymem_init.h" />
<ClInclude Include="..\Include\internal\pycore_pyqueue.h" />
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
<ClInclude Include="..\Include\internal\pycore_pythread.h" />
<ClInclude Include="..\Include\internal\pycore_qsbr.h" />
Expand Down
3 changes: 3 additions & 0 deletions PCbuild/pythoncore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,9 @@
<ClInclude Include="..\Include\internal\pycore_pymem_init.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_pyqueue.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_pystate.h">
<Filter>Include\internal</Filter>
</ClInclude>
Expand Down

0 comments on commit 74df778

Please sign in to comment.