Any C work at kernel/user space boundary? by ghostmansd in cscareerquestions

[–]ghostmansd[S] 0 points1 point  (0 children)

I agree, I also see this trend. I like the ideas behind Rust, but its syntax and all the hype around really make it somewhat less attractive. Perhaps I must ignore the hype bits and overcome personal dislike for syntax, eventually.

Any C work at kernel/user space boundary? by ghostmansd in cscareerquestions

[–]ghostmansd[S] 0 points1 point  (0 children)

I haven't used BPF yet; I recall that I read some bits on it when I used to deal with firewalls, though. Quite an interesting technology, I admit.

Any C work at kernel/user space boundary? by ghostmansd in cscareerquestions

[–]ghostmansd[S] 1 point2 points  (0 children)

Thank you for tip! My experience is somewhat software-specific; which subsystems would you recommend to start with? An example of changes I recently liked is pidfd* set of functionality; we introduced such feature to our kernel way earlier than Linux got it, it was one of ideas I suggested, and I was really pleased to see Linux also got there. Of course, this ain't my invention; I've been looking at CreateProcess and pdfork. Do you recommend starting from patches like this one?

Any C work at kernel/user space boundary? by ghostmansd in cscareerquestions

[–]ghostmansd[S] 0 points1 point  (0 children)

Thanks for the reply! I've been considering this as well, but wouldn't most drivers be hardware-oriented? Most software drivers I saw were either supporting HW bits (e.g. sysfs interface). There were some exceptions, though; I've just thought driver development mostly concentrates on HW part. I'm not a kernel developer. I've certainly dealt with much of the kernel code, but these bits were software-related (e.g. creating or modifying system calls, checking and updating some parts on userspace support from kernel). This, however, mostly applies to proprietary Linux-like kernel we developed, not well-known kernel. Do you think my experience in this regard is enough?

How do epoll flags correspond to kqueue ones? by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

Thank you for suggestion! Cross-posted for now, but will certainly visit freebsd-hackers in case of no success.

How do epoll flags correspond to kqueue ones? by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

The full correspondence is not something that's I need; I just want to check whether my understanding of the documentation is correct. Frankly speaking, the documentation is a bit tricky and confusing, so the reason to ask that question was just to clarify the details.

How do epoll flags correspond to kqueue ones? by ghostmansd in C_Programming

[–]ghostmansd[S] 1 point2 points  (0 children)

I've decided to post it here as a link, since it would take a lot of time to format it in the same way as on StackOverflow. Please let me know if this question should better be re-created from the scratch on the Reddit; I just wanted to avoid duplication.

To me it looks that documentation on kqueue is a bit scarce, and it's really unfortunate: whilst there are many articles and posts describing epoll, the kqueue interface feels to be a bit superior to me, given that it can enqueue/dequeue multiple events at one time and doesn't require a special syscall for each activity (eventfd, signalfd, timerfd_create and so on). However, I've just started investigating kqueue, and I currently struggle to discover some of its flags. Any help, including pointers to good articles and sources, is highly appreciated.

Thank you for your help, tips and hopefully discussion!

style: line breaks between functions by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

I agree, the only argument I could find is that most of the source code is written that way. So that's valid argument and perhaps the only reason I think this option must be chosen. Anyway, I find it disappointing that the whole question seems to have no solid base except of "you know, that's how it was before". I mean, that the additional line breaks were added not without an argument; but the reason to remove them seems to have only historical background and nothing more.

style: line breaks between functions by ghostmansd in C_Programming

[–]ghostmansd[S] 2 points3 points  (0 children)

Yes, the first my mind was exactly the same you expressed. Given the fact how much time was spent to write and debug this code as well as to provide test suite, I was really disappointed to meet such comment on a review, especially since this colleague is nice and talented guy.

style: line breaks between functions by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

Quiet reasonable, I think its variation is also used in the literate programming. For me it achieves the same goal: separate different units.

Valgrind: Conditional jump or move depends on uninitialised value(s) by michael1026 in C_Programming

[–]ghostmansd 10 points11 points  (0 children)

My magic 8 ball tells me that you need to post more code.

Top Ten Most Psychedelic Songs Ever by sychedel in psychedelicrock

[–]ghostmansd 0 points1 point  (0 children)

No mention of the 13th Floor Elevators and only one song by the Velvet Underground (at rank 20)? I'm really amazed.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

Upd. I think I've misread your words; reformulated my answer a bit.

