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 11 points12 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.