I came across something curious as I was exercising my code for semaphores. My test basically prints the characters from ASCII 33 to 126 a few hundred times and then waits and repeats. There was a difference in the way that QEMU handled order of printing the characters versus the way Bochs did the same. QEMU prints the characters in ascending order the way I would expect and ran for more than 300,000 iterations where my spot checks did not show anything in the wrong order. However, Bochs botches up the order, though it appears consistent with each iteration (iteration to iteration may be different).
Here is a snapshot from a Bochs execution (notice the digits, as an easy call-out):
Later in the same execution I get "1032546789" for the digits.:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+
.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{
|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklm
nopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`
^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQ
RTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABC
DEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/021453
6798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(
')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwv
xyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehi
jklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\
[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLN
OJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?
@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/02
14536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#
"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrs
tuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdf
gehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHIKMLNOJPQRTSVUW
XZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<;=>?@ABCDEFGHI
KMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&#"%$(')*+.,-/0214536798:<
;=>?@ABCDEFGHIKMLNOJPQRTSVUWXZY\[]_`^bacdfgehijklmnopqrstuwvxyz{|~!}&"#%$(')*+.,
-/0214536798:<;=>?@ABCDEFGHIKMLONJPRQTSUVWXYZ\[]_`^bacdfgehijklmnpoqrstuwvxyz{|~
}
iteration complete: 3
Spur: 0 Prc: 1 H:0 N:0 L:0 W:0 F:1023
Is there a config setting I may be missing in Bochs? Or do I really have a bug in my code that I am not seeing and QEMU is masking it? I'm looking for a point in the right direction.... I have been working from the position that QEMU is behaving correctly, but I want to be sure before I continue.
I am using a simple round-robin scheduling algorithm with 3 possible priorities. All task processes run at the same "normal" priority with the code that created the processes at a low priority.
Also, if it helps my development environment is FC15 and Bochs version is 2.4.5-4.fc15.
The code I am exercising with is:
Code: Select all
// Exercise the Kernel:
SemID sem = SemCreate(0);
while (1) {
uint32 i;
for (i = 33; i <= 126; i ++) {
Resume(CreateProcess(TASK_FUNC(PrintLetter), 2, i, sem));
}
while (1 < processCount) {
if (0 > SemCount(sem)) Signal(sem);
else {
asm volatile("sti");
asm volatile("hlt");
}
}
iteration ++;
kPutStr("\niteration complete: "); kPutDec(iteration);
for (i = 0; i < 65000000; i ++) ; // do nothing
}
Code: Select all
#include "kernel.h"
void PrintLetter(char l, SemID sem)
{
int i;
for (i = 0; i < 490; i ++) {
Wait(sem);
kPutCh(l);
}
}
Thanks for the help!