* Force consecutive operation when using asm volatile macro
@ 2008-10-06 13:01 Jari Kuusisto
2008-10-07 4:26 ` Ian Lance Taylor
0 siblings, 1 reply; 8+ messages in thread
From: Jari Kuusisto @ 2008-10-06 13:01 UTC (permalink / raw)
To: gcc-help
Hello,
I've successfully updated gcc 2.95.3 to 4.3.2 (made necessary syntax
changes to code etc.).
With GCC 2.95.3 I've used a critical section asm volatile macro to enter
and exit critical sections in the code. When entering critical section,
there are two asm volatile lines needed. On critical section exit only
one asm volatile line is required.
After upgrading from gcc 2.95.3 to 4.3.2 the critical section handling
in the code stopped working. It seems that some of the code that should
be in critical section seems to be relocated outside the critical
section. I do know that asm volatile does not guarantee consecutive
execution of the code. I also know that using singe asm would fix this
problem, but in my case it is not possible.
I've managed to to get around this problem by replacing the critical
section macros with assembler functions as the blr instruction forces
the correct consecutive operation when entering and exiting critical
section. However, this function call type implementation seems to
significantly slow down runtime operation of the software. The result is
that the performance improvement gained with new gcc optimizations is
waisted due to this function call type implementation.
If I enable all other optimizations from -O2 but not the
-freorder-blocks the code is working with the old asm volatile macros,
but this is not an option.
Is there any other way to force the consecutive operation of asm
volatile macros?
BR. Jari Kuusisto
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-06 13:01 Force consecutive operation when using asm volatile macro Jari Kuusisto
@ 2008-10-07 4:26 ` Ian Lance Taylor
2008-10-07 4:43 ` Jari Kuusisto
0 siblings, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2008-10-07 4:26 UTC (permalink / raw)
To: Jari Kuusisto; +Cc: gcc-help
Jari Kuusisto <jari.h.kuusisto@gmail.com> writes:
> After upgrading from gcc 2.95.3 to 4.3.2 the critical section handling
> in the code stopped working. It seems that some of the code that
> should be in critical section seems to be relocated outside the
> critical section. I do know that asm volatile does not guarantee
> consecutive execution of the code. I also know that using singe asm
> would fix this problem, but in my case it is not possible.
>
> I've managed to to get around this problem by replacing the critical
> section macros with assembler functions as the blr instruction forces
> the correct consecutive operation when entering and exiting critical
> section. However, this function call type implementation seems to
> significantly slow down runtime operation of the software. The result
> is that the performance improvement gained with new gcc optimizations
> is waisted due to this function call type implementation.
>
> If I enable all other optimizations from -O2 but not the
> -freorder-blocks the code is working with the old asm volatile macros,
> but this is not an option.
>
> Is there any other way to force the consecutive operation of asm
> volatile macros?
You're going to have to show us the code.
Ian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 4:26 ` Ian Lance Taylor
@ 2008-10-07 4:43 ` Jari Kuusisto
2008-10-07 4:52 ` Ian Lance Taylor
0 siblings, 1 reply; 8+ messages in thread
From: Jari Kuusisto @ 2008-10-07 4:43 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
Hello Ian,
Here's an example function from uC/OS where the critical section asm
macro code seems not to work as expected (but with critical section
function it works).
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate
storage for CPU status register */
OS_CPU_SR cpu_sr;
cpu_sr = 0; /* Prevent
compiler warning */
#endif
if (OSIntNesting > 0) { /* See if called
from ISR ... */
*err = OS_ERR_PEND_ISR; /* ... can't PEND
from an ISR */
return;
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate
'pevent' */
*err = OS_ERR_PEVENT_NULL;
return;
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event
block type */
*err = OS_ERR_EVENT_TYPE;
return;
}
OS_ENTER_CRITICAL();
if (pevent->OSEventCnt > 0) { /* If sem. is
positive, resource available ... */
pevent->OSEventCnt--; /* ... decrement
semaphore only if positive. */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return;
}
/* Otherwise, must
wait until event occurs */
OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not
available, pend on semaphore */
OSTCBCur->OSTCBPendTO = FALSE;
OSTCBCur->OSTCBDly = timeout; /* Store pend
timeout in TCB */
OS_EventTaskWait(pevent); /* Suspend task
until event or timeout occurs */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next
highest priority task ready */
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBPendTO == TRUE) { /* See if we
timedout */
OS_EventTO(pevent);
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* Indicate that
didn't get event within TO */
return;
}
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
INT8U OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate
storage for CPU status register */
OS_CPU_SR cpu_sr;
cpu_sr = 0; /* Prevent
compiler warning */
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate
'pevent' */
return (OS_ERR_PEVENT_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate
event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00) { /* See if
any task waiting for semaphore*/
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready
HPT waiting on event */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find
HPT ready to run */
return (OS_NO_ERR);
}
if (pevent->OSEventCnt < 65535u) { /* Make sure
semaphore will not overflow */
pevent->OSEventCnt++; /* Increment
semaphore count to register event */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL(); /* Semaphore value
has reached its maximum */
return (OS_SEM_OVF);
}
With this asm macro implementation the semaphore handling is not working
with new GCC version:
#define OS_ENTER_CRITICAL() asm volatile("mfmsr
%0":"=r"(cpu_sr));asm volatile("mtspr 81,r0")
#define OS_EXIT_CRITICAL() asm volatile("mtmsr %0"::"r"(cpu_sr))
But when using function-type implementation for critical section
enter/exit, the semaphore handling works as expected:
h-file:
void OSEnterCriticalFunc(OS_CPU_SR *cpu_sr);
void OSExitCriticalFunc(OS_CPU_SR *cpu_sr);
#define OS_ENTER_CRITICAL() ( OSEnterCriticalFunc( &cpu_sr ) )
#define OS_EXIT_CRITICAL() ( OSExitCriticalFunc ( &cpu_sr ) )
c-file:
void OSEnterCriticalFunc(OS_CPU_SR *cpu_sr)
{
asm volatile("mfmsr %0":"=r"(*cpu_sr));
asm volatile("mtspr 81,r0");
}
void OSExitCriticalFunc(OS_CPU_SR *cpu_sr)
{
asm volatile("mtmsr %0"::"r"(*cpu_sr));
}
BR. Jari Kuusisto
Ian Lance Taylor wrote:
> Jari Kuusisto <jari.h.kuusisto@gmail.com> writes:
>
>
>> After upgrading from gcc 2.95.3 to 4.3.2 the critical section handling
>> in the code stopped working. It seems that some of the code that
>> should be in critical section seems to be relocated outside the
>> critical section. I do know that asm volatile does not guarantee
>> consecutive execution of the code. I also know that using singe asm
>> would fix this problem, but in my case it is not possible.
>>
>> I've managed to to get around this problem by replacing the critical
>> section macros with assembler functions as the blr instruction forces
>> the correct consecutive operation when entering and exiting critical
>> section. However, this function call type implementation seems to
>> significantly slow down runtime operation of the software. The result
>> is that the performance improvement gained with new gcc optimizations
>> is waisted due to this function call type implementation.
>>
>> If I enable all other optimizations from -O2 but not the
>> -freorder-blocks the code is working with the old asm volatile macros,
>> but this is not an option.
>>
>> Is there any other way to force the consecutive operation of asm
>> volatile macros?
>>
>
>
> You're going to have to show us the code.
>
> Ian
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 4:43 ` Jari Kuusisto
@ 2008-10-07 4:52 ` Ian Lance Taylor
2008-10-07 6:50 ` Jari Kuusisto
0 siblings, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2008-10-07 4:52 UTC (permalink / raw)
To: Jari Kuusisto; +Cc: gcc-help
Jari Kuusisto <jari.h.kuusisto@gmail.com> writes:
> Here's an example function from uC/OS where the critical section asm
> macro code seems not to work as expected (but with critical section
> function it works).
It might help to see how it fails. That said...
> #define OS_ENTER_CRITICAL() asm volatile("mfmsr
> %0":"=r"(cpu_sr));asm volatile("mtspr 81,r0")
> #define OS_EXIT_CRITICAL() asm volatile("mtmsr %0"::"r"(cpu_sr))
...there is nothing in these asm statements which tells the compiler
that it can't schedule instructions across them. The asm statements
say that the asm must not be deleted, but they don't say anything
about running before or after any other instructions.
Depending upon your requirements, it may suffice to simply say
asm volatile("mfmsr %" : "=r" : : "memory");
asm volatile("mtspr 81,r0" : : : "memory");
and
asm volatile("mtmsr %0" : : "r" (cpu_sr) : "memory");
Ian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 4:52 ` Ian Lance Taylor
@ 2008-10-07 6:50 ` Jari Kuusisto
2008-10-07 7:48 ` Andrew Haley
0 siblings, 1 reply; 8+ messages in thread
From: Jari Kuusisto @ 2008-10-07 6:50 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
Hi,
Ian Lance Taylor wrote:
> Jari Kuusisto <jari.h.kuusisto@gmail.com> writes:
>
>
>> Here's an example function from uC/OS where the critical section asm
>> macro code seems not to work as expected (but with critical section
>> function it works).
>>
>
> It might help to see how it fails. That said...
>
>
>> #define OS_ENTER_CRITICAL() asm volatile("mfmsr
>> %0":"=r"(cpu_sr));asm volatile("mtspr 81,r0")
>> #define OS_EXIT_CRITICAL() asm volatile("mtmsr %0"::"r"(cpu_sr))
>>
>
> ...there is nothing in these asm statements which tells the compiler
> that it can't schedule instructions across them. The asm statements
> say that the asm must not be deleted, but they don't say anything
> about running before or after any other instructions.
>
> Depending upon your requirements, it may suffice to simply say
> asm volatile("mfmsr %" : "=r" : : "memory");
> asm volatile("mtspr 81,r0" : : : "memory");
> and
> asm volatile("mtmsr %0" : : "r" (cpu_sr) : "memory");
>
> Ian
>
I've now tested this method, the exact macro lines are now:
#define OS_ENTER_CRITICAL() asm volatile("mfmsr %0":"=r"(cpu_sr) : :
"memory");asm volatile("mtspr 81,r0" : : : "memory")
#define OS_EXIT_CRITICAL() asm volatile("mtmsr %0"::"r"(cpu_sr) :
"memory")
An this solution seems to be working, and performance values were now
improved. Could you please explain to me what this "memory" section in
asm line actually does?
Thanks for your help!
BR. Jari
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 6:50 ` Jari Kuusisto
@ 2008-10-07 7:48 ` Andrew Haley
2008-10-07 10:25 ` Jari Kuusisto
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2008-10-07 7:48 UTC (permalink / raw)
To: Jari Kuusisto; +Cc: Ian Lance Taylor, gcc-help
Jari Kuusisto wrote:
>
> An this solution seems to be working, and performance values were now
> improved. Could you please explain to me what this "memory" section in
> asm line actually does?
Rather than asking Ian himself to explain it to you, please look in the docs.
It's called a memory clobber.
See 5.37 Assembler Instructions with C Expression Operands
Andrew.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 7:48 ` Andrew Haley
@ 2008-10-07 10:25 ` Jari Kuusisto
2008-10-07 12:19 ` Andrew Haley
0 siblings, 1 reply; 8+ messages in thread
From: Jari Kuusisto @ 2008-10-07 10:25 UTC (permalink / raw)
To: Andrew Haley; +Cc: Ian Lance Taylor, gcc-help
Hi,
Andrew Haley wrote:
> Jari Kuusisto wrote:
>
>
>> An this solution seems to be working, and performance values were now
>> improved. Could you please explain to me what this "memory" section in
>> asm line actually does?
>>
>
> Rather than asking Ian himself to explain it to you, please look in the docs.
> It's called a memory clobber.
>
> See 5.37 Assembler Instructions with C Expression Operands
>
> Andrew.
>
I've read that documentation couple of times before but did not notice
that memory clobber there before. Now that I know the feature I should
use, I of course found the definition from the documentation.
But I still ain't exactly sure what the memory clobber actually does,
but I assume that it prevents reordering code blocks before and after
the specific asm command because it declares access to memory in an
unpredictable fashion and GCC cannot move code blocks because of that.
Thanks for your help!
BR. Jari K.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Force consecutive operation when using asm volatile macro
2008-10-07 10:25 ` Jari Kuusisto
@ 2008-10-07 12:19 ` Andrew Haley
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Haley @ 2008-10-07 12:19 UTC (permalink / raw)
To: Jari Kuusisto; +Cc: Ian Lance Taylor, gcc-help
Jari Kuusisto wrote:
>
> But I still ain't exactly sure what the memory clobber actually does,
> but I assume that it prevents reordering code blocks before and after
> the specific asm command because it declares access to memory in an
> unpredictable fashion and GCC cannot move code blocks because of that.
That is what it does. It tells gcc that every memory operand is changed
by this asm statement.
Andrew.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-10-07 12:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-06 13:01 Force consecutive operation when using asm volatile macro Jari Kuusisto
2008-10-07 4:26 ` Ian Lance Taylor
2008-10-07 4:43 ` Jari Kuusisto
2008-10-07 4:52 ` Ian Lance Taylor
2008-10-07 6:50 ` Jari Kuusisto
2008-10-07 7:48 ` Andrew Haley
2008-10-07 10:25 ` Jari Kuusisto
2008-10-07 12:19 ` Andrew Haley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).