|
I was looking to see if there was a bug with device_create/class_create not being pointed out when building a module with a proprietary license. So I did a checkout of the kernel and built it. I don't have anything like kbuild included in there. How do I get that set up too? I want to use the one from the checkout since I expect it's tied in to whatever logic was skipping that problem.
|
# ? Jun 10, 2021 22:41 |
|
|
# ? Jun 9, 2024 04:12 |
|
Welp, it's been a long time I posted here and I really am stuck with something that I shouldn't be stuck with. I want to use this library to do some IIR filtering: https://github.com/berndporr/iir1 To create a filter of n-th order using this library, you need to use the generic type: C++ code:
C++ code:
However, I don't want to duplicate code and I was thinking of writing some generic function that accepts an int as a template parameter, but I can't figure out how to do it (or if it's even possible). Could anyone point me in the right direction? C++ code:
|
# ? Jun 22, 2021 10:32 |
|
go play outside Skyler posted:
|
# ? Jun 22, 2021 12:36 |
|
Why do I feel like I should have known this? Thank you, works wonders!
|
# ? Jun 22, 2021 13:48 |
|
I've got a template type with a base class. I want to mostly deal with base class pointers without needing to know the template type. I want to make an easy AsType() to make getting the derived type (if it happens to be that type) clean. But this would require forward declaring the derived type, which is a template type. It fails to compile with error C2988: unrecognizable template declaration/definition I'm pretty sure this is possible but I think I'm just getting the syntax wrong. How do I do this? C++ code:
C++ code:
|
# ? Jul 9, 2021 23:17 |
|
Don't you just need to forward declare the derived template before the Base, so it can be used in the method return type?
|
# ? Jul 9, 2021 23:24 |
|
Yeah, this seems to compile once you take out the unnecessary typename qualifiers: https://gcc.godbolt.org/z/9Mnva3KEx
|
# ? Jul 10, 2021 06:59 |
|
Ok, thank you both. I didn't realize you could just forward declare a template type like that.
|
# ? Jul 10, 2021 17:15 |
|
Edit: I actually think this is impossible as it is, because I guess you can't partially specialize a function. So I'll need to rearrange things a bit. I'm now stuck on the next part. I want to implement a GetValueAsString() / SetValueFromString() for an EditableTimelineNodeBase class. These need to be specialized on the various types that I want to support (float, glm::vec4, etc). I know I've done this a dozen times but it has been years, and I can't find any examples right now, or I don't know what the real name of this is. Maybe if I simply knew the name of what I'm trying to do, or if I could find one example to look at, then I can easily figure this out. I'm searching for "template specialization" but I'm not finding anything that looks like a solution for me. code:
This is simplified of course so maybe it isn't even correct code: https://gcc.godbolt.org/z/4rWzv4bM4 baby puzzle fucked around with this message at 14:32 on Jul 13, 2021 |
# ? Jul 13, 2021 13:51 |
|
Sounds like you’re looking for partial template specialization, but as I recall that’s limited to classes and can’t be used for functions. e: Missed your edit, you seem to have found that, but yeah, you might need to look for another approach. chglcu fucked around with this message at 16:10 on Jul 13, 2021 |
# ? Jul 13, 2021 16:08 |
|
You have to make a struct which is partially specialized which has a single static function that contains your actual implementation and then call that from your public function. It's a ton of boilerplate unfortunately. Alternatively, if you're using c++17 you can just do if constexpr (std::is_same_v<TimeType, float>) { ... } rather than template specialization. This is a little more limited in what can differ between the types but it's going to be way less code in this case.
|
# ? Jul 13, 2021 16:31 |
|
Speaking of, is there actually a good reason partial specialization isn’t allowed for functions? Does it just make things easier for the compiler?
|
# ? Jul 13, 2021 16:40 |
|
The reason is just "because the language says you can't". The interaction between function overloading and function specialization is really weird and partial function specialization would make it even weirder, but AFAIK the restriction never got dropped because people hated the idea rather than because it was impossible.
|
# ? Jul 13, 2021 16:47 |
|
Ok, I think I'm just getting myself confused. I don't really need both template types involved with the functions I want to write. Maybe the actual work I want to do can go into a function template outside of this class, which only has one template parameter. Then the member function can be a "primary template" function that won't need any specialization. Edit: yeah something like this. I think I can figure it out now. Although I don't really want to learn sfinae right now, I'll take the verbosity. Plorkyeran posted:You have to make a struct which is partially specialized which has a single static function that contains your actual implementation and then call that from your public function. It's a ton of boilerplate unfortunately. baby puzzle fucked around with this message at 16:54 on Jul 13, 2021 |
# ? Jul 13, 2021 16:52 |
|
if constexpr is not SFINAE and if you can swing it, it is pretty much always a less verbose and better performing option
|
# ? Jul 14, 2021 20:51 |
|
I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros:code:
If it matters, my compiler doesn't seem to get it either: code:
|
# ? Jul 20, 2021 21:45 |
Yes that looks like some C99 syntax that isn't adopted by C++. The intention seems to be to initialize every element of the array with the special in it value, statically. The expression in the square brackets would be the range of indexes to initialize with the right hand side.
|
|
# ? Jul 20, 2021 21:57 |
|
Rocko Bonaparte posted:I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros: Yes, it's C-only (and the "...." part is a GNU extension I believe). It's initialising every element in the array to HLIST_HEAD_INIT )
|
# ? Jul 20, 2021 21:57 |
|
Rocko Bonaparte posted:I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
|
# ? Jul 20, 2021 22:39 |
|
I feel a lot better that I asked because that was impossible to google when I didn't even have the context. It looks like I'll have to write that stuff out into a loop instead, which is fine.
|
# ? Jul 20, 2021 23:03 |
|
One programming interview question that stumped me was to search a binary search tree for a node, tree in question having ~300,000+ nodes. A recursive search seg faulted on me as I figured it would so I tried a iterative search after that; however this appeared to have been too slow and error'd on me that it run out of time/timed out. Iterative search being basically this: code:
|
# ? Jul 20, 2021 23:36 |
|
Designated initializers are a C99 feature. ... is a range designator, which is a GCC extension that initializes a fixed range of array elements. In this case, the range coincides with the entire array, which is useful because in standard C there is no way to initialize an entire array with a non-zero value without writing that value out as a separate initializer for each of the elements, which is impossible if (as here) you've abstracted over the array size. EDIT: and yes, gcc doesn't support designated initializers in C++ mode (except for the reduced set now added to the language), although I think clang might. rjmccall fucked around with this message at 00:01 on Jul 21, 2021 |
# ? Jul 20, 2021 23:58 |
|
Raenir Salazar posted:I read afterwards that maybe the tree might have been unbalanced might have reduced the search efficiency to O(N); is there some trick to this problem?
|
# ? Jul 21, 2021 00:14 |
|
Yeah I wonder if the question is one of those trick questions where the tree is hosed.
|
# ? Jul 21, 2021 00:38 |
|
Honestly, that looks optimal; all the dependencies are inherent. A good compiler should even have everything it needs to do the core comparisons with one compare instruction plus branches on flags. If that solution is timing out then either the timeout is unreasonable, the tree is very badly unbalanced, or the tree is corrupt (e.g. has a loop). It’s reasonable to expect you to be able to identify those possibilities (well, assuming this is an appropriate question at all), but none of them are your responsibility to solve in a standard search-tree find algorithm. If you also implemented insertion, that’s different.
|
# ? Jul 21, 2021 00:49 |
|
rjmccall posted:Honestly, that looks optimal; all the dependencies are inherent. A good compiler should even have everything it needs to do the core comparisons with one compare instruction plus branches on flags. If that solution is timing out then either the timeout is unreasonable, the tree is very badly unbalanced, or the tree is corrupt (e.g. has a loop). It’s reasonable to expect you to be able to identify those possibilities (well, assuming this is an appropriate question at all), but none of them are your responsibility to solve in a standard search-tree find algorithm. If you also implemented insertion, that’s different. Nope, no insection; just find. It's one of those "submit online" tests where you can test your code, so either its all green or it fails some test; does tortoise and hare work on trees? Maybe I should keep loops in mind if its an utterly hosed tree. I'll be annoyed if it was a trick question because I have no idea how I am supposed to indicate it given the format. You have a spot for your code and that's basically it.
|
# ? Jul 21, 2021 01:15 |
|
Yeah, tortoise and hare will work on any sort of traversal.
|
# ? Jul 21, 2021 01:39 |
|
You can probably do better than tortoise+hare for the specific case of a binary search tree though - if you make a leftward transition, you have an exclusive upper bound for the subtree you are now searching, and similarly if you make a rightward transition then you now know an exclusive lower bound - and these bounds tighten as you get deeper in the tree. If there's a loop in the tree, that condition will be violated on some edge, so all you need to do is track your bounds and you can identify that edge the moment you see it.
|
# ? Jul 21, 2021 02:11 |
|
Jabor posted:You can probably do better than tortoise+hare for the specific case of a binary search tree though - if you make a leftward transition, you have an exclusive upper bound for the subtree you are now searching, and similarly if you make a rightward transition then you now know an exclusive lower bound - and these bounds tighten as you get deeper in the tree. If there's a loop in the tree, that condition will be violated on some edge, so all you need to do is track your bounds and you can identify that edge the moment you see it.
|
# ? Jul 21, 2021 02:24 |
|
roomforthetuna posted:Don't even have to keep track of the bounds really - either left.data>=current.data or right.data<=current.data means some kind of tree corruption has occurred, and one of those must occur in case of a loop. (May also be caused by a malsorted tree though so if you're *specifically* looking for a loop then I think you'd still need to tortoise it.) Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree.
|
# ? Jul 21, 2021 03:44 |
|
Jabor posted:Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree. But what if all values are the same? Edit: I should go sleep. People don't normally make multisets.
|
# ? Jul 21, 2021 04:46 |
|
OddObserver posted:But what if all values are the same? While not multisets, if you're talking about user-supplied types or relations used to define the set then it's definitely possible to have multiple different elements that are "the same" according to the ordering relation. If you're writing an implementation that needs to handle that then typically one of your bounds will be inclusive instead of exclusive (e.g. "elements to the right are greater or equal"). You would need to use a tortoise-hare thing if you encountered two elements in succession that were ordered the same, since your bounds would no longer be narrowing at every step. Jabor fucked around with this message at 05:01 on Jul 21, 2021 |
# ? Jul 21, 2021 04:59 |
|
Jabor posted:If you're writing an implementation that needs to handle that then typically one of your bounds will be inclusive instead of exclusive (e.g. "elements to the right are greater or equal"). That sort of invariant can be useful but can also be problematic. Maintaining it means that rotations are not generally valid, and that it's not generally possible to balance the tree. If you control all the tree operations and don't need rotations or need to care about balancing, at least in the degenerate cases, then sure. My experience is that they're rare in practice; being able to do arbitrary rotations is useful.
|
# ? Jul 21, 2021 08:10 |
|
Jabor posted:Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree. Oh, wait, I see what you're saying. And a.left is null and b.right is null, yeah, that would do it. So you could keep track of "value and direction of the last branch taken" rather than both bounds, would be enough to also detect that case, but then it's two things anyway so meh. And it would probably be possible to construct a situation that breaks that too, so at that point bounds is easier. roomforthetuna fucked around with this message at 12:32 on Jul 21, 2021 |
# ? Jul 21, 2021 12:28 |
|
Xerophyte posted:That sort of invariant can be useful but can also be problematic. Maintaining it means that rotations are not generally valid, and that it's not generally possible to balance the tree. If you control all the tree operations and don't need rotations or need to care about balancing, at least in the degenerate cases, then sure. My experience is that they're rare in practice; being able to do arbitrary rotations is useful. Yeah, when I've implemented tree multisets in the past (I really do not remember why I did this), I think I just had nodes carry next pointers. Adding another pointer to struct node { struct node *left, *right; T value; }; doesn't actually require more memory in practice for the common case that sizeof(T) <= sizeof(void*). EDIT: markdown doesn't work here rjmccall fucked around with this message at 21:19 on Jul 21, 2021 |
# ? Jul 21, 2021 21:16 |
|
Can anyone help me understand a C networking programming mystery? Might need to repost in the sh/sc networking thread I'm using the Data Plane Development Kit https://www.dpdk.org/ for accelerated userland packet processing. I've built the DPDK ethernet device drivers, unbound my (compatible) eth ifaces from their kernel drivers and bound them to the DPDK drivers; so far so good. But I run a Traffic Forwarding example ( https://doc.dpdk.org/guides/sample_app_ug/skeleton.html ) which simply listens on one ethernet port, and forwards the traffic on another. I'm running this on a VMWare 16, Ubuntu 18.04 VM with 2 bridged adapters (these appears as Intel e1000's in the VM), but what I'm about to describe has been repro'ed on a bare metal RHEL server with NetExreme NICs. So I run the traffic forwarding example, and immediately all network traffic on my entire home LAN gets black-holed. Separate devices can no longer connect to e.g. google.com, and the second I kill the example program the connect again. The machine that the VM is running has an ethernet cable connecting to our home router, but the same thing happened when it was on our home WPA2. Wifi devices still show that they are connected to the network but can't complete any IP connections, apparently. It even generated this on my Android phoen, which I've never seen before: My theory about why this is happening is that the eth ifaces are in promiscuous mode so are "intercepting" all ethernet traffic, then the sample program's tiny rx queue buffer causes the packets to immediately get dropped. But this is not consistent with what I thought "promiscuous mode" meant. When I ran this on the bare metal RHEL server, my SSH session stopped responding, even though I had confirmed that the 2 eth ifaces (of 8 total) that I was binding were not hosting SSHD, at least according to the routing tables. Any thoughts about whats going on? Im interested mostly because it seems like a huge security issue to be able to DoS any entire LAN. Thanks
|
# ? Jul 23, 2021 18:02 |
|
Just from the symptoms it sounds like you're accidentally doing something ARP-related, like ARP-spoofing one or more important IPs. If you get full ethernet frames and not just IP packets, try only forwarding IP4 packets (ethertype 0x0800)?
|
# ? Jul 24, 2021 01:17 |
|
The Scientist posted:Can anyone help me understand a C networking programming mystery? Might need to repost in the sh/sc networking thread So, I've worked with DPDK a fair amount. I don't know for certain what you're issue is, but can confirm a few things in case that helps. The basic forwarding app blindly copies everything hitting the source interface to the target interface. It will not mutate any of the received frames, and it won't generate any bonus frames / negotiation. The user-space drivers for your NIC essentially turn the interface into a dumb/passive device. With no specific hardware configuration set (i.e. default interface configuration in DPDK) it is effectively running in passive mode. I would be very surprised if it is managing to drop packets - I'd expect something as basic as the forwarding sample application to manage a fully occupied 10GbE pipe on one core. It doesn't need a particularly deep packet queue to achieve this. The application isn't doing any form of flow control or filtering, so if you'd anticipate rote copies of ~any~ frame hitting interface 1 coming out of interface 2 have any kind of negative impact, this is likely the issue. Two things you might try to confirm this - 1) setup a virtual interface as the output interface (use 'ip link add ... type dummy'). you should be able to bind this as your output port using the DPDK RTE command-line options. You'll need to setup both the virtual pmd and also blacklist the existing tx interface - check /sys/class/net/<iface>/device/uevent can provide the PCI address for an interface, but the standard NIC drivers need to be bound for that to be present. code:
once you have it copying to that interface, you should able to tcpdump straight from that to confirm what's coming through. If this works without bricking your network (no reason to expect it wouldn't), you should now have a dump of the kinds of things it would have been forwarding - hopefully this will make it make sense. 2) modify the application as Computer Viking suggests, and stop it forwarding anything non-IP. You'll need to perform some trivial packet decode to achieve this as the rte_pktmbuf will not have any packet metadata attached to it (the structure has placeholders for such metadata, it just won't be populated). If you cast the packet data to rte_ether_hdr from rte_ether.h, then you can check the ether type against some whitelisted types. I can put together a suitable patch for the sample application if required. Alternatively the L3 forwarding sample application should be filtering non-IP (amongst other things). Spectral Elvis fucked around with this message at 09:08 on Jul 26, 2021 |
# ? Jul 26, 2021 00:12 |
|
Thanks for the comments, already proving to be very helpful. I am proceeding by running this all on multiple vm's on a private network to isolate it from other machines on this LAN. Next will be to alter the "RxTx Callbacks" dpdk example app to decode Eth frames as you all mentioned and not interfere with non-IP traffic. If this works I can transition to a real lan and a bare metal server. Thanks again and will update more if I have problems
|
# ? Jul 28, 2021 17:21 |
|
|
# ? Jun 9, 2024 04:12 |
|
I had ended up continuing the discussion of my earlier question on discord and realized I had a misconception regarding time complexity. My understanding is average time to search for a node in a balanced binary tree being O(logn) but in the worst case (in the case of an imbalanced binary tree being O(n) meant that since re-balancing the tree also took O(n) that there was no real benefit to rebalancing the three and then searching because searching and rebalancing in the case of an imbalanced tree took the same time. For some silly reason I didn't consider that if I am doing multiple searches which is what presumably the test was doing, then it has to be faster to rebalance first and then once you do all your searches you will benefit from the speed up. Granted with the interface provided I'd have to make sure it only rebalances the tree once and its unclear in retrospect if it would have even let me attempt to rebalance the tree but at least I know better now.
|
# ? Jul 28, 2021 17:30 |