UDI, EDI, CDI Which do you use and why

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
gmoney
Member
Member
Posts: 106
Joined: Mon Jan 03, 2005 12:00 am
Location: Texas, Usa

UDI, EDI, CDI Which do you use and why

Post by gmoney »

Hi im currently re-working on my module loader to be compatible with other hobby os and I honestly don't know which one to implement i started with cdi but couldnt find enough info on it... So what do you use in your os and why?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by thepowersgang »

Most of my loadable modules are native modules, but I have a (nearly) fully working UDI implementation.

Of the "common" device interfaces, I prefer UDI, because it has had the most work put into it. It is relatively complex to get started with, but it is the most extensible of the interfaces. (That said, it lacks a proper graphics binding, though someone was working on one).

EDI is dead as far as I know (and had some glaring holes in it), I've never worked with CDI, but I think it was quite a bit better (just nowhere as cross-platform as UDI)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Kevin »

UDI is the heavy-weight professional solution that covers probably most requirements that you could think of and it comes with the corresponding complexity.

CDI is the "just a hobby, won't big and professional like UDI" thing that has simple interfaces with less features and is therefore quite easy to understand and implement. It is still extensible, because unlike UDI it doesn't guarantee strict API and especially ABI stability (binary compatibility between OSes isn't a goal for CDI), so if you need more at some point, you can probably do it.

The two main reasons why I started CDI with some other hobby OS developers is that UDI was too complex for my needs, and that I couldn't find any free drivers to use for the standard components like IDE, rtl8139, etc. Not sure if anything has changed with UDI, but with CDI we tried to create a central repository of free drivers - which might not be that large yet, but it's more useful for my hobby OSes than anything that I've seen for UDI so far.

As for information, you probably know the Doxygen docs, which I'll freely admit are still lacking. Basically the approach for implementing it is checking out the CDI repository, choosing a driver and implementing functions from the header files until it builds. Then make sure you call the init function of the driver and the devices it detected and that's it. I think network drivers are the easiest for the start, or possibly storage.
Developer of tyndur - community OS of Lowlevel (German)
gmoney
Member
Member
Posts: 106
Joined: Mon Jan 03, 2005 12:00 am
Location: Texas, Usa

Re: UDI, EDI, CDI Which do you use and why

Post by gmoney »

So in a nutshell i should start off with an easy interface such as cdi then when i need more power and portability then implement udi. Also, out of curiosity, what glaring holes does edi have in it since i see you have implemented it in your kernel (acess2)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Combuster »

UDI is the powerhouse of the lot, but doesn't have that much drivers unfortunately because it's more complicated. I have a fair bit of it implemented though.

CDI is ok for unix clones, but it needs some horrible hacks to use in an asynchronous message passing userspace to the extent that I decided against it. In comparison, UDI is fully suited for such microkernel environments without becoming unwieldy on monolithic environments.

EDI is apparently dead. The homepage is broken and shows me the source of the CGI script (proper doxygen here). It also has a hard dependency on posix threads.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by thepowersgang »

I once had an attempt at an EDI shim, but never completed it (*goes and deletes that evil*). I may look into CDI sometime, either that or make a bigger set of UDI drivers (I have a NE2000 one that works well enough for my OS to use it).

IMO, the best is UDI, but it is complex. Hopefully the presence of multiple independent implementations will make it more likely to be used.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Kevin »

Combuster wrote:CDI is ok for unix clones, but it needs some horrible hacks to use in an asynchronous message passing userspace to the extent that I decided against it.
What kind of hacks are you thinking of here? You won't easily get parallelism, but that's only a performance issue (and true when used with monolithic Unix-like kernels, too - changing that would involve API changes) and the basic implementation shouldn't involve any horribe hacks. Most of the OSes implementing CDI aren't exactly Unix clones, and a good share of them uses microkernels.
Developer of tyndur - community OS of Lowlevel (German)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Combuster »

