On Tue Feb 3, 2026 at 7:26 PM GMT, Daniel Almeida wrote: > >> >> I think it's fine to have all of these: >> * `Clone` impl >> * `enable` which consumes `Clk<Prepared>` by value and spit out >> `Clk<Enabled>` >> * `with_enabled` that gives `&Clk<Enabled>` >> >> This way, if you only want to enable in short time, you can do >> `with_enabled`. >> If the closure callback wants to keep clock enabled for longer, it can just >> do >> `.clone()` inside the closure and obtain an owned `Clk<Enabled>`. >> >> If the user just have a reference and want to enable the callback they can do >> `prepared_clk.clone().enable()` which gives an owned `Clk<Enabled>`. >> Thoughts? >> >> Best, >> Gary > > > I’m ok with what you proposed above. The only problem is that implementing > clone() is done through an Arc<*mut bindings::clk> in Boris’ current > design, so this requires an extra allocation.
Hmm, that's a very good point. `struct clk` is already a reference into clk_core, so having to put another level of indirection over is not ideal. However, if we're going to keep C code unchanged and do a zero-cost abstraction on the Rust side, then we won't be able to have have multiple prepare/enable to the same `struct clk` with the current design. It feels like we can to do a trade-off and choose from: * Not be able to have multiple prepare/enable calls on the same `clk` (this can limit users that need dynamically enable/disable clocks, with the very limited exception that closure-callback is fine). * Do an extra allocation * Put lifetime on types that represent a prepared/enabled `Clk` * Change C to make `struct clk` refcounted. Best, Gary > > — Daniel
