Hello,
I have some questions about Vex threads, scheduler, and VexOS.
I have the following code:
// forward declaration
void count();
void myThreadCallback();
int global_counter = 0;
int main() {
// two threads will read/write from same var
thread myThread = thread(myThreadCallback);
count();
// this is needed else main will end before thread does
myThread.join();
// final result
printf("%d\n", global_counter);
}
// thread will run this
void myThreadCallback() {
for(int i = 0; i < 100000; i++){
global_counter++;
}
}
// called from main
void count(){
for(int i = 0; i < 100000; i++){
global_counter++;
}
}
Running this code on a single-core VM (using std::thread) produces the correct increment 200,000 (as expected because the threads run concurrently, a single thread touching a variable at a time). 2+ core VM produces with wrong increment (as expected because the threads run at the same time leading to stale/bad variables).
The EXP produces the correct increment 200,000 all the time, from the above code on VEXcode IDE. However, it is noted here that a single-core scheduler can preempt before the thread was finishes i.e. produce a wrong increment answer.
I have the following questions:
- Can the V5/EXP ever produce a data race? My tests point towards no but my threads had time to finish gracefully before the scheduler splice expired.
- How is the scheduler implemented? I’m currently assuming preemptive but I’m not certain
- What is the scheduler quantum?
- Can Events in VEXcode produce a data race? Again, I couldn’t force a data race (between main() and event function reading the same variable)
- Are Events an abstraction of threads or threads and interrupts?
Thank you for reading the post!