Announcement

Collapse
No announcement yet.

The Latest Progress On Rust For The Linux Kernel

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #91
    Originally posted by IndioNuvemChuva View Post
    You are comparing apples to oranges here. The actual mechanism through RefCell does its "borrow checking" is not even close to that of the static borrow checker, so even calling it borrow checking is somewhat wrong to boot, and it is also much, much faster, on account of how it is implemented. On top of that, using it is offered as an explicit choice to users who wish to have a specific piece of data be "borrow checked" at runtime, for cases in which ownership rules can't be determined statically.

    In terms of speed, RefCell does add one or two dozen instructions around resource acquisition and release points. And, for most applications, those acquisition and release points will be so sparse it will never be a real problem. However, in those applications they somehow turn out to be frequent, either by the nature of the procedure being implemented or, most likely, by the developer's unfamiliarity with the language and environment, they could always be replaced or rewritten at wish.

    Asserting that "the borrow checker has a runtime component", then, is just plain wrong. The borrow checker runs entirely inside the compiler and that's it. Whatever access control mechanisms a developer decides to use after the fact are entirely their own choice, and those can, of course, range from no overhead at all, in the case they just decide for bypassing the compiler time checker with unsafe code, to very mildly expensive, in the case of wrapping a global structure around an RwLock or something, or hell, they could even write their own mechanism, if that's what they want.
    This is simple wrong point of view. As you stated RefCell is for cases that ownership rules cannot be determined statically. RefCell and other feature were added with oxide for that very problem what todo when you hit case that the static borrow checking processing cannot solve yet still have borrow checking..

    So you have static borrow checker and functions to have runtime borrow checker where that cannot work.

    Originally posted by oleid View Post
    Okay, I'm using rust for at least four years now and never come across any runtime borrow checking that was not opt-in, such as refcell. Do you have anything do back-up your claim?

    Also, wasn't oxide designed after-the-fact and is not used within the compiler?
    Please note I did not say that runtime borrow checker bits were not opt in. But the fact they are opt in they are something you have to be aware of when comparing benchmark results.

    Not being used in the compiler does not mean its not part of the borrow checker design of rust.

    The reality here is some oxide design with runtime borrow checking is to deal with the cases of borrow checking that the static borrow checking cannot do. This includes across dynamically loaded libraries.

    The Oxide design included the option that long term that the compiler could dynamically change cell for refcell and other functions like this cases where the borrow checker could not solve safely any more. Like building what would be a static library normally as a dynamic library.

    Interesting enough it appears rust compiler developers have stalled on implementing oxide completely so that people can keep on claiming that rust does not have a dynamic borrow checker or if people use the dynamic borrow checker parts they had to opt in. Not that they were force by their use case to use the dynamic borrow checker because if they don't the static borrow checker will not let their code build. This happens where developers is force with some cases of multi threaded with rust when if you attempt to use Cell the code will refuse build but Refcell will build due to the fact the static borrow checker cannot solve.

    The truth of the matter rust design has opt in runtime borrow checking. Sometimes it not that opt in as it you use the opt in runtime borrow checking or your code will not build because the static borrow solver cannot see there will never be a problem. Yes this forced hand can happen when nothing is technically wrong in the code. Fun of rust compiler bugs/limitations for you.

    Comment


    • #92
      Originally posted by oleid View Post

      Why is it not an option? And maybe you could give us an example from your code where you HAVE to use a RefCell?
      Because it would be way too fucked up, it was an API at its core managing a dynamically mutable tree, it means you have to borrow() a lot of items and rewriting to rely on try_borrow() just creates a nonsense clusterfuck of an API and source code.

      Comment


      • #93
        Originally posted by cl333r View Post

        The borrow checker is a concept whose job is to enforce the borrowing rules, which can be checked at compile or runtime. Period.
        Utterly and terminally ignorant and wrong. The borrow checker is a specific and well defined algorithm that is part of the compiler and covers some aspects of the broader Rust concept of borrowing. It doesn't even exist at runtime.

        It's basically like saying that calling a function in C somehow involves the prologue and epilogue generator at runtime.

        Comment


        • #94
          Originally posted by jacob View Post

          Yes we are not talking about threads, which is why this is a concurrency problem as opposed to a parallelism problem.



          RefCell *is* about concurrent mutation, which you obviously mistake for parallel mutation. It is to concurrency what a mutex is to parallelism. The point being that it is an acknowledgement that a problem exists. Other languages of course have the exact same problem but they simply fail to even recognise it. I really don't see how exactly is that supposed to be better.



          Then you will be pleased to know that corner or unusual cases aside, you don't have to use it. In all cases where an object can be copied atomically (from a concurrency point of view), you don't have to use RefCell. You would use Cell where no borrowing is needed. This covers things like scalars, small cheap structs and vectors etc, which are basically the same cases where you can be sure that no problem can arise in C.
          Dude you're totally screwing meanings. Concurrent is about threads, sequential is about single threaded stuff running in sequence.

          Concurrency is about independent computations that can be executed in an arbitrary order with the same outcome. The opposite of concurrent is sequential, meaning that sequential computations depend on being executed step-by-step to produce correct results.

          Comment


          • #95
            Originally posted by cl333r View Post
            Oh my..
            maybe you could rephrase.

            A "proper" example of what? Aliased mutability that isn't a bug? I already did give a normal example (don't recall if it was for you) I use relatively often: removing items from a vector looping from end to start, item removal happens based on certain criteria of the item.
            Well, as I said before: where is the aliased mutation? you don't have mutable access to the same memory location more than once.

            Also, what you are asking for works fine in rust. no runtime borrow checking needed.

            Comment


            • #96
              Originally posted by cl333r View Post

              Dude you're totally screwing meanings. Concurrent is about threads, sequential is about single threaded stuff running in sequence.


              https://slikts.github.io/concurrency...-vs-sequential
              You are the one who is totally confused here:
              • concurrent = multiple independent sequences of operations can be executed in interleaving ordering. That's what we are discussing here.
              • parallel = multiple sequences of operations can be executed simultaneously (multithreading)
              If there is no concurrency OR parallelism (i.e. the ordering of your operations is strictly deterministic), you don't need RefCell and there is no reason to use it, standard mutable references will suffice. It gets even better in that the borrow checker (the real borrow checker, not the imaginary and incorrect vision of it that you have) will enforce that you pay attention to your data flow and make it explicit who can access the data and when. But if you actually still want to use RefCell in that case for no reason at all, it will never panic on borrow() or fail on try_borrow().

              On the other hand, if you have parallelism, you can't even use RefCell since the type checker won't allow you to share it across multiple threads - you need Mutex instead.
              Last edited by jacob; 12 September 2021, 07:23 PM.

              Comment


              • #97
                Originally posted by mdedetrich View Post

                To be honest, you have zero clue what you are talking about and its evident in your responses.

                RefCel has nothing to do with the borrow checker, its an abstraction that allows reference counting (similar to how Python works but a lot more efficient) hence the Ref in its name (as opposed to just Cell which doesn't have this reference counting mechanism). Using this deranged logic, you can also claim that a GC is a borrow checker (hint: its not)

                The borrow checker, i.e. the process that checks the flow of memory using linear type system is a purely compile time construct and when people say "borrow checker" thats what they mean. RefCel can be used in cases where the borrow checker can't prove something, but that in of itself doesn't mean its a borrow checker.
                Actually you are incorrect, RefCell doesn't do reference counting, that's Rc and Arc. The "Ref" in RefCell simply means that you can borrow() a reference to the object (as opposed to a plain Cell which will give you a copy of the object). It only has a borrowed/not borrowed flag, not a reference counter.

                Comment


                • #98
                  Originally posted by jacob View Post
                  If there is no concurrency OR parallelism (i.e. the ordering of your operations is strictly deterministic), you don't need RefCell and there is no reason to use it
                  This is not quite right. If your operations are strictly deterministic and the compiler also believes the operations is strictly deterministic then there is no reason to use RefCell. is the correct.

                  Yes you can be using RefCell to get around rust compiler bug where it incorrect believes something is not strictly deterministic when it is in fact strictly deterministic. This is what leads to some badly written and performing code with rust where people worked around bug in X version of rust then have forgot to remove that work around latter when the compiler is fixed. Of course this also lead to some code where people have used RefCell on not strictly deterministic code resulting in rust program pulling the instant splat.

                  The runtime borrow checker options of rust do have some issues and so does the static borrow checker of rust.

                  Comment


                  • #99
                    Originally posted by oiaohm View Post

                    This is not quite right. If your operations are strictly deterministic and the compiler also believes the operations is strictly deterministic then there is no reason to use RefCell. is the correct.

                    Yes you can be using RefCell to get around rust compiler bug where it incorrect believes something is not strictly deterministic when it is in fact strictly deterministic. This is what leads to some badly written and performing code with rust where people worked around bug in X version of rust then have forgot to remove that work around latter when the compiler is fixed. Of course this also lead to some code where people have used RefCell on not strictly deterministic code resulting in rust program pulling the instant splat.

                    The runtime borrow checker options of rust do have some issues and so does the static borrow checker of rust.
                    I've seen code like that too. If the operations sequencing is deterministic, then such patterns usually show up when someone is trying to hold mut& references to the same object at several places at the same time, which is a C-ism and bad design anyway. The correct approach is to pass a mut& to your object around as parameter so that it has a clear lifetime.

                    In practice the only time I personally had to use RefCell was when writing gtk-rs code, because you need to mutate the state of a widget or its associated data from an event callback, which brings us back to concurrency - obviously a callback is by nature not deterministic.

                    Comment


                    • Originally posted by jacob View Post

                      Utterly and terminally ignorant and wrong. The borrow checker is a specific and well defined algorithm that is part of the compiler and covers some aspects of the broader Rust concept of borrowing. It doesn't even exist at runtime.

                      It's basically like saying that calling a function in C somehow involves the prologue and epilogue generator at runtime.
                      Utterly and terminally ignorant and wrong. The borrow checker is Rust's mechanism of dealing with borrowing rules.

                      Comment

                      Working...
                      X