What kind of hacks are you thinking of here?
Driver code is never interrupted. The only exception is the function cdi_wait_irq: While it is running, IRQ handler may be executed.
The problem is that you have to block the thread for any calls made to services provided outside of the process. In a synchronous design you can just wait for the reply and then continue the code normally, but for an asynchronous design you'll have to deal with the problem of the next request arriving to your event queue (which you can't execute because it would interrupt running code) before the response of the pending operation you need for finishing the waiting request does.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Kevin »

I see. So you're getting the responses to your own requests in the same message queue as where you get new requests? Won't that always be awkward to work with as soon as one request needs to take a lock, no matter what the interface to the actual driver code looks like?

I can imagine that it's quite easy to write a simple network or block driver that doesn't need locking and can always accept new requests, but less so for something complex like a file system driver. So in the end I suppose you always end up moving requests from your message queue into a different queue where they wait for the lock to be released while you're waiting for the responses for your own requests.

Does UDI really work without such an internal queue? I don't know it well enough to say who'll call the callback when the driver is ready to process the next request and it may be hidden somewhere deep in the UDI mechanisms, but I'm pretty sure that it must be there.
Developer of tyndur - community OS of Lowlevel (German)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Combuster »

I see. So you're getting the responses to your own requests in the same message queue as where you get new requests? Won't that always be awkward to work with as soon as one request needs to take a lock, no matter what the interface to the actual driver code looks like?
Even if you separate message queues, you have to know which one serve requests, and which ones serve replies. Besides, it might be very well the same process that delegates your permissions and relays the requests at the same time - will you suddenly force it to use a different channel for each possible message to keep them separate - that would be just as much an ugly hack, and a less favourable one than doublequeueing everything regardless of origin.

I consider locks an antipattern anyway - in particular the kind that don't get relinquished within a constant number of instructions. Locks add complexity and security hazards, can be nearly impossible to reason about, and they are often added to tasks that can be written intrinsically safe without them: proper queueing and threading give good multitasking without the use of any such constructs. There's no need at all to block app B from reading a cache because app A happens to be waiting for a disk access.

In fact, one such haphazard is that the specification implies that any cyclic attempt to communicate within CDI automatically deadlocks. Permanently, regardless of kernel architecture.


As far as your question is concerned: UDI strictly disallows blocking. It also provides queues as part of its own standard library for the obvious reason.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Kevin »

If you're interpreting "lock" as threads and their mutexes, then you're taking a much narrower definition than what I intended. What I mean is any mechanism that manages access to a shared resource by letting some users wait for others to release the resource. You may well implement this using queues, but the implemented concept remains the same.

At least as long as we don't introduce parallelism, CDI is neutral towards the way of implementing this. I would probably use a queue, too.
Combuster wrote:There's no need at all to block app B from reading a cache because app A happens to be waiting for a disk access.
And I hope that nobody is suggesting this.
In fact, one such haphazard is that the specification implies that any cyclic attempt to communicate within CDI automatically deadlocks. Permanently, regardless of kernel architecture.
So far there hasn't been any need to do so. You don't have to agree with the approach, but the CDI way has always been to solve problems when they arise in practice.
As far as your question is concerned: UDI strictly disallows blocking. It also provides queues as part of its own standard library for the obvious reason.
In my book, a request is still blocked when it's waiting in a queue, but that's terminology. :)

The important part is that you can use the same queuing in both frameworks. UDI just allows drivers having multiple requests being in a non-initial state (i.e. not waiting in the queue of incoming requests), whereas CDI doesn't.
Developer of tyndur - community OS of Lowlevel (German)
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: UDI, EDI, CDI Which do you use and why

Post by gravaera »

