|
From: Mark W. <ma...@np...> - 2001-09-25 02:22:51
|
> > I thought that on NT they were implemented using real threads, and just > play games with the scheduler. I guess I got this idea from seeing a > function called ConvertThreadToFiber() or something. They are pretty much all user mode code. SwitchFiber is a very short function that just saves registers, switches the stack and exception record pointers and then dumps in new ones. It never gets into the kernel, which is one of the reasons that I find fibers so attractive. > I don't see how it is a pain. The difference is having an OOD vs. a > procedural programming model. I prefer the OOP approach, but the > difference at the machine level is that you keep a bit of state > information > in an object on the heap instead of on the stack. Of course, having the > stack for this means you have to reserve one, and even if you > only use say, > an 8kb stack, that's still a fixed 8kb for each connection, instead of > maybe a dozen bytes on the heap. For short lived connections, > this may be > a decent way to do it, but if you have connections that could live for a > good duration, you could easily end up with many 8kb stacks laying around > that aren't being used. Using a heap, you are going to get contention when allocating/freeing memory blocks. If your server is simple enough that all the objects it uses can be created at connection time then you can probably live with this, however if the state sequence it goes through is complicated enough then you won't want those objects to be there all the time. To get around this, you can outfit each connection with its own heap - but then you have to pay for the heap data structure, which is going to allocate at least one page, so we are back to paying the 4-8Kb per connection anyway. > I can see your point, and not having to change existing code is a > powerful > argument, however for new code, I'd prefer to store a function pointer to > the function for handling the next expected state, and each > function is an > easy to understand self contained piece, rather than a large > block of code > that does send/recv over and over. I think that way the code is more > readable. It's a good way of doing it - but I really want to avoid doing the rewriting if possible. Some of the code would be pretty irksome to rewrite in this style - especially since I've got a good chunk of BIND's resolver to cope with! Also I think that keeping the linear path can be more readable. For the SMTP example, then the send/recv calls can all be wrapped up in functions. These functions can just throw exceptions on error, and that way you can keep all of the error handling code in one place. This model just isn't going to work with a chain of functions. > >Just on the subject of IOCP they do seem to be a total hack (`set the low > >bit of the event handle in the overlapped structure to 1 to prevent IOCP > > Huh? > > >notification' is my favourite bit). What is it that means that > threads have > >so much weight in NT anyway? It's from the API docs. My main objection to IOCP is that seems to me that if threads were lighter weight then IOCP would be unnecessary - its just a way of getting around the weight of threads in NT. Of course the OS is far more general purpose than a specific app - there are obviously good reasons for the weight of the threads, and you can't have your cake and eat it (unfortunately!). Putting more of the responsibility on the app is going to yield a more efficient solution, as it knows more about the specifics of the situation, but it also means that the app has more to do. Thanks once again! Mark ==================================================== = To remove yourself from this mailing list, go to = = http://www.reactos.com/home/mailing.html = ==================================================== |