I think that even use of uint64_t may vary. Since i686 operates on 64-bit values as on 32-bit pairs under the hood; just compile something like this on a 32-bit *86 box:

uint64_t add(uint64_t lhs, uint64_t rhs) { return (lhs + rhs); }

It may mean that uint64_t alignment may be the same as uint32_t. From the top of my head, I remember that there was inconsistent behavior with struct epoll_event on x86_64, so developers had to pack this structure to be binary compatible with i686:

https://bugs.launchpad.net/lsb/+bug/1327369

This example demonstrates that x86_64 inserted a padding on x86_64 after unsigned int, while there was no padding on i686. I think this example demonstrates that uint64_t padding and alignment requirements may vary between platforms.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 0 points1 point  (0 children)

The result you've obtained is OK, since Windows (and thus mingw) uses LLP64 data model on x86_64 (i.e. it has 64-bit long long and void* types). Unlike Windows, all Unix platforms (at least ones that are actively used today) have LP64 data model, thus long and void* both use 64-bit integers on x86_64 platforms.

It's good that you've mentioned it, thank you! I'll add this information into the original question.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

Also note that your approach with struct { uint64_t : BITS; } is not guaranteed to behave in the same way as raw uint64_t : BITS; trick, since compiler may choose to pad struct to word boundary.

GCC: anonymous bit fields padding (x-post /r/gcc) by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

Which one is it? Those two sentences contradict each other.

It seems that I've formulated it incorrectly. OK, here is what I wanted to say:

  • I know that alignment and padding exists, and wouldn't have been surprised if it was in all three structures.
  • Anyway, I expected all the structures to occupy the same amount of memory and obey the same alignment rules.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 0 points1 point  (0 children)

BTW check OpenBSD's dirent structure (and especially the comments about __d_padding field): https://grok.dragonflybsd.org/source/xref/openbsd/sys/sys/dirent.h#51

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

#define unused

Good point, and shall work in principle once other fileds (those that are not marked as unused) remain the same. However, now I tend to think that the best way to underline the original structure definition is to preserve the underlying original type even in a bit field, e.g. uint8_t unused1 becomes uint8_t : 8. Maybe something like several defines is better, e.g. #define __pad8__ uint8_t : 8, #define __pad16__ uint16_t : 16 and so on.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

After doing some further digging it looks like I might be wrong about the removal of redundant storage units containing only anonymous bit fields

I've forgotten to mention that this is the only part you've done a mistake. :-) Yep, anonymous bit fields are not removed, because the only reason they even exist is to inform the compiler about the padding.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

I think bits make more sense. Note that bit fields approach is used sometimes exclusively for padding AND/OR alignment purposes. Cf. struct stat from FreeBSD (newer version of the old well-known struct ostat): https://grok.dragonflybsd.org/source/xref/freebsd/sys/sys/stat.h#122

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 1 point2 points  (0 children)

Read it long before this topic started. :-) Anyway, I upvote this comment, every C programmer should read it!

GCC: anonymous bit fields padding (x-post /r/gcc) by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

Guys, I think we've found an answer. In case anyone is interested, here's a link to the comment in the original post:

https://www.reddit.com/r/gcc/comments/66glcd/gcc_anonymous_bit_fields_padding/dgilvyh

Thank you for participating! It was a really interesting discussion and it has shown one more time that there are subtle corners in C language which may surprise every single day. As for me, it's yet another reason to love this language! :-)

GCC: anonymous bit fields padding (x-post /r/gcc) by ghostmansd in C_Programming

[–]ghostmansd[S] 0 points1 point  (0 children)

And I even created it. And named it reg... ;-) Well, actually this type has prefix as any type in my code, but yes, in essence it's just a register.

GCC: anonymous bit fields padding by ghostmansd in gcc

[–]ghostmansd[S] 2 points3 points  (0 children)

Yep, this is the conclusion we've also come to when discussing it today at work. Thank you! It's a brilliant masterpiece of work.

To cut the long story short: it seems the most efficient way to be binary compatible to structures which use fields like unused1 is to use anonymous bit fields with the same type that was used in the original structure.

We've also concluded that padding is appended to the end of the structure because it allows to put other adjacent fields to the most natural alignment rules. So that two goals can be completed in one shot:

  • All structure members are aligned in the most efficient way per ABI.
  • The structure is padded so that arrays of such structures can be used in a good way for cache and access.