Page 1 of 1

Resource Control Issues

Posted: Wed Jun 20, 2007 8:47 pm
by astrocrep
Ok, if I have two threads that run in infinite loops printing an increasingly large number (in the same location) I have an issue where it apprears the time slice cuts in the middle of the printf or even worse in the middle of the move cursor routines and sometimes I get charecters at random locations.

What I was think was placing a resource semaphore on the console.

So basically, if someone wanted to move the cursor, or print a charecter those routines would do something like a:

Code: Select all

REQUEST_CONSOLE();
And basically this would sit in a loop and wait until the Console Semaphor was 0, and then it would jack it up to 1, and then when its operation completed, drop it back down to 0.

Code: Select all

void REQUEST_CONSOLE()
{
  while(RESOURCE_CHECK(CONSOLE_ID) == 1);

  RESOURCE_SET(CONSOLE_ID);
}

void RELEASE_CONSOLE()
{
 RESOURCE_FREE(CONSOLE_ID);
}

void putch(int c)
{
  REQUEST_CONSOLE();
   .... putch
  RELEASE_CONSOLE();
}

void movecursor(int x, int y)
{
  REQUEST_CONSOLE();
  .... move cursor
  RELEASE_CONSOLE();
}

The functions:

RESOURCE_FREE
RESOURCE_SET
RESOURCE_CHECK

Would all be used to check / modify the state values of various elements. I was thinking I could use an array, and in this case, CONSOLE_ID would be the index in the array. I Could also have KEYBOARD_ID etc etc...

I would have to declared the volitale char RESOURCE[16]; like that right?

This way if the processes are running back and forth, only one of them could actually access the screen resources at a time, and this would save me from having to disable interrupts as an alternative approach.

Is that about right?

Thanks,
Rich

Posted: Thu Jun 21, 2007 6:42 am
by Combuster
No:
you can have a task switch occurring between the while loop and the set(), which will cause several threads to think they are the only ones with the lock set.

read Wikipedia and the many pages linking from there to get an idea of what is involved.

Posted: Thu Jun 21, 2007 8:18 am
by Brendan
Hi,
Combuster wrote:No:
you can have a task switch occurring between the while loop and the set(), which will cause several threads to think they are the only ones with the lock set.

read Wikipedia and the many pages linking from there to get an idea of what is involved.
Yes.

But then ask yourself if it'll work properly after you've got some mutual exclusion around "printf()".

For example, what if you've got 2 threads like this:

Code: Select all

void thread1(void) {
    for(;;) {
        printf("The CPU is ");
        if(temperature > 35) {
            printf("HOT!\n");
        } else {
            printf("cool.\n");
        }
        sleep(10);
    }
}

void thread2(void) {
    for(;;) {
        printf("You are ");
        if(mood > 0) {
            printf("happy.\n");
        } else {
            printf("sad.\n");
        }
        sleep(10);
    }
}
In this case, you might get something like:

Code: Select all

The CPU is You are HOT!
happy.
It doesn't work...

Instead you could have seperate "line buffers" for each thread, and send the buffer to the console when a "/n" is placed into the line buffer. This is (sort of) what UNIX systems do and it does fix the problem above, but it still doesn't really work. Consider this:

Code: Select all

void thread1(void) {
    for(;;) {
        printf("Memory usage:\n");
        printf("  %d pages free\n", freePages);
        printf("  %d pages in use\n", totalPages - freePages);
        printf("  %d pages total\n", totalPages);
        sleep(10);
    }
}

void thread2(void) {
    for(;;) {
        printf("Shopping list:\n");
        printf("  bread\n");
        printf("  3 eggs\n");
        printf("  12 donuts");
        sleep(10);
    }
}
In this case, you might get something like:

Code: Select all

Shopping list:
  bread
Memory usage:
  23 pages free
  3 eggs
  44 pages in use
  67 pages total
  12 donuts
You could have a seperate buffer for each thread, and send everything in the buffer when the thread calls something like "flush()". In this case the thread can put several related lines of text into the buffer and then send all of the related lines of text to the console at the same time.


Cheers,

Brendan

Posted: Thu Jun 21, 2007 8:58 am
by Aali
protecting the console functions is a Good Idea (TM)

protecting applications from "ruining" each others output however, is pointless
two or more applications on the same console is always going to be a mess, whichever way you chose to print their output

Posted: Thu Jun 21, 2007 9:50 am
by astrocrep
Aali wrote:protecting the console functions is a Good Idea (TM)

protecting applications from "ruining" each others output however, is pointless
two or more applications on the same console is always going to be a mess, whichever way you chose to print their output
Ohh I totally agree, I am just screwing around with some testing stuff, my OS is going to be very similar to BEOS in the fact that you've got a GUI from almost the moment it boots.

So I really don't care about protecting the console from two running threads, but I was more interested in the thought process and logic behing semaphore and mutexs.

Thanks,
Rich