In the previous implementation, the direct use of Adi_acquire_lock to implement the Spinlock, when the cache is not enabled, there is no problem, but after the Icache enabled, there will be a dead loop.
The implementation of the Adi_acquire_lock in VDSP5 is in the Ccblkfn.h file, as follows:
#pragma inline
#pragma always_inline
static void adi_acquire_lock(testset_t *_t) {
int tVal;
csync();
#ifdef __WORKAROUND_L2_TESTSET_STALL
tVal = __builtin_testset_05000248((char *) _t);
#else
tVal = __builtin_testset((char *) _t);
#endif
while (tVal == 0) {
csync();
#ifdef __WORKAROUND_L2_TESTSET_STALL
tVal = __builtin_testset_05000248((char *) _t);
#else
tVal = __builtin_testset((char *) _t);
#endif
}
}
Check out the __workaround_l2_testset_stall in the VDSP5 document, which is described as follows:
The enables workaround for the anomaly 05-00-0248: Testset operation causes to the other core. The avoidance is enforced by the compiler automatically issuing a write to a l2-defined variable immediately following a Testset instruction. This is the code generated to a __builtin_testset () call.
The compiler defines the macro __workaround_l2_testset_stall at the compile, assembly, and link builds stages when this WOR Karound is enabled.
Check again visualdsp++ Silicon Anomaly Support, a further description of Anomaly 05-00-0248:
Anomaly ID |
Summary |
05-00-0248 |
Testset operation causes core stall (Dual-core). |
Compiler |
-workaround l2-testset-stall |
-d__workaround_l2_testset_stall |
in Dual-core Blackfins, when one core performs a testset operation to internal L2, it memory out of the other core if The latter is accessing L2 memory in the same time. The solution to the. Testset operation to internal L2 memory the should are followed immediately by a write to L2 m Emory. The compiler automatically works around this anomaly, so and any call to __builtin_testset () would contain the appropriate Write to L2 memory. |
|
Assembler |
No assembler actions. |
Libraries |
No Runtime Library actions. |
Take a further look at the assembly code for __build_in_testset ():
P1 = [FP + -40];
P0.L = 0x2C;
P0.H = 0xfeb0;
TESTSET (P1);
[P0] = P0;
When cache is not enabled, this code has no problems, but when cache is enabled, when the PC pointer points to Testset (P1), before execution, [P1] points to the content has become 0x80 (the cause of the assembly line), and then execute the Testset, Of course the return value of 0, so caused by the adi_acquire_lock after the death cycle!