To make my point clearer I take the example of printf. I don´t know how this works in OS´s like Linux or Windows, but the problem I have with this special function is, how can I get a string, of a length I don´t know, into my appserver? E.g.
Code:
printf("value of x: %d and of y: %d\n",x,y);
Either you make the whole string thing in userspace, so you have to allocate a buffer which is big enough and then you copy the string there and if you finished you call the kernel to send a msg with the string. Here the kernel now needs to allocate memory big enough in size to take the string and what else is needed for the msg and send it to the receiver.
Another way would be, call the kernel and send only the string till the "%". Then use a buffer and construct the string which is needed for "%d", call the kernel again. And so on. This would be the worst method.
So I would have a ringbuffer and I assume that the read and write pointer are at the same point. So I could write at least so much bytes into the buffer as the size of the ringbuffer. And I think for my above example of the printf function 4096bytes should be enough. So I would make only one call to the kernel which then could wake up the receiver which then could read byte by byte out of the ringbuffer and display it on screen. I could also make it so, that the sender gives up its timeslice and the priority of the receiver gets a boost, maybe this would make things faster on a one cpu system. And on a one cpu system you will have always context switches to get the code of the receiver run.
I know that is just another form of shared memory, but here the programmer hasn´t to do the work to get it synchronized.
The only disadvantage of this is that it is a one way communication. At the moment I don´t see a problem with that. Ok I wast at least 4kb of memory for every ringbuffer, but this shouldn´t be a problem. I think with a fixed sized msg you can do most things and when there is the need of bigger sizes you take the ringbuffer.
I think the advantage of my design is, that the user just calls a "put" function as often as he wishes and he hasn´t to deal with if the buffer is full or not, the user even wont notice if the "put" function gives up to the receiver. So I have only to do:
Code:
putchar(char c) {
put(bufHandle,c,1);
}
And the rest of handling the buffer and call the receiver is done at the "put" function. The only thing is that at the end of a printf, the user should call something like "flushBuffer" for the case that the buffer isn´t full. This however would make my implementation of printf in some way tricky, because I call myself if I need to do something like this:
Code:
printf("text: %s\n","Hello World!");
So maybe I find a way to resolve this.