strange loop behavior

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

strange loop behavior

Post by woodsb »

Hello,

This problem is so bizarre I thought not to post here as I must be doing something obviously wrong, although I cannot myself figure out what.

I have a "for" loop that erroneously never ends when an array variable of type "mic_array_frame_time_domain" is accessed inside the loop. When I comment out the variable's access the loop ends as expected. I can also force the loop to end by putting a test of the index inside the loop and breaking on the desired index value. I can access and modfiy other variables in the loop with no problem.

This is occurring in code I have based on the low resolution delay example (AN00219), modified to work with different hardware and different parameters. The basic problem looks as follows (with "nSamp" the index and "current" the variable showing the bizarre behavior):

Code: Select all

       
         while(1)
        {
            mic_array_frame_time_domain *  current =   mic_array_get_next_time_domain_frame(c_ds_output, DECIMATOR_COUNT, buffer, audio, dc);
            for(uint8_t nMic = 0; nMic < MIC_ARRAY_NUM_MICS; nMic++)
            {
                for(uint8_t nSamp = 0; nSamp < (uint8_t)FRAME_SIZE; nSamp++)
                {
                    c_audio <: current->data[nMic][nSamp];  // send the audio data out over the channel.
                }
             }
        }
// etc. ...
The problem doesn't matter how the offending variable is used. For example, copying the variable to another variable or incrementing the variable's value will also cause the loop to run longer than expected, although in the latter case the loop stops when a memory access exception is thrown (albeit with the index far beyond the intended stop value).

This is running in a region marked unsafe.

My flag settings are XCC_FLAGS = -O2 -g -report.

The variable is typedef-ed in lib_mic_array.h:

Code: Select all

typedef struct {
    long long alignment; 		/**<Used to force double work alignment. */
#if MIC_ARRAY_WORD_LENGTH_SHORT
    int16_t data[MIC_ARRAY_NUM_MICS][1<<MIC_ARRAY_MAX_FRAME_SIZE_LOG2];/**< Raw audio data*/
#else
    int32_t data[MIC_ARRAY_NUM_MICS][1<<MIC_ARRAY_MAX_FRAME_SIZE_LOG2];/**< Raw audio data*/
#endif
    mic_array_metadata_t metadata[(MIC_ARRAY_NUM_MICS+3)/4]; /**< Frame metadata*/
} mic_array_frame_time_domain;
I know there are other ways to exchange data as I need to do, but either something's horribly wrong or I fundamentally don't understand something (probably the latter) and I believe there's something for me to learn here.

I would be grateful if anyone could suggest something to pursue.

Sincerely,
Bill


woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Hello again,

A bit more info on this strange loop problem. I forgot to say that the "FRAME_SIZE" used is 128, which is less than the max a uint8_t is supposed to be able to hold, so that should not be the root of the problem.

I have found, however, that the problem goes away if I use "unsigned" instead of "uint8_t" for the loop counter. While I can move forward on the coding, it is still a mystery to me why the problem exists at all, and prompts me to wonder if I need to change every use of "uint8_t" to "unsigned".

cheers,
Bill
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Hi Bill. Not sure of the root cause of your issue but you could consider to use the real-time printf to possible debug this for-loop:

https://www.xmos.com/developer/download ... 1093A).pdf

Print out the value of nSamp for each iteration to determine if there is a fault or code / compiler bug. If a compiler bug, please report it to XMOS using their ticket system on xmos.com.
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Thanks for the response, mon2. I printed out the nSamp value and it got up to 2060 before stopping. As a uint8_t, it shouldn't have grown beyond 255, of course, and the loop correctly ends at 127 when variable changed from uint8_t to unsigned.

Will look into posting a ticket.
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

With respect, an unsigned will be more efficient with the XCORE anyway I would think, since it's got a 32 bit ALU. So raising a ticket might be helpful but you might as well use unsigned.
Post Reply