From: Kent Gibson <warthog618@gmail.com>
To: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Jack Winch <sunt.un.morcov@gmail.com>,
Helmut Grohne <helmut.grohne@intenta.de>,
linux-gpio@vger.kernel.org,
Bartosz Golaszewski <bgolaszewski@baylibre.com>
Subject: Re: [PATCH v2] treewide: rework struct gpiod_line_bulk
Date: Wed, 28 Oct 2020 17:39:28 +0800 [thread overview]
Message-ID: <20201028093928.GA152368@sol> (raw)
In-Reply-To: <20201027091715.8958-1-brgl@bgdev.pl>
On Tue, Oct 27, 2020 at 10:17:15AM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
Subject should be prefixed with [libgpiod] according to the README ;).
[snip]
> diff --git a/bindings/cxx/line_bulk.cpp b/bindings/cxx/line_bulk.cpp
> index e77baa2..e7bd20e 100644
> --- a/bindings/cxx/line_bulk.cpp
> +++ b/bindings/cxx/line_bulk.cpp
> @@ -46,6 +46,29 @@ const ::std::map<::std::bitset<32>, int, bitset_cmp> reqflag_mapping = {
> { line_request::FLAG_BIAS_PULL_UP, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP, },
> };
>
A - see comment after line_bulk::event_wait()
> +struct line_bulk_iter_deleter
> +{
> + void operator()(::gpiod_line_bulk_iter *iter)
> + {
> + ::gpiod_line_bulk_iter_free(iter);
> + }
> +};
> +
> +using line_bulk_iter_ptr = ::std::unique_ptr<::gpiod_line_bulk_iter,
> + line_bulk_iter_deleter>;
> +
> +line_bulk_iter_ptr make_line_bulk_iter(::gpiod_line_bulk *bulk)
> +{
> + ::gpiod_line_bulk_iter *iter;
> +
> + iter = ::gpiod_line_bulk_iter_new(bulk);
> + if (!iter)
> + throw ::std::system_error(errno, ::std::system_category(),
> + "Unable to create new line bulk iterator");
> +
> + return line_bulk_iter_ptr(iter);
> +}
> +
B - see comment after line_bulk::event_wait()
> } /* namespace */
>
[snip]
> @@ -263,27 +270,26 @@ line_bulk line_bulk::event_wait(const ::std::chrono::nanoseconds& timeout) const
> {
> this->throw_if_empty();
>
> - ::gpiod_line_bulk bulk, event_bulk;
> + line_bulk_ptr ev_bulk(::gpiod_line_bulk_new(this->size()));
> + auto chip = this->_m_bulk[0].get_chip();
Move chip into the block where it is used.
> + auto bulk = this->to_line_bulk();
> ::timespec ts;
> line_bulk ret;
> int rv;
>
> - this->to_line_bulk(::std::addressof(bulk));
> -
> - ::gpiod_line_bulk_init(::std::addressof(event_bulk));
> -
> ts.tv_sec = timeout.count() / 1000000000ULL;
> ts.tv_nsec = timeout.count() % 1000000000ULL;
>
> - rv = ::gpiod_line_event_wait_bulk(::std::addressof(bulk),
> - ::std::addressof(ts),
> - ::std::addressof(event_bulk));
> + rv = ::gpiod_line_event_wait_bulk(bulk.get(), ::std::addressof(ts), ev_bulk.get());
> if (rv < 0) {
> throw ::std::system_error(errno, ::std::system_category(),
> "error polling for events");
> } else if (rv > 0) {
> - for (unsigned int i = 0; i < event_bulk.num_lines; i++)
> - ret.append(line(event_bulk.lines[i], this->_m_bulk[i].get_chip()));
> + auto iter = make_line_bulk_iter(ev_bulk.get());
> + ::gpiod_line *curr_line;
> +
> + gpiod_line_bulk_iter_foreach_line(iter.get(), curr_line)
> + ret.append(line(curr_line, chip));
> }
>
If you replace the gpiod_line_bulk_iter_foreach_line() here with
manually looping over the bulk lines then everything from A to B above
can be dropped.
i.e.
- auto iter = make_line_bulk_iter(ev_bulk.get());
- ::gpiod_line *curr_line;
+ auto chip = this->_m_bulk[0].get_chip();
+ auto num_lines = ::gpiod_line_bulk_num_lines(ev_bulk.get());
- gpiod_line_bulk_iter_foreach_line(iter.get(), curr_line)
- ret.append(line(curr_line, chip));
+ for (unsigned int i = 0; i < num_lines; i++)
+ ret.append(line(::gpiod_line_bulk_get_line(ev_bulk.get(), i), chip));
That includes the chip relocation, btw.
[snip]
> }
> @@ -1715,9 +1751,10 @@ static PyObject *gpiod_LineBulk_event_wait(gpiod_LineBulkObject *self,
> {
> static char *kwlist[] = { "sec", "nsec", NULL };
>
> - struct gpiod_line_bulk bulk, ev_bulk;
> - struct gpiod_line *line, **line_ptr;
> + struct gpiod_line_bulk *bulk, *ev_bulk;
> + struct gpiod_line_bulk_iter *iter;
> gpiod_LineObject *line_obj;
> + struct gpiod_line *line;
> gpiod_ChipObject *owner;
> long sec = 0, nsec = 0;
> struct timespec ts;
> @@ -1736,37 +1773,64 @@ static PyObject *gpiod_LineBulk_event_wait(gpiod_LineBulkObject *self,
> ts.tv_sec = sec;
> ts.tv_nsec = nsec;
>
> - gpiod_LineBulkObjToCLineBulk(self, &bulk);
> + bulk = gpiod_LineBulkObjToCLineBulk(self);
> + if (!bulk)
> + return NULL;
> +
> + ev_bulk = gpiod_line_bulk_new(self->num_lines);
> + if (!ev_bulk) {
> + gpiod_line_bulk_free(bulk);
> + return NULL;
> + }
>
> Py_BEGIN_ALLOW_THREADS;
> - rv = gpiod_line_event_wait_bulk(&bulk, &ts, &ev_bulk);
> + rv = gpiod_line_event_wait_bulk(bulk, &ts, ev_bulk);
> + gpiod_line_bulk_free(bulk);
> Py_END_ALLOW_THREADS;
> - if (rv < 0)
> + if (rv < 0) {
> + gpiod_line_bulk_free(ev_bulk);
> return PyErr_SetFromErrno(PyExc_OSError);
> - else if (rv == 0)
> + } else if (rv == 0) {
> + gpiod_line_bulk_free(ev_bulk);
> Py_RETURN_NONE;
> + }
>
> - ret = PyList_New(gpiod_line_bulk_num_lines(&ev_bulk));
> - if (!ret)
> + ret = PyList_New(gpiod_line_bulk_num_lines(ev_bulk));
> + if (!ret) {
> + gpiod_line_bulk_free(ev_bulk);
> return NULL;
> + }
>
> owner = ((gpiod_LineObject *)(self->lines[0]))->owner;
>
> + iter = gpiod_line_bulk_iter_new(ev_bulk);
> + if (!iter) {
> + gpiod_line_bulk_free(ev_bulk);
> + return PyErr_SetFromErrno(PyExc_OSError);
> + }
> +
> i = 0;
> - gpiod_line_bulk_foreach_line(&ev_bulk, line, line_ptr) {
> + gpiod_line_bulk_iter_foreach_line(iter, line) {
> line_obj = gpiod_MakeLineObject(owner, line);
> if (!line_obj) {
> + gpiod_line_bulk_iter_free(iter);
> + gpiod_line_bulk_free(ev_bulk);
> Py_DECREF(ret);
> return NULL;
> }
>
> rv = PyList_SetItem(ret, i++, (PyObject *)line_obj);
> if (rv < 0) {
> + gpiod_line_bulk_iter_free(iter);
> + gpiod_line_bulk_free(ev_bulk);
> Py_DECREF(ret);
> return NULL;
> }
> }
>
This function can be simplified by looping over the bulk manually rather
than using the line_bulk_iter.
> + gpiod_line_bulk_iter_free(iter);
> + gpiod_line_bulk_free(ev_bulk);
> +
> return ret;
> }
>
> @@ -2241,41 +2305,59 @@ PyDoc_STRVAR(gpiod_Chip_get_all_lines_doc,
> static gpiod_LineBulkObject *
> gpiod_Chip_get_all_lines(gpiod_ChipObject *self, PyObject *Py_UNUSED(ignored))
> {
> + struct gpiod_line_bulk_iter *iter;
> gpiod_LineBulkObject *bulk_obj;
> - struct gpiod_line_bulk bulk;
> + struct gpiod_line_bulk *bulk;
> gpiod_LineObject *line_obj;
> struct gpiod_line *line;
> - unsigned int offset;
> + unsigned int index = 0;
> PyObject *list;
> int rv;
>
> if (gpiod_ChipIsClosed(self))
> return NULL;
>
> - rv = gpiod_chip_get_all_lines(self->chip, &bulk);
> - if (rv)
> + bulk = gpiod_chip_get_all_lines(self->chip);
> + if (!bulk)
> return (gpiod_LineBulkObject *)PyErr_SetFromErrno(
> PyExc_OSError);
>
> - list = PyList_New(gpiod_line_bulk_num_lines(&bulk));
> - if (!list)
> + list = PyList_New(gpiod_line_bulk_num_lines(bulk));
> + if (!list) {
> + gpiod_line_bulk_free(bulk);
> return NULL;
> + }
>
> - gpiod_line_bulk_foreach_line_off(&bulk, line, offset) {
> + iter = gpiod_line_bulk_iter_new(bulk);
> + if (!iter) {
> + gpiod_line_bulk_free(bulk);
> + Py_DECREF(list);
> + return (gpiod_LineBulkObject *)PyErr_SetFromErrno(
> + PyExc_OSError);
> + }
> +
> + gpiod_line_bulk_iter_foreach_line(iter, line) {
> line_obj = gpiod_MakeLineObject(self, line);
> if (!line_obj) {
> + gpiod_line_bulk_iter_free(iter);
> + gpiod_line_bulk_free(bulk);
> Py_DECREF(list);
> return NULL;
> }
>
Again, NOT using the line_bulk_iter here, and manually looping instead, is
actually simpler and cleaner.
Cheers,
Kent.
next prev parent reply other threads:[~2020-10-28 21:58 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-27 9:17 [PATCH v2] treewide: rework struct gpiod_line_bulk Bartosz Golaszewski
2020-10-28 9:39 ` Kent Gibson [this message]
2020-10-28 13:19 ` Bartosz Golaszewski
2020-10-28 15:03 ` Kent Gibson
2020-10-28 16:26 ` Bartosz Golaszewski
2020-10-28 23:07 ` Kent Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201028093928.GA152368@sol \
--to=warthog618@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bgolaszewski@baylibre.com \
--cc=brgl@bgdev.pl \
--cc=geert@linux-m68k.org \
--cc=helmut.grohne@intenta.de \
--cc=linux-gpio@vger.kernel.org \
--cc=sunt.un.morcov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).