Yo:
Kevin wrote:I see. So you're getting the responses to your own requests in the same message queue as where you get new requests?
There is no request queue as far as the UDI driver is concerned. The UDI driver uses callbacks and is not aware of the presence or absence of a request queue (and many environments may not use message loops, because their APIs are not asynchronous, or they are monolithic). The UDI driver has functions, and entry points.
Kevin wrote:Won't that always be awkward to work with as soon as one request needs to take a lock...
There is no lock, and I am one of the people whose UDI environment is already completely lockless. UDI has no concept known as a "lock".
Kevin wrote:So in the end I suppose you always end up moving requests from your message queue into a different queue where they wait for the lock to be released while you're waiting for the responses for your own requests.
You don't need to wait for anything in an asynchronous design: that's the entire reason for asynchronous design :)
Kevin wrote:Does UDI really work without such an internal queue?
Yes, it will: the UDIRef reference implementation is mostly based on a monolithic blob design, and you can see this at work in there. My own environment is microkernel-like, and has separate-address-space drivers, and an almost purely asynchronous kernel, so I use request queues. This is just the most natural way for my kernel to do anything, being highly asynchronous.
Kevin wrote:I don't know it well enough to say who'll call the callback when the driver is ready to process the next request and it may be hidden somewhere deep in the UDI mechanisms, but I'm pretty sure that it must be there.
For a monolithic kernel, channel operations are transformed into function calls. Think of it as being the same as how the Linux kernel (and probably your own as well) silently optimizes locking primitives into "CLI/STI" on a single-CPU build.
Kevin wrote:If you're interpreting "lock" as threads and their mutexes, then you're taking a much narrower definition than what I intended. What I mean is any mechanism that manages access to a shared resource by letting some users wait for others to release the resource. You may well implement this using queues, but the implemented concept remains the same.
No such concept exists in UDI, and it is entirely conceivable for a kernel to operate UDI drivers locklessly (like mine).
Kevin wrote:In my book, a request is still blocked when it's waiting in a queue, but that's terminology. :)
Requests don't block; they are queued and processed. Threads block :)

--Peace out,
gravaera
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Kevin »

Hi gravaera,

you may prefer different terminology than what I use, but as I already explained to Combuster, in which I sense I meant them, I must assume that you're intentionally misunderstanding what I'm saying. Therefore I won't bother to reply to most of your points.

Also, maybe I should add that as a qemu block layer developer for a few years, I'm intimately familiar with different styles that coexist there, from synchronous requests and callback-style AIO to per-request coroutines and worker threads processing queues. So you can assume that I do know that callback-style APIs don't have an aio_lock() call - but semantically, queuing them is doing the same thing as a mutex: letting a request wait (and guess how qemu's coroutine locks are implemented internally? Right, queues.) It's all the same thing, just looking a bit different on the surface.
gravaera wrote:
Kevin wrote:I see. So you're getting the responses to your own requests in the same message queue as where you get new requests?
There is no request queue as far as the UDI driver is concerned.
We're talking specifically about Combuster's OS here (and in other quoted parts of my message that I won't reply to). There is no request queue as far as CDI is concerned either. It's the OS-specific implementation of the interfaces that needs to add it and that may or may not be easier with one interface or the other.
You don't need to wait for anything in an asynchronous design: that's the entire reason for asynchronous design :)
In something as complex as a file system driver, you will very likely have to let some requests wait on other requests. Yes, sitting in a queue is waiting, even if you avoid the bad word "lock". Changing terminology doesn't change the way your code works.
Developer of tyndur - community OS of Lowlevel (German)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: UDI, EDI, CDI Which do you use and why

Post by Combuster »

Kevin wrote:you may prefer different terminology than what I use
Considering that
Wikipedia wrote:In computer science, a lock is a synchronization mechanism for enforcing limits on access to a resource in an environment where there are many threads of execution.
it might be wise to actually use the scientifically accepted definitions, instead of turning "lock" into something as meaningless as "anything that waits" which only ever serves the purpose of being unable to use the term.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: UDI, EDI, CDI Which do you use and why

Post by gravaera »

Yo:

Kevin, I didn't realize you were specifically talking about Combuster's environment, my bad;

--Peace out,
gravaera
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Post Reply