Bochs and QEMU concurrency test

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
MarkD
Posts: 7
Joined: Tue Jul 16, 2024 6:33 pm

Bochs and QEMU concurrency test

Post by MarkD »

Hi,
For my hobby OS, I'm currently using a single processor and have a preemptive kernel with time slicing. I disable interrupts to protect my scheduler queues and other state. No virtual memory or user mode support. Mostly C++ (gnu cross compiler) with a bit of assembly. No compiler optimization turned on. Everything is a kernel thread and is running nicely.

I'm now ready to start work on exploring proper locks. So I wrote a simple test to see the actual problem:

int count = 0;

void funP(void*)
{
for (int ii = 0; ii < 10000000; ii++) {
count++;
}
}

void testConcurrency()
{
Task* task1 = new Task("1", &funP, (void*) 1); // Name, function, argument
Task* task2 = new Task("2", &funP, (void*) 2);

task1->join();
task2->join();

printf("Count = %d\n", count);
}

To my surprise, QEMU always printed out 20000000. No concurrency issues!? The increments are perfectly interleaved. Bochs did what I expected and returned a different result every time 15782628, 15090785, 14213397, etc. Exact same image run by each tool.

I added a printf in the loop to check that the tasks were in fact being interleaved
void funP(void* arg)
{
int num = (int) arg;

for (int ii = 0; ii < 10000000; ii++) {
count++;
if ((ii % 1000000) == 0) {
printf("%d", num);
}
}
}

The (cleaned up) output was
12 12 12 21 ...
So it's not the case that task1 was run to completion then task2 was run.

Any idea on why they are different? I'd like to make QEMU run more realistically, but I don't know what to look for in the doc.

Thanks.
Octocontrabass
Member
Member
Posts: 5446
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bochs and QEMU concurrency test

Post by Octocontrabass »

MarkD wrote: Sat Aug 24, 2024 2:11 pmAny idea on why they are different?
Bochs emulates each instruction one at a time. It can emulate an interrupt occurring on any instruction boundary.

QEMU either recompiles the guest code for the host CPU or runs the guest code using hardware virtualization. With recompiled guest code, interrupts are only possible between blocks of recompiled code, not between individual instructions. If the entire read-modify-write sequence ends up in a single block, there will be no concurrency issues. With hardware virtualization, I'm not sure if you would still have the same problem.
MarkD
Posts: 7
Joined: Tue Jul 16, 2024 6:33 pm

Re: Bochs and QEMU concurrency test

Post by MarkD »

Thanks. I think that's it.

If I run qemu with -accel kvm and increase the loop counter to 1000000000 (1B) (because it is so much faster) then some runs I will see count < 2B, e.g., 1.96B

Thanks.
Post Reply