Page 1 of 1

Process specific IO

Posted: Sat Mar 29, 2008 8:29 pm
by piranha
I arrived at a question today while working on some init code and hadn't wrote the forking properly. As a result it executed the shell twice, making the commands not work.

Anyway, my question:
Is there a specific or known-good way to distinguish between 2 programs wanting input?
Say each call gets() at the same time. Each process is reading port 64 or whatever at the same time. Therefor the data that each gets is not correct.

Is there a simple way to distinguish?

-JL

Posted: Sat Mar 29, 2008 9:14 pm
by jzgriffin
If you have two programs running and both call gets(), I would assume that you have virtual terminals, in which case you would deliver the input to the active terminal, or, more specifically, the active (foreground) process. I would recommend building this in to your keyboard driver and having the syscall interface that. Then, the driver would use the terminal driver (or process system, which would in turn use the terminal driver) to figure out what process/terminal is active, and then deliver the input there.

Just my 2c. I haven't gotten that far yet, but it's how I'd implement it once there.

Posted: Sun Mar 30, 2008 12:59 pm
by AJ
Yup - I have implemented virtual consoles and that's how I do it. You need to keep track of which console currently has 'focus' and send the keystrokes to that app. You then need some way of switching between consoles.

In the same way, you need to do this for printing on the screen, otherwise you end up with a similar problem. From my own personal experience, trying to multitask in a single console instance just creates one big mess!

Cheers,
Adam

Posted: Sun Mar 30, 2008 1:44 pm
by t6q4
Although this suggestion will not let you access the port with 2 apps reading from there at the same time, it will create a lock so only the first shell will work.

Code: Select all

u32int shell_running = 0;

void shell(){
  if(shell_running==1){
    for(;;);
  } else {
    shell_running=1;
  }

  //Shell stuff goes here
}
Just a bit of psudocode there. Hopefully it will explain itself.

Posted: Sun Mar 30, 2008 2:01 pm
by xyzzy
I don't quite see how that works if there are 2 separate processes, because each process will have it's own copy of the shell_running variable.

Anyway, if you do line buffering for gets in the kernel, you can put processes on a queue for lines of input. When you get a full line of input available, take the next process/thread off the queue and give it that line, then when the next line comes in give it to the next process/thread on the queue, etc.

Posted: Sun Mar 30, 2008 3:57 pm
by AJ
Hi,

I think t6q4's way is a little drastic, particularly the:
t6q4 wrote:

Code: Select all

if(shell_running==1){
    for(;;);
  } else {
    shell_running=1;
  } 
which will lock indefinitely if there is a shell instance already running (once you get in to that for(;;) loop). If you wanted this approach (allow just one shell running at a time), it would be better to use either:

Code: Select all

while(shell_running==1);
which will let the second shell start once the first shell has finished, or:

Code: Select all

if(shell_running==1) exit();
which (if you have written an exit system call) will exit subsequant shells. I still think giving one console 'focus' is the best idea, though.

Cheers,
Adam

Posted: Sun Mar 30, 2008 4:59 pm
by jzgriffin
Virtual console/active process focus is a more long-term solution, for when you have 'programs' running from the shell - certainly, some will use a gets() call to ask the user for information.

Posted: Sun Mar 30, 2008 7:07 pm
by piranha
My solution (came up at a party, as most of my ideas come from a little alcohol):

Code: Select all

getch() {
	  while(!get_kb_ok || (current_task!=focused_task)
	  {
		  hlt();
	  }
          get_kb_ok=0;
          /* Do getch() code here */
          get_kb_ok=1;
          return key_press;
}
It does work. Of course, I had to modify a bunch of tasking code to fit it, but it works now.

-JL

Posted: Mon Mar 31, 2008 1:58 am
by distantvoices
Never seen such a solution.

I'm doing it by the use of the console driver and dedicated console-nodes in the VFS. There's a flow of communication between fs-service and console driver of course.

So, if f. ex. console 3 is active (in text mode - gui mode works completely different), it is marked active inside the driver which then sends keys to the according endpoint, which is registered in the file system service.

File system service knows who's reading on that special node currently (only one at a time permitted) and sends the input to that task.

End of problem. This model works without special hlt() or loops. Just look who's sitting there waiting for keys. It comes along in different shapes: synchrounous, async, buffered, nonbuffered, what so ever.

Microkernels are cool. *gg*

Posted: Mon Mar 31, 2008 4:56 am
by einsteinjunior
Why not force each application to create some sort of console handle.
Then your keyboard driver should send the data to the app having focus at the time and also using the console handle that uniquely identifies the console of the application.Moreover,with this concept,an application could have more than one console where is can receive input.

Posted: Tue Apr 01, 2008 6:10 pm
by iammisc
if you open a terminal(a virtual terminal or a physical terminal or any terminal) on linux, and run python then fork it, each python process gets any of the characters you typed. This is not really an answer but rather some insight into how a very popular operating system handles it. Personally for me, if having each program get garbage input worked for linux, then i'm sure it will be more than enough for me.