Here I have the problem. I have four files, really, but I mimicked the structure here. I have moved millis_state_t my_millis = {0,0}; from inside one of the tasks to above main.
In my head your code should have caused the same violation.. Because the violation is correctly reported (in my head).
Code: Select all
// See http://www.xcore.com/viewtopic.php?f=26&t=6470&start=10
#include <stdio.h>
#include <xs1.h>
#include <iso646.h>
#include <timer.h> // delay_milliseconds(200), XS1_TIMER_HZ etc
typedef enum {false,true} bool;
#define DEBUG_PRINT_TEST 1
#define debug_print(fmt, ...) do { if(DEBUG_PRINT_TEST) printf(fmt, __VA_ARGS__); } while (0)
// ---- Would be in a header file ----
typedef struct millis_state_t {
unsigned long tick_hi;
unsigned long last_tick;
} millis_state_t;
millis_state_t millis_state; // "extern" or not makes no difference here, but I do need it in the header file
#define MILLIS() millis_p(millis_state)
// ---- Would be in a source file ----
unsigned long millis_p (millis_state_t &millis_state) {
timer tmr;
unsigned long long total_ticks;
unsigned long current_tick;
tmr :> current_tick;
if( current_tick < millis_state.last_tick ) {
++millis_state.tick_hi;
}
millis_state.last_tick = current_tick;
total_ticks = ((unsigned long long)millis_state.tick_hi << 32) | (unsigned long long)current_tick;
return (unsigned long)(total_ticks / (unsigned long long)XS1_TIMER_KHZ);
}
// ---- I actually have two files for two different tasks ----
unsigned digitalRead (void) {
delay_milliseconds (200);
return (0);
}
#define RF69_TX_LIMIT_MS 1000
#define TEST_TYPE unsigned long
void test_task (int task_num) {
TEST_TYPE millis_;
TEST_TYPE txStart;
unsigned testCnt = 0;
bool not_timed_out;
while (testCnt < 2000) {
txStart = MILLIS();
do {
millis_ = MILLIS();
not_timed_out = (millis_ - txStart) < RF69_TX_LIMIT_MS;
debug_print ("task %d: testCnt(%d), millis(%d), txStart(%d), millis_-txStart(%d), timedOut(%d)\n",
task_num, testCnt, millis_, txStart, millis_ - txStart, !not_timed_out);
delay_milliseconds(20);
} while ((digitalRead() == 0) && not_timed_out);
testCnt++;
}
}
// ---- In main.xc ----
millis_state_t my_millis = {0,0};
int main() {
par { // error: use of `millis_state' violates parallel usage rules
test_task(0);
test_task(1);
}
return 0;
}
Code: Select all
11:20:33 **** Incremental Build of configuration Default for project _xmos_issues ****
xmake CONFIG=Default all
Checking build modules
No build modules used.
Analyzing main.xc
Creating dependencies for main.xc
Compiling main.xc
Creating xmos_issues_nnnm.xe
../src/main.xc:1701:9: error: use of `millis_state' violates parallel usage rules
par { // error: use of `millis_state' violates parallel usage rules
^~~
../src/main.xc:1684:23: note: object used here
txStart = MILLIS();
^~~~~~~~
../src/main.xc:1649:31: note: expanded from here
#define MILLIS() millis_p(millis_state)
^~~~~~~~~~~~
../src/main.xc:1684:23: note: object used here
txStart = MILLIS();
^~~~~~~~
../src/main.xc:1649:31: note: expanded from here
#define MILLIS() millis_p(millis_state)
^~~~~~~~~~~~
xmake[1]: *** [bin//xmos_issues_nnnm.xe] Error 1
xmake: *** [bin//xmos_issues_nnnm.xe] Error 2
11:20:34 Build Finished (took 863ms)
Update: It's the same task that's instantiated twice. And when it contains the global instatiation it incorrectly (?) does not report the violation?