Global Variables

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Global Variables

Post by TSC »

My application requires the use of global variables, i.e. variables declared outside of a function, accessible by multiple functions.

They will be accessed only by one thread, so no memory sharing is happening, and this part is written in XC. All functions concerned with the global variables are in the same .xc file. I am trying to use an array of structs, but I can't even get something like an int to have persistent state.

Code: Select all

static int numInterfaces;
static interface interfaceArray[20];       // interface refers to a struct
static interface testStruct;
Within the scope of a single function, I can store to and access the variables. The problem is, whether I use the static specifier or not, any changes appear to be wiped when I access the global variables from a different function.

I tried the extern specifier, but that gives me:
Error: Undefined reference to 'interfaceArray

Can anyone tell me what I need to do to make global variables work?


User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

In theory you do not need it. I think if you think about really hard you can easily replace the global array with channel communication (e.g. one thread to write and read the variable over channels).

But if you really need to go the way with global variables

Code: Select all

#pragma unsafe arrays
is your friend ;)
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

I'm not sure what your problem is with global variables in xc.

I just compiled this code:

Code: Select all

typedef struct {
	int a;
	int b;
} interface;

static int numInterfaces;
static interface interfaceArray[20];       // interface refers to a struct
static interface testStruct;

void setter()
{
	interfaceArray[3].a = 2;
}

int getter()
{
	return(interfaceArray[3].a);
}
In another function I call these like so:

Code: Select all

	int x;
	setter();
	x = getter();
	printf ("Interface[3].a = %d\n", x);
It compiles OK and prints the correct result:

Code: Select all

Interface[3].a = 2
So sharing variables betwwen functions in the same thread is quite OK.

If you were trying to share across functions in different threads then you would get the compiler error:
error: use of `interfaceArray' violates parallel usage rules

I have to disagree with Interactive_Matter. There is no need or sense in using channels to communicate between functions in the same thread. (Is that even possible?)
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

Heater wrote: I have to disagree with Interactive_Matter. There is no need or sense in using channels to communicate between functions in the same thread. (Is that even possible?)
You are right. I misinterpreted the question as 'using arrays in differen threads' - so ignore my answer for a single thread ;)
mculibrk
Active Member
Posts: 38
Joined: Tue Jul 13, 2010 2:57 pm

Post by mculibrk »

....but what if I want to access the global arrays/struct from different threads?
As I understand, the only way is to use "shared/global" variables is to "pass by reference" to thread functions. (the #pragma directive does not help) and this will only compile if both functions use const &variable.

Assume a "reader" and a "writter" thread.

Code: Select all


typedef struct {
   int a;
   int b;
} interface;

static int numInterfaces;
static interface interfaceArray[20];       // interface refers to a struct
static interface testStruct;

// if all thread functions do not have const the compiler complains about parallel usage!
void setter(const interface Arr[])
{
  // this won't compile because of assignment to constant variable, but as an idea
   Arr[3].a = 2;
}

void getter(const interface Arr[])
{
   printintln(Arr[3].a);
}


void main() {
  par {
      setter(Array);
      getter(Array);
}
}
So, what would be some elegant way to accomplish that in XC? ...or it's not possible?

I tried to define a thread local array and use some tricks to copy the reference pointer (passed as cost in thread function) to the local one - so the local array (which is actually a pointer, right?) should point to the shared (global) data...
I thought the CAST32 macro would help but it's not....

is there an (elegant?) way of doing that in XC? like this:

Code: Select all


void threadFunction(const someType globalArr[]) {
   someType localArr[1];

   // this obviously won't work
   localArr = globalArr;

   // I thought CAST32 would but...
   CAST32(localArr, globalArr);

}

regards,
mculibrk
}
User avatar
daveg
Member++
Posts: 28
Joined: Thu Dec 10, 2009 7:25 pm

Post by daveg »

mculibrk wrote:....but what if I want to access the global arrays/struct from different threads?
As I understand, the only way is to use "shared/global" variables is to "pass by reference" to thread functions. (the #pragma directive does not help) and this will only compile if both functions use const &variable.

Assume a "reader" and a "writter" thread.
XC doesn't allow shared memory like this, so the compiler will try its hardest to stop you from aliasing arrays in this way. This is why you can only pass it to both functions if it is const.

You'll need to use C if you want to read and write a global array across more than one thread (and do your own thread-safety via locking or transactions etc), or use channels for communication between the XC threads to a buffering thread (which is the only thread which does the reads and writes to the array).