Skip to content

Commit b2b05ea

Browse files
committed
implement __sizeof__ for SimpleQueue to account for ring-buffer storage
1 parent 4d03baf commit b2b05ea

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

Lib/test/test_queue.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
from test.support import gc_collect, bigmemtest
1010
from test.support import import_helper
1111
from test.support import threading_helper
12-
import ctypes
12+
import sys
13+
from test import support
1314

1415
# queue module depends on threading primitives
1516
threading_helper.requires_working_threading(module=True)
@@ -1034,12 +1035,12 @@ def test_is_default(self):
10341035

10351036
def test_simplequeue_sizeof_reflects_buffer_growth(self):
10361037
q = self.type2test()
1037-
before = q.__sizeof__()
1038+
before = sys.getsizeof(q)
10381039
for _ in range(1000):
10391040
q.put(object())
1040-
after = q.__sizeof__()
1041+
after = sys.getsizeof(q)
10411042
self.assertGreater(after, before)
1042-
ptr = ctypes.sizeof(ctypes.c_void_p)
1043+
ptr = support.calcobjsize(1) - support.calcobjsize(0)
10431044
self.assertEqual((after - before) % ptr, 0)
10441045

10451046
def test_reentrancy(self):

Modules/_queuemodule.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,18 +238,28 @@ simplequeue_traverse(PyObject *op, visitproc visit, void *arg)
238238
Py_VISIT(Py_TYPE(self));
239239
return 0;
240240
}
241-
static PyObject *
242-
simplequeue_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored))
241+
242+
/*[clinic input]
243+
@critical_section
244+
_queue.SimpleQueue.__sizeof__ -> Py_ssize_t
245+
246+
Returns size in memory, in bytes.
247+
[clinic start generated code]*/
248+
249+
static Py_ssize_t
250+
_queue_SimpleQueue___sizeof___impl(simplequeueobject *self)
243251
{
244-
simplequeueobject *self = simplequeueobject_CAST(op);
245252
Py_ssize_t size = Py_TYPE(self)->tp_basicsize;
253+
PyObject **items = self->buf.items;
254+
Py_ssize_t items_cap = self->buf.items_cap;
246255

247-
if (self->buf.items != NULL) {
248-
size += (Py_ssize_t)self->buf.items_cap * (Py_ssize_t)sizeof(PyObject *);
256+
if (items != NULL) {
257+
size += items_cap * (Py_ssize_t)sizeof(void *);
249258
}
250259

251-
return PyLong_FromSsize_t(size);
260+
return size;
252261
}
262+
/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/
253263

254264
/*[clinic input]
255265
@classmethod
@@ -546,7 +556,7 @@ static PyMethodDef simplequeue_methods[] = {
546556
_QUEUE_SIMPLEQUEUE_PUT_METHODDEF
547557
_QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF
548558
_QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF
549-
{"__sizeof__", (PyCFunction)simplequeue_sizeof, METH_NOARGS, NULL},
559+
_QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF
550560
{"__class_getitem__", Py_GenericAlias,
551561
METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
552562
{NULL, NULL} /* sentinel */

Modules/clinic/_queuemodule.c.h

Lines changed: 31 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)