Global Variables

Non-technical related questions should go here.
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Global Variables

Post by rubenc »

How are the Global variables implemented?

Can a global variable be accessed by different cores?

ex:
on core[0] : EthernetApp();
on core[1] : UartApp();


-- Ethernet App.xc
sometypearray Variable1

-- UartApp.c
external sometypearray Variable1


Both apps are working propperly however each one is accessing its own variable? or they use the same ( memory sharing? )

Any ideas?
Thankyou!
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

You cannot access a global variables from one core to another. The memory spaces of each core is strictly separated.
Global variables in XC are quite restrictive: sharing global variables between multiple threads is mostly not possible to avoid typical concurrency problems. If you program the threads in C you should be able to share globals between threads. You can use hardware locks to mutually exclude multiple threads from accessing a global at the same time. In any case XMOS advertises to use channels for inter-thread communication instead of shared memory.
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

Bianco wrote:You cannot access a global variables from one core to another. The memory spaces of each core is strictly separated..
Shouldnt it throw in this case an error the linker?
one thread is accesing a variable declared external which is nowhere declared.
It is declared but in another core.
Bianco wrote: Global variables in XC are quite restrictive: sharing global variables between multiple threads is mostly not possible to avoid typical concurrency problems. If you program the threads in C you should be able to share globals between threads. You can use hardware locks to mutually exclude multiple threads from accessing a global at the same time. In any case XMOS advertises to use channels for inter-thread communication instead of shared memory.
If I use channels, i will be able to use it for inter-thread communicatio. but will it also work for inter-core communication?

I cant run both codes on the same core.

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

Post by Interactive_Matter »

With channels there is no real difference between communicating in one core or between two cores.
The only real difference is that there are just a number of channels between the different cores. So if you have too much inter-core communication the linker will notify you.

You can even reconfigure threads easily to run on other cores without changing the pgramming (except for main.xc). If you do not need specific pins, which are mapped to a core.

I can only second the argument to move from a shared array to channels - it is much easier and more robust.
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

Interactive_Matter wrote: I can only second the argument to move from a shared array to channels - it is much easier and more robust.
Ok thankyou! Now I have implemented the channels, but now I have another problem. I will explain the application I hope you can help me solve this.

Use of "myVariable" violates the parallel usage rules.

I have read the doc and verify the rules and I even found this
Programing XC on Xmos Devices.pdf wrote:"a group of threads can have shared read-only access to a variable, but only a single thread can have exclusive read-write access to a variable. "
This is what I am trying to achieve but still something is wrong :-(

Core0 is handling some comunication and I modify it so that trough channels now the information is sent to the Core1 ( New )
But now in Core1. I have Thread0 which needs to read and write to myVariable. ( which is in Core 1 defined as global)
in another file I am defining what will run as Thread1 in the same core. (myVariable as external global)
Thread1 only reads myVariable.

As I see it TH0 has the rw exclusivity and TH1 the read-only therefore no rules are been broken isnt it?

still I get the error.
any ideas?
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

Unfortunately: Nope.

I had the same problems myself (I am more a user of XC than an in depth expert). But I was never able to use shared variables.

But from a computer scientist point of view (you now getting abit strict on software design here) I can only encourage to use channels to remove the global variables alltogether. If you need information from the other thread simply ask the thread for the value of the variable. This may be some ticks slower but on the other hand your threads are much more flexible since you the reading thread has no information of how the writing thread comes up with the value of the variable. It makes no assumptions about the outside world, just that it has somebody to ask for the specified value.

I stress that pint since I noticed that XC is really cool in that regard. If you have ever heard of 'inversion of control' this is exactly what XC does:
The threads are defining services they need or provide (this is the messages they send over the channels, unfortunately there is no specification for this it is just in the code and/or documentation - a topic that has to be addressed ;) )
The main routine configures and connects the thread so taht every thread has the resources and services it needs - no matter where they come from.

If you think it sounds a bit academic, it is true. But sticking to those patterns helped me a lot to write more reusbale code with much less problems.

Marcus
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

I think I might find out why

Thread0 acces it as: (read only)
payload = Data_Globald.Nr[Nr].PortNo[TxPortNr].Word[j];

Thread1 the only trhead with (read-write) access
Data_Globald.Nr[rqst.nr].PortNo[rqst.ports].Word[rqst.word] = rqst.value;

Since the acces to the global variable is depending on other variables, It seems that the compiler is trying to protect the case when a read and a write can occurr at the same time in the case that
Th0 Th1
Nr = rqst.nr
PortNr = rqst.ports
j = rqst.word
Programing Xmos Devices Page 32 wrote: In general, indexing an array by anything other than a constant value is treated as if
all elements in the array are accessed.

It seems that it is cold be solved by hardware locks. (mutex)
Does anyone knows how to use them?
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

I saw that by using constants it is working and that's somehow it gave me the idea that I have read that somewhere before.

but now I cant find where I have read about using of mutexes.
I would suggest a Tutorial about it ;-)
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

The application that I was trying to build is now running. A couple of tricks were needed but I would like to share some of them in the case that someone needs it.

I tried with the hardware locks and even if those might be usefull depending on the implementation, it was not exactly that the solution.

I found it by diving on the ethernet_module from the sc_ethernet project (on git), There I have read that some internal trheads are comunicating by shared memory. Therefore that means that it is possible.

I was reading the code to understand how it was implemented. I will mention the files where you can find it in the case that someone wants to see it by themselves.

on ethernet_server.xc
// These thrads all communicate internally via shared memory
mii_rx_pins(m.p_mii_rxdv, m.p_mii_rxd, 0, c);
mii_tx_pins(m.p_mii_txd, 0);
ethernet_rx_server(rx, num_rx);

mii.xc and ethernet_tx_Server.xc
are the files that comunicate internally, trough a global variable called buf[]

The trick is that since XC does not supports pointers. a dummy file (maybe not so dummy, infact a clever file) needs to be used in order to "WRAP" the functions.

that is the reason why mii_wrapers.c file exists.
that file is passing the pointer of the variable to both of the .xc files and since it is a .c file it is allowed and works :D

Summary: Global Variables ( prefferably arrays ) need to be wraped in a .c file in order to share the memory among two or more threads in .xc files.

I would be glad to explain or provide more info in the case that someone needs it.

Have a nice day!
User avatar
phalt
Respected Member
Posts: 298
Joined: Thu May 12, 2011 11:14 am

Post by phalt »

Did you create a tutorial in the tutorial wiki for anyone who might encounter this problem again?