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!
Global Variables
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
-
- XCore Expert
- Posts: 754
- Joined: Thu Dec 10, 2009 6:56 pm
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.
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.
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
Shouldnt it throw in this case an error the linker?Bianco wrote:You cannot access a global variables from one core to another. The memory spaces of each core is strictly separated..
one thread is accesing a variable declared external which is nowhere declared.
It is declared but in another core.
If I use channels, i will be able to use it for inter-thread communicatio. but will it also work for inter-core communication?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.
I cant run both codes on the same core.
Thanks Bianco
-
- XCore Addict
- Posts: 216
- Joined: Wed Feb 10, 2010 10:26 am
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.
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.
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
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.Interactive_Matter wrote: I can only second the argument to move from a shared array to channels - it is much easier and more robust.
Use of "myVariable" violates the parallel usage rules.
I have read the doc and verify the rules and I even found this
This is what I am trying to achieve but still something is wrong :-(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. "
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?
-
- XCore Addict
- Posts: 216
- Joined: Wed Feb 10, 2010 10:26 am
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
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
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
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
It seems that it is cold be solved by hardware locks. (mutex)
Does anyone knows how to use them?
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?
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
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 ;-)
but now I cant find where I have read about using of mutexes.
I would suggest a Tutorial about it ;-)
-
- Active Member
- Posts: 40
- Joined: Fri Jul 22, 2011 2:31 pm
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!
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!
-
- Respected Member
- Posts: 298
- Joined: Thu May 12, 2011 11:14 am
Did you create a tutorial in the tutorial wiki for anyone who might encounter this problem again?