Re: [PATCH V6 3/8] libgpiod: Add rust wrapper crate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 27, 2022 at 3:57 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote:
>
> On Tue, 27 Sept 2022 at 18:48, Bartosz Golaszewski <brgl@xxxxxxxx> wrote:
> > On Mon, Sep 26, 2022 at 5:27 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote:
>
> > > This is where Rust's memory safety comes in. If you see the design of
> > > the 'structure Event', it saves a reference to the 'struct BufferInternal'.
> > > The drop() implementation of BufferInternal calls:
> > > gpiod_edge_event_buffer_free(), but it won't get called unless all the
> > > references to it have gone out of scope. So untill the time user is still
> > > using any of the events, the buffer won't get freed. So we will never
> > > have invalid reference issue here.
> >
> > You've got to help me out here, just looking at the code doesn't make
> > things clear for me.
>
> Just to clarify, Buffer is just a wrapper over BufferInternal, you can think
> of them as the same entity for simplicity.
>
> > Am I right to understand that each Event holds a reference to the
> > BufferInternal object and it will only be destroyed when the last
> > event is dropped?
>
> Yes. But the buffer variable itself too holds a reference to the Buffer.
> Even if all the events are dropped, the buffer won't get free unless the
> buffer variable gets dropped too.
>
> > If we read new events into the buffer, does that
> > create a new BufferInternal?
>
> No. It uses the existing buffer only, that we created using Buffer::new().
>

So what happens if I do this:

let buf = edge::event::Buffer::new(10)?;
let request = chip.request_lines(&rconfig, &lconfig)?;
let count = request.read_edge_events(&buffer)?;
let event = buffer.event(0);
let count = request.read_edge_events(&buffer)?;
println!("line: {}", event.line_offset());

?

> > Is that efficient? Aren't we allocating
> > memory for each new BufferInternal at every read?
>
> No, we reuse the same buffer for all the reads.
>
> If you see the gpiomon.rs example, it shows how this is being done.
> The buffer (and internal buffer too) is created only once in line 42:
>
> let buffer = edge::event::Buffer::new(1)?;
>
> This allocates the memory for buffer only once, after that we continue
> reading from the same buffer.
>
> The BufferInternal structure is enclosed within an Arc<> instance, which is
> "Atomically Reference Counted", very much like kref_get/put in kernel.
>
> Unless the last reference is dropped, it stays.
>
> Hope I was able to clarify this here.



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux