CPU time per timeslice on 386/486

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.
Post Reply
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

CPU time per timeslice on 386/486

Post by durand »

Hi,

I'm currently using the rdtsc instruction to determine how many instructions were executed during a timeslice. Then I'm adjusting system time accordingly (since I know how long a single instruction takes).

But how can I do something similar on a 386 or a 486? They didn't have the rdtsc instruction. Also, my timeslices are variable in length because a thread can release the rest of it's time if it no longer needs it.

Durand.
pini

Re:CPU time per timeslice on 386/486

Post by pini »

I would use timer interrupt rather than TSC to keep track of time/timeslices, because TSC is based on the processor speed, and even if you can adjust calculation to obtain a time value, the game is not worth the candle (I don't know if this expression means the same in english as it does in french).

If you want compatibility with older computers, you'll have to use timer interrupts. A good timeslice value is between 20 and 50ms (according to A. Tannenbaum) to maintain interactivity. These values are easily done by reprogramming the timer.
If you want to provide a kind of "sleep" system call, you could even set up a 10ms timer to count down sleeping time and count the current process/thread timeslice before switching.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:CPU time per timeslice on 386/486

Post by durand »

Cool. Thanks for the reply.

I've actually added an i386 branch to my kernel tree and I'm removing anything that requires a 486+ in that branch. So it's not a decision of either/or this-method or that-method because my old method still remains for the default i686 branch. Which is great.

There is a userland call which releases the rest of the timeslice available to the thread and I'm using a default of 10ms slices. I think it is, and have found, the call to be very useful. It definitely improves the responsiveness of the system. If my thread only takes 1ms to run, it only uses 1ms.

I was hoping there was another way, though, for i386 machines which provide the same functionality.

If there isn't, I'll replace my userland call with a basic asm("halt") which will hang stuff until the next interrupt. Then my timeslices will always be a specific length. Easy enough to add 10ms on every scheduler entry... :-/ Not great though. There must be a better way.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:CPU time per timeslice on 386/486

Post by Candy »

386/486 have a static time per instruction, not counting memory access. You should be able to determine them quite easily, possibly even with the PIC.
sturmstiger

Re:CPU time per timeslice on 386/486

Post by sturmstiger »

I really don't think today's kernel designer need to consider 386 compatibility. Who still use 386 anyway? To enable 1/2^32 users to use your OS, you need to sacrifice speed and code size...or have users recompile the code for optimization.
Sorry if I offended any 386 user.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:CPU time per timeslice on 386/486

Post by durand »

I want to do it to support some embedded boards. :) I'm planning on playing soon by making really small things.

Although, you do get some good pentium+ based systems on chips and stuff, I was just playing again and seeing how far back I can get the system. Obviously, if I can save some money by going for 386/486 compatible versus pentium compatible, I will. :)

There are some really cheap ARM boards available here for 6 - 10 US$ as well. Uh.. but I don't support ARM yet.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:CPU time per timeslice on 386/486

Post by Brendan »

Hi,

Not sure if this will help, but my OS uses either the PIT or local APIC timer (depending on what's present) in one-shot mode (rather than in periodic mode). Instead of getting an IRQ every X mS I get an IRQ X mS after the count is set.

Generally I reprogram the timer's count during the thread switch. This means that the amount of time before the IRQ occurs can be different for each thread (ie. lower priority threads would get more time before the IRQ is generated).

The main problem here is that you can't use the PIT for measuring elapsed time (e.g. the "system timer tick"). I use the RTC/CMOS timer (IRQ 8 ) for this instead.

I've found this technique to be reliable, and it also has unrelated benefits for older multi-CPU computers where IRQ 0 isn't connected to the IO APIC. AFAIK Linux gets around this by setting up an ugly "virtual wire" thing, where the PIC sends some IRQs and the IO APIC sends others. In this case my OS doesn't use the PIT timer at all, so I don't need the virtual wire thing (all IRQs are handled by the IO APIC in all cases, except when there is no IO APIC).

BTW the 2 main reasons I won't support 80386 is the NE bit (native FPU exception reporting), and the INVLPG instruction. My minimum requirement is an 80486DX - FPU is required, even though the kernel doesn't use it.

If you can get an 80386 based embedded board for $6 to $10 then you can probably get an 80486 board for $8 to $14. IMHO the extra is well worth it, even if it is just for the INVPLG instruction :).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:CPU time per timeslice on 386/486

Post by Pype.Clicker »

alternatively, you can also program the PIT with a higher frequency (say, 1000 Hz) and decrement a 'time quota' of the thread at each interrupt, switching only when the quota comes to zero (in your case, the quota is set to 100 initially).

If a thread releases early, you just look at its 'quota' variable to know for how long it has been running (that should be 100-quota ;) )

That being said, i don't know what you want to do with that value ... are you going to allow the thread to run longer the next time ?
Ushma

Re:CPU time per timeslice on 386/486

Post by Ushma »

Pype.Clicker wrote: If a thread releases early, you just look at its 'quota' variable to know for how long it has been running (that should be 100-quota ;) )

That being said, i don't know what you want to do with that value ... are you going to allow the thread to run longer the next time ?
Donation of remaining timeslice to another thread?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:CPU time per timeslice on 386/486

Post by Candy »

Ushma wrote:
Pype.Clicker wrote: If a thread releases early, you just look at its 'quota' variable to know for how long it has been running (that should be 100-quota ;) )

That being said, i don't know what you want to do with that value ... are you going to allow the thread to run longer the next time ?
Donation of remaining timeslice to another thread?
My idea of that would be to donate the timeslice & priority level to a thread on which it is waiting, so that the other thread can run at its level (avoiding priority inversion if I'm correct) and to give it back when it returns a mutex.
mystran

Re:CPU time per timeslice on 386/486

Post by mystran »

What I do is basicly what Pype described.

Reprogramming PIT with a new counter at thread switch has the problem that there can be problems with accurate timing, and you probably need another source for your wall-clock time then. The trouble is, unless you can reprogram the PIT really fast, you must also adjust for the time between the PIT interrupt, and the moment at which you re-enabled counting. If this time can be long enough for internal PIT-ticks to go by, then you have a timer drift problem, unless you measure the time somehow.

Ok, so you have a drift problem with periodic PIT too.. but at least it's more or less constant then, because it's caused by internal inaccuracy of your PIT. But then again, you'd have to compensate for this one anyway, whether you use periodic or oneshot.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:CPU time per timeslice on 386/486

Post by durand »

Cool guys. Thanks a lot for the help. :)

Basically it comes down to it not being as easy as it is on new processors - which is to be expected.

I've gone with setting a hard 20ms timeslice using the PIT. Each "release timeslice" call just jumps through and halts the CPU (interrupted by the timer IRQ) until the next timeslice - whether kernel or userland . It doesn't make for a very responsive system but it works. My sleep/timing is accurate enough and the time drift hasn't been noticable yet. (I should leave it over night.)

I have a working i386 branch and a working i686 branch for my system. :) It's cool. So I'm modifying the make system and adding a configuration system to support the multiple branches.

So.. the real question is, does anyone have a 386 lying around? ;)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:CPU time per timeslice on 386/486

Post by Candy »

lowest I have present is a 486dx-100. You could try anything on it, don't use it myself at all.

Ignore 386 and lower, they don't have invlpg making each page table change slow down your entire computer significantly
Post Reply