1

I'm writing a simple system call function, and came across some phenomenon I couldn't understand. In the code below, I used a variable "flag" to replace the long bothering "prptr->prhasmsgb" at [1] and [2]. I supposed that it won't cause any difference, but it turned out that the first call to this function, with prptr->prhasmsgb=0, will skip if and enter the switch(). This error is consistent, and I suppose this may have something to do with compiler (gcc)? Also, how does the compiler (gcc) determine what is independent and what to parallelize? I've got no clue on compiler, any advice would be appreciated. Thanks!

ps: The code below is almost what I have in my original code, except for the do something part.

prptr = &proctab[currpid];      /* prptr is a pointer, and below are supposed   */
                                /* dealing with different prptr->prhasmsgb.     */
                                /* prptr->prhasmsgb = (int){0,1,2,3}            */
//  int flag;
//  flag = prptr->prhasmsgb;    /* I used flag to replace prptr->prhasmsgb      */
//                              /* if[1] & switch[2] are "paralleled" somehow */

/* case 0 is handled here */
if (prptr->prhasmsgb == 0) {    /* [1] once was flag                            */
    do something;
    resched();                  /* call reschedule */
}

switch (prptr->prhasmsgb) {     /* [2] once was flag                            */
    case 1: 
        do something;
        return value;
    case 2: 
        do something;
        return value;
    case 3:
        do something;
        return value;
    case 0:
        /* should never enter case 0 */
    default:
        return error;
}    
7
  • Are you compiling with or without optimizations? Commented Mar 25, 2014 at 4:21
  • Could your function be called from more than one place? Commented Mar 25, 2014 at 4:23
  • The compiler doesn't parallelize your code in the sense of multi-threading, it does "vectorize" your code if it can pack multiple operands into a vector register, but that isn't what is going on here. Commented Mar 25, 2014 at 4:28
  • print flag after assignment Commented Mar 25, 2014 at 4:32
  • @sharth The given Makefile has "-O0" flag. I'm not quite sure how it works though. Commented Mar 25, 2014 at 13:36

1 Answer 1

4

The compiler doesn't parallelize your code in the sense of multi-threading, it does "vectorize" your code if it can pack multiple operands into a vector register, but that isn't what is going on here.

My guess is that the call to resched() will change the contents of proctab[currpid], so that when it returns to your program it now has a different value. As long as you access that by dereferencing prptr the compiler does the safe thing, and makes no assumptions about the contents of memory at that location, so it generates a load from memory.

However, if you use a local variable, flag, to "cache" the contents of prptr->prhasmsgb, then it doesn't reload from memory, and you don't execute case 1, 2, or 3 in your switch, you execute case 0 which falls thru to the default case and return error.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, the scenario was indeed "not executing case 1, 2, or 3 in switch". However, as above in the other comments, I tried to print flag right before "if", and it was 0. Is that possible the machine code put "if - switch" before "assignment - print"? Since the error only happen in the first call... I'll try to wiki "vectorize", thanks for the keyword :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.