Page 2 of 2

Re: GCC and SMP problems

Posted: Fri Nov 27, 2009 2:43 am
by Solar
gravaera wrote:I had always assumed that keywords and storage class keywords applied to the entire declaration/definition...
Funny... it was one of the first things in the books I read, the differences between

Code: Select all

int * i1;

const int * i2;

int const * i3;

int * const i4;

int const * const i5;
For anyone not following the article links: i2 and i3 are identical, pointers to constant integers. In i4, you have a constant pointer to a non-const integer (you can change the integer but not the pointer, so you better initialize it right away), and in i5 you have a constant pointer to a constant integer (you can change neither).

Same goes for volatile.

gravaera, what you probably remembered meant are static, extern and auto, which indeed work for the whole declaraction.

PS: And if you take a minute looking at the code lines above, you can figure out why I always write it as with i3, and never as with i2 (if I can help it - I went with the standard declarations in PDCLib).

Re: GCC and SMP problems

Posted: Fri Nov 27, 2009 10:55 am
by gravaera
@Solar: Thanks :)

I'm always glad to learn something new, or improve something where I was faltering. I suppose a bit more reading is in order, but you've laid it out rather clearly for me.

--All the best
gravaera.

"Volatile-considered harmful" (was:Re: GCC and SMP problems)

Posted: Thu Dec 03, 2009 4:28 pm
by Darwish
FlashBurn wrote:So, problems solved. You have to write the following and then it works:

Code: Select all

static struct smpMsg_t * volatile freeList
So maybe someone could say where should the volatile keyword stay? I always though that "volatile uint32t foo" is alright, isn´t it. Or is this only not right for pointers?
Volatiles are really subtle in C, and as seen by the ACM paper posted by dosfan above, many compilers get them wrong. For above coding case, I prefer the Linux way of handling the issue, namely minimizing 'volatile' as far as possible, and depending on compiler and/or cpu barriers as needed.

In above case, you can simply avoid volatile altogether, and use the gcc barrier "memory". As said by its manual, the memory barrier "will cause GCC to not keep memory values cached in registers across the assembler instruction and not optimize stores or loads to that memory." So in above code, you can use:

Code: Select all

      while(likely(freeList == 0))
         asm volatile("pause": : :"memory");
and have peace.

In the risk of mimicking the linux kernel too much, you can create a cpu_relax() method, which abstracts the 'asm volatile("pause": :"memory")' part and use it in all your busy-loops. For further info check:
1- Linux kernel Documentation/volatiles-considered-harmful.txt
2- Linus's posts on volatile. Original patch, reply 1, and reply 2.

Re: "Volatile-considered harmful" (was:Re: GCC and SMP problems)

Posted: Thu Dec 03, 2009 5:19 pm
by earlz
Darwish wrote:
FlashBurn wrote:So, problems solved. You have to write the following and then it works:

Code: Select all

static struct smpMsg_t * volatile freeList
So maybe someone could say where should the volatile keyword stay? I always though that "volatile uint32t foo" is alright, isn´t it. Or is this only not right for pointers?
Volatiles are really subtle in C, and as seen by the ACM paper posted by dosfan above, many compilers get them wrong. For above coding case, I prefer the Linux way of handling the issue, namely minimizing 'volatile' as far as possible, and depending on compiler and/or cpu barriers as needed.

In above case, you can simply avoid volatile altogether, and use the gcc barrier "memory". As said by its manual, the memory barrier "will cause GCC to not keep memory values cached in registers across the assembler instruction and not optimize stores or loads to that memory." So in above code, you can use:

Code: Select all

      while(likely(freeList == 0))
         asm volatile("pause": : :"memory");
and have peace.

In the risk of mimicking the linux kernel too much, you can create a cpu_relax() method, which abstracts the 'asm volatile("pause": :"memory")' part and use it in all your busy-loops. For further info check:
1- Linux kernel Documentation/volatiles-considered-harmful.txt
2- Linus's posts on volatile. Original patch, reply 1, and reply 2.

I would assume your not going to have any hope of compiling your kernel with anything but gcc then?

Re: "Volatile-considered harmful" (was:Re: GCC and SMP problems)

Posted: Thu Dec 03, 2009 6:55 pm
by Darwish
earlz wrote:I would assume your not going to have any hope of compiling your kernel with anything but gcc then?
Why? If the other compiler provides a compile-time memory barrier (and if it does aggressive reordering, it should), you can abstract this difference away in a macro inside cpu_relax() above.