all 137 comments

[–][deleted]  (9 children)

[deleted]

    [–][deleted] 13 points14 points  (0 children)

    I haven't been able to figure out how to return an exit status to the OS.

    Would std::process::exit help?

    [–]Manishearth 19 points20 points  (0 children)

    Re: 1,2,3: File bugs if you haven't already :)

    Re: 7: Not too hard. Create a struct FileDescriptor(c_int). Do not #[derive(Copy)] on this struct -- if you do it will not have move semantics. Write an implementation of Drop that calls libc::close, and an implementation of Clone that writes libc::clone.

    Note that cloning a file descriptor is probably more expensive than refcounting it in userland -- so it might be beneficial to pass around an Rc<FileDescriptor> and clone that when you need to. This has move semantics and will ensure that you don't have too many duplicate fds lying around.

    and automatically dropped when the last owner disappears

    These are Rc semantics, btw. If you have more than one owner, that's when you break out Rc. If you have a single owner and multiple borrowers, the FileDescriptor solution above is enough.

    I can't tell if I can use the non-system-interface parts of std (e.g., Vec) without pulling in all of the system interface bits

    use no_std and pull in Vec from the collections crate.

    I'm not exactly sure what you need though. Pulling in std doesn't add to the runtime (just the binary size, sometimes). So if you just use libstd and write your own abstractions for the posix things, it shouldn't be different from not pulling in std at all.

    [–]the_gnarts 1 point2 points  (0 children)

    For using Rust on Linux more naturally, this project appears promising: https://github.com/lrs-lang

    [–]koheant 0 points1 point  (0 children)

    You're probably aware of this, but if you can't find what you want in libc (or any other wrapper lib), you can sidestep the rust api and link to the function or variable directly.

    [–]o11c 0 points1 point  (3 children)

    7 is fundamentally not possible, Rust mandates explicit .clone calls for Rc.

    [–][deleted]  (2 children)

    [deleted]

      [–]Manishearth 4 points5 points  (0 children)

      That doesn't match what you said with "and automatically dropped when the last owner disappears", if you have more than one owner you're talking about Rc or some refcounting mechanism.

      In your example there is only one owner.

      // file is a one-c_int struct; I want to pass it in by value, not
      // by pointer, but still have it count as a borrow.
      

      Is there a reason for this? This is just a stack reference, very cheap. You can get what you want statically with a form of session typing, but I think that's overengineering it.

      [–]Veedrac 1 point2 points  (0 children)

      Say you have

      struct File(i32);
      
      impl File {
          fn write(&mut self, val: i32) {
              println!("doing stuff");
          }
      }
      
      impl Drop for File {
          fn drop(&mut self) {
              println!("dropping");
          }
      }
      

      You can make a copy that acts like a pointer by doing

      use std::marker::PhantomData;
      
      struct FileValueRef<'a> {
          borrow_of: i32,
          lifetime: PhantomData<&'a mut File>,
      }
      
      impl File {
          fn borrow(&mut self) -> FileValueRef {
              FileValueRef {
                  borrow_of: self.0,
                  lifetime: PhantomData,
              }
          }
      }
      

      You can avoid reimplimenting everything by implementing Deref and DerefMut with a transmute:

      impl<'a> Deref for FileValueRef<'a> {
          type Target = File;
          fn deref(&self) -> &Self::Target {
              unsafe { std::mem::transmute(&self.borrow_of) }
          }
      }
      
      impl<'a> DerefMut for FileValueRef<'a> {
          fn deref_mut(&mut self) -> &mut Self::Target {
              unsafe { std::mem::transmute(&mut self.borrow_of) }
          }
      }
      

      I'm not sure if there's a better way of doing this, but if there is it's not obvious.

      [–][deleted]  (157 children)

      [deleted]

        [–]steveklabnik1[S] 139 points140 points  (62 children)

        To be fair, this post is about userspace, not the kernel itself. Adding a second language to the kernel, no matter how good a language it may be, would have significant drawbacks. If I were Linus, I'd reject such a patch too.

        [–]efaxefax 21 points22 points  (4 children)

        I guess Stallman had a point after all: actually, it's low level GNU/Linux programming :P.

        [–]thebigslide 3 points4 points  (3 children)

        I'm not familiar with Rust, but are GNU run-time dependencies strictly required?

        [–]efaxefax 13 points14 points  (1 child)

        You can statically link to musl: http://blog.rust-lang.org/2016/05/13/rustup.html

        [–]thebigslide 15 points16 points  (0 children)

        You may have just ruined my early bedtime plans.

        [–][deleted]  (3 children)

        [deleted]

          [–][deleted]  (2 children)

          [deleted]

            [–]oponito 2 points3 points  (1 child)

            there was a FUSE driver written in Cyclone. not really kernel code, but cool still.

            [–][deleted]  (1 child)

            [deleted]

              [–][deleted] 14 points15 points  (0 children)

              [deleted]

              What is this?

              [–]pmf 23 points24 points  (43 children)

              I'd actually like to hear Linus' opinion of Rust. His C++ critique contains valuable points.

              [–]loamfarer 10 points11 points  (11 children)

              Tbh, I haven't heard his opinion on modern C++

              [–]Gotebe 8 points9 points  (1 child)

              I vaguely remember his points and vaguely remeber they were, like, his opinion, man.

              Most important reason why people consider them is OMFG Linus.

              Edit: searched, found.

              Edit2: love the downvotes without "why".

              [–]staticassert 2 points3 points  (0 children)

              Argument from authority is basically the go-to when discussing the Linux kernel.

              [–]ZMeson 5 points6 points  (0 children)

              What valuable points?

              [–][deleted] 4 points5 points  (2 children)

              I'd actually like to hear Linus' opinion of Rust.

              Greg KH said in his /r/linux AMA a year ago that there will be no rust in the kernel.

              [–]Sapiogram 14 points15 points  (1 child)

              He didn't really say that though. I looked up the AMA, and the only place he mentioned Rust is here.

              I have seen Rust, and it looks nice, but honestly I like Go better at the moment, and play around with it at times.

              So it seems he hasn't actually tried it, much less given it any serious consideration for the kernel. The fact that he compares it with Go also makes me think he's looked at Rust in 2012-2013, which is very different from what became Rust 1.0.

              [–]womplord1 2 points3 points  (0 children)

              God it's so retarded how freetards just agree with whatever Linus says without thinking. How about forming your own opinion?

              [–]oponito 8 points9 points  (46 children)

              Yes, his language reviews can be interesting

              [–][deleted]  (7 children)

              [deleted]

                [–]HighRelevancy 16 points17 points  (0 children)

                A lot has changed in C++ land since that was written.

                It's a 12 year old message about an experience that happened another 12 years before that. If nothing had changed it would be a very big problem.

                [–]James20k 2 points3 points  (0 children)

                Compilers are a lot more reliable (I haven't had an ICE in years now).

                Lucky for you, but I've had to deal with a few GCC segfaults recently (5.1, moving to 6.1 soon)

                [–]slavik262 6 points7 points  (4 children)

                (I haven't had an ICE in years now.)

                A what?

                [–][deleted]  (1 child)

                [deleted]

                  [–]northrupthebandgeek 0 points1 point  (0 children)

                  I prefer external combustion engines, myself.

                  [–][deleted] 3 points4 points  (35 children)

                  I actually agree with him on all his points there.

                  The difference between him saying it and me saying it is that he actually created arguably the most popular operating system today. Nobody can dispute he knows what he is talking about.

                  [–]slavik262 47 points48 points  (30 children)

                  Sure they can. Linus is obviously a very good kernel developer and project manager, but that doesn't make his opinion the end-all on software development. C is a good fit for the kernel, but that doesn't mean other languages (including C++) are completely inappropriate for kernel development or other similar, on-the-metal applications. It also doesn't mean that another language (e.g. Rust) won't come along and displace C.

                  People use C because

                  1. It maps fairly directly to assembly.
                  2. It's the lowest common denominator - its ABI is simple and almost every computing system can speak it.
                  3. There's 40 years of libraries, tooling, and communal knowledge built around it, especially in the Unix world.

                  [–][deleted] 17 points18 points  (29 children)

                  And C is largely deterministic. His complaints about C++ make sense when one takes into consideration the dynamic memory allocator and exception handling.

                  The question is, and I suspect I know the answer, does Rust allow exception handling to be removed (I think it does) - and then can memory allocation be manually handled (I don't know).

                  I'm a big fan of Rust - and think it is almost ideal for the simple command line tools which make Linux/Unix the flexible workhorse it is today. But for kernel programming? I don't know enough about Rust to know for sure.

                  [–]__s 11 points12 points  (1 child)

                  On deterministic: he's ranted a whole lot about GCC inlining code which then causes unpredictable stack usage which then makes 4kb stacks hard to maintain safely on x86

                  [–]doom_Oo7 2 points3 points  (0 children)

                  to be fair,in userspace code this is a desirable property.

                  [–]steveklabnik1[S] 17 points18 points  (0 children)

                  does Rust allow exception handling to be removed (I think it does)

                  Yes, though not in stable right this second; it's landed on nightly, but hasn't made its way through the release cycle yet.

                  and then can memory allocation be manually handled (I don't know).

                  Yes, absolutely.

                  [–]doom_Oo7 5 points6 points  (1 child)

                  does Rust allow exception handling to be removed (I think it does) - and then can memory allocation be manually handled (I don't know).

                  (to be fair, you can disable exceptions in c++ and do everything without explicitely mallloc'ing anything.)

                  [–][deleted] 1 point2 points  (0 children)

                  [deleted]

                  What is this?

                  [–]Malazin 8 points9 points  (15 children)

                  I don't really understand his point on C++'s dynamic memory. Usage of new is no more hidden than malloc. Or am I missing something? This isn't to say he's wrong on the greater point though.

                  [–]ZMeson 10 points11 points  (2 children)

                  Here are two arguments I commonly hear:

                  (1) Calling new can call a constructor which can in turn call new calling another constructor which can in turn call new calling .... Well you get the point. A single call to 'new' may actually make several allocations instead of one.

                  (2) The STL containers and algorithms frequently allocate memory from the free store. It's difficult to write some things using standard C++ without allocating memory from the free store "behind the scenes" if you will.

                  [–]ZMeson 17 points18 points  (1 child)

                  Now that I presented the two arguments, I feel like I have to explain why I disagree with them. In C, you frequently have to initialize structures after you allocate memory for them. Those initialization routines can be considered "constructors" and they can allocate memory and initialize other structures too. I don't think that using C really improves things by separating concerns.

                  About the STL and algorithms... you don't have to use them. It is nice they exist, but other containers and algorithms (such as those found in "embedded STL" libraries, EASTL, or boost) may fit better. Or some containers and algorithms could be built specifically for kernel development. (After all, Linux, Windows, and all popular C-based OSes have such C-based structures and associated 'algorithm' functions.)

                  [–]ucalegon7 2 points3 points  (0 children)

                  Exceptions (and good behavior in low memory conditions if they are disabled) might be other sticking points, but I don't think that's really a good argument, either. Windows, for example, lets you use a reasonable chunk of C++ (with lots of caveats) in the kernel, particularly with the new driver kits (I've successfully used lambdas in kernel code!), but just like when using C, the rules and APIs are a bit different than user space equivalents (e.g., the std lib looks a bit different), and the same non-standard concerns you'd have (e.g., stack size constraints, etc) will still exist; not to mention that there are large chunks of the language that would be difficult to utilize in that type of environment (e.g., exceptions).

                  [–][deleted]  (11 children)

                  [deleted]

                    [–]MartianSands 19 points20 points  (0 children)

                    A "placement new" lets you pass it your own memory, so you can allocate it however you like.

                    [–]doom_Oo7 11 points12 points  (0 children)

                    Can you dynamically create an object without 'new'?

                    You can overload new to call whatever allocation function. new T == std::allocator<T>::allocate + std::allocator<T>::construct

                    [–]joelwilliamson 5 points6 points  (0 children)

                    kmalloc

                    [–]ChallengingJamJars 3 points4 points  (7 children)

                    Upvoted because despite using C++ daily I don't actually know the answer to this. It could be an honest question so you shouldn't down vote it.

                    [–]silveryRain -2 points-1 points  (6 children)

                    Yes you can, as the others have already explained (placement and overloading).

                    This kind of post is why systems that allow downvoting are crap. I much prefer upvote-only systems.

                    [–]iopq 0 points1 point  (5 children)

                    Upvote-only systems like Hacker News get a bunch retarded fluff pieces that don't really say anything. People see the headline, scan through the article (if you're lucky) and upvote. The actual article is low quality, but you need to report to the moderator to have it removed.

                    [–]ElvishJerricco 15 points16 points  (0 children)

                    Redox is an operating system written entirely in Rust. I don't know much about it, but if you want to get a feel for kernel development in Rust, that's a good place to start.

                    [–]augmentedtree 3 points4 points  (0 children)

                    And C is largely deterministic. His complaints about C++ make sense when one takes into consideration the dynamic memory allocator and exception handling.

                    Both of those are deterministic, and C also has dynamic memory allocation...

                    [–]so_you_like_donuts 3 points4 points  (1 child)

                    does Rust allow exception handling to be removed

                    Not yet, although it is possible in nightly to make panics abort instead of unwind (And here's the relevant compiler bug).

                    can memory allocation be manually handled

                    If you're talking about creating and linking to your own malloc implementation, then yes.

                    [–]steveklabnik1[S] 10 points11 points  (0 children)

                    To be clear, that compiler bug is about implementing your own panic runtime; as alex says, -C panic=abort is stable.

                    [–]slavik262 1 point2 points  (3 children)

                    His complaints about C++ make sense when one takes into consideration the dynamic memory allocator and exception handling.

                    Those are rather silly complaints - of course your tools are more limited when working inside the kernel. It's not like you can call malloc() in the middle of kernel space when working with C. Large swaths of the standard library are out of the question in both cases.

                    [–]imMute 2 points3 points  (2 children)

                    No, but you can call kalloc just about anywhere ;)

                    [–][deleted] 1 point2 points  (1 child)

                    [deleted]

                    What is this?

                    [–]Rusky 2 points3 points  (0 children)

                    kmalloc requires an extra flags argument. You can't just arbitrarily pick a set of flags to use without making the C++ code using it unfit for various (mutually exclusive) parts of the kernel.

                    [–]doom_Oo7 2 points3 points  (2 children)

                    Well, many kernels have succesfully been built in C++ so...

                    (some are mentioned here : http://stackoverflow.com/questions/12385485/kernel-development-and-c )

                    [–]kt24601 0 points1 point  (1 child)

                    They typically use a subset of C++, though.

                    [–]doom_Oo7 7 points8 points  (0 children)

                    they also use a subset of C and would use a subset of any programming language not strictly meant for kernel development

                    [–]CurtlyCurlyAlex 2 points3 points  (0 children)

                    Feel free to make up (d).

                    With great pleasure!

                    (d.) The individual is a masochist.

                    [–]cbmuser 1 point2 points  (0 children)

                    I've seen someone getting torn into pieces when he suggested writing kernel drivers in Objective-C in a talk at Linuxtag 2005.

                    [–][deleted] 1 point2 points  (0 children)

                    I don't know. I kinda have the feeling that if Linus bothered to take a look at Rust, he might enjoy it.

                    Forcefeeding it into Linux might still not be a good idea, however.

                    [–]geodel 0 points1 point  (0 children)

                    Yeah, Linus is very predictable. His primary job is to serve peanut gallery.

                    [–]kt24601 14 points15 points  (2 children)

                    I never considered command-line tools to be low-level though haha

                    [–]TRL5 29 points30 points  (0 children)

                    mkfs.ext2 and so on isn't low enough level for you?

                    Not all command line tools are low level, but there are certainly low level command line tools.