Message ID | 1455782806-4787-3-git-send-email-christophe.milard@linaro.org |
---|---|
State | Superseded |
Headers | show |
On 02/18/16 11:06, Christophe Milard wrote: > section regarding shared memo added. > > Signed-off-by: Christophe Milard <christophe.milard@linaro.org> > Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org> > --- > doc/users-guide/users-guide.adoc | 129 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 129 insertions(+) > > diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc > index bbb53a7..d0eb7bc 100644 > --- a/doc/users-guide/users-guide.adoc > +++ b/doc/users-guide/users-guide.adoc > @@ -543,6 +543,135 @@ lookup. The lookup function is particularly useful to allow an ODP application > that is divided into multiple processes to obtain the handle for the common > resource. > > +== Shared memory > +=== Allocating shared memory > +Blocks of shared memory can be created using the +odp_shm_reserve()+ API > +call. The call expects a shared memory block name, a block size, an alignment > +requirement, and optional flags as parameters. It returns a +odp_shm_t+ > +handle. The size and alignment requirement are given in bytes. > + > +.creating a block of shared memory > +[source,c] > +---- > +#define ALIGNMENT 128 > +#define BLKNAME +shared_items+ "shared_items"? do you need this define at all? I think that is also understandable: shm = odp_shm_reserve("shm name", sizeof(shared_data_t), ALIGNMENT, 0); but the last argument I think it's better to write as flags. I.e.: uint32_t shm_flags = 0; shm = odp_shm_reserve("shm name", sizeof(shared_data_t), ALIGNMENT, shm_flags); > + > +odp_shm_t shm; > + > +typedef struct { > +... > +} shared_data_t; > + > +shm = odp_shm_reserve(BLKNAME, sizeof(shared_data_t), ALIGNMENT, 0); > +---- > + > +=== Getting the shared memory block address > +The returned odp_shm_t handle can then be used to retrieve the actual > +address (in the caller's ODP thread virtual address space) of the created > +shared memory block. > + > +.getting the address of a shared memory block > +[source,c] > +---- > +shared_data_t *shared_data; > +shared_data = odp_shm_addr(shm); > +---- > + > +The address returned by +odp_shm_addr()+ is valid only in the calling ODP > +thread space: odp_shm_t handles can be shared between ODP threads and remain > +valid within any threads, whereas the address returned by +odp_shm_addr(shm)+ > +may differ from ODP threads to ODP threads (for the same 'shm' block), and > +should therefore not be shared between ODP threads. > +For instance, it would be correct to send a shm handle using IPC between two > +ODP threads and let each of these thread do their own +odp_shm_addr()+ to > +get the block address. Directly sending the address returned by > ++odp_shm_addr()+ from one ODP thread to another would however possibly fail > +(the address may have no sense in the receiver address space). > + > +The address returned by +odp_shm_addr()+ is nevertheless guaranteed to be > +aligned according to the alignment requirements provided at block creation > +time, even if the call to +odp_shm_addr()+ is performed by a different ODP > +thread than the one which originally called +odp_shm_reserve()+. > + > +All shared memory blocks are contiguous in any ODP thread addressing space: > +'address' to 'address'\+'size' (where 'size' is the shared memory block size, > +as provided in the +odp_shm_reserve()+ call) is read and writeable and > +mapping the shared memory block. There is no fragmentation. > + > +=== Memory behaviour > +By default ODP threads are assumed to behave as cache coherent systems: > +Any change performed on a shared memory block is guaranteed to eventually > +become visible to other ODP threads sharing this memory block. > +(this behaviour may be altered by flags to +odp_shm_reserve()+ in the future). > +Nevertheless, there is no implicit memory barrier associated with any action > +on shared memories: *When* a change performed by an ODP thread becomes visible > +to another ODP thread is not known: An application using shared memory > +blocks has to use some memory barrier provided by ODP to guarantee shared data > +validity between ODP threads. > + > +=== Lookup by name > +As mentioned, shared memory handles can be sent from ODP threads to ODP > +threads using any IPC mechanism, and then the block address retrieved. > +A simpler approach to get the shared memory block handle of an already created > +block is to use the +odp_shm_lookup()+ API function call. > +This nevertheless requires the calling ODP thread to provide the name of the > +shared memory block: > ++odp_shm_lookup()+ will return +ODP_SHM_INVALID+ if no shared memory block > +with the provided name is known by ODP. > + > +.retrieving a block handle and address from another ODP task > +[source,c] > +---- > +#define BLKNAME 'shared_items' > + > +odp_shm_t shm; > +shared_data_t *shared_data; > + > +shm = odp_shm_lookup(BLKNAME); > +if (shm != ODP_SHM_INVALID) { > + shared_data = odp_shm_addr(shm); > + ... > +} > +---- > + > +=== Freeing memory > +Freeing shared memory is performed using the +odp_shm_free()+ API call. > ++odp_shm_free()+ takes one single argument, the shared memory block handle. > +Any ODP thread is allowed to perform a +odp_shm_free()+ on a shared memory > +block (i.e. the thread performing the +odp_shm_free()+ may be different > +from the thread which did the +odp_shm_reserve()+). Shared memory blocks should > +be freed only once, and once freed, a shared memory block should no longer > +be referenced by any ODP threads. > + > +.freeing a shared memory block > +[source,c] > +---- > +if (odp_shm_free(shm) != 0) { > + ...//handle error > +} > +---- > + > +=== Memory creation flags > +The last argument to odp_shm_reserve() is a set of ORed flags. > +Two flags are supported: > + > +==== ODP_SHM_PROC > +When this flag is given, the allocated shared memory will become visible > +outside ODP. Non ODP threads (e.g. usual linux process or linux threads) > +will be able to access the memory using native (non ODP) OS calls such as > +'shm_open()' and 'mmap' (for linux). > +Each ODP implementation should provide a description on exactly how > +this mapping should be done on that specific platform. > + > +==== ODP_SHM_SW_ONLY > +This flag tells ODP that the shared memory will be used by the ODP application > +software only: no HW (such as DMA, or other accelerator) will ever > +try to access the memory. No other ODP call will be involved on this memory > +(as ODP calls could implicitly involve HW, depending on the ODP > +implementation), except for +odp_shm_lookup()+ and +odp_shm_free()+. > +ODP implementations may use this flag as a hint for performance optimization, > +or may as well ignore this flag. > + > == Queues > Queues are the fundamental event sequencing mechanism provided by ODP and all > ODP applications make use of them either explicitly or implicitly. Queues are
On 18 February 2016 at 09:29, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > On 02/18/16 11:06, Christophe Milard wrote: > >> section regarding shared memo added. >> >> Signed-off-by: Christophe Milard <christophe.milard@linaro.org> >> Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org> >> --- >> doc/users-guide/users-guide.adoc | 129 >> +++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 129 insertions(+) >> >> diff --git a/doc/users-guide/users-guide.adoc >> b/doc/users-guide/users-guide.adoc >> index bbb53a7..d0eb7bc 100644 >> --- a/doc/users-guide/users-guide.adoc >> +++ b/doc/users-guide/users-guide.adoc >> @@ -543,6 +543,135 @@ lookup. The lookup function is particularly useful >> to allow an ODP application >> that is divided into multiple processes to obtain the handle for the >> common >> resource. >> +== Shared memory >> +=== Allocating shared memory >> +Blocks of shared memory can be created using the +odp_shm_reserve()+ API >> +call. The call expects a shared memory block name, a block size, an >> alignment >> +requirement, and optional flags as parameters. It returns a +odp_shm_t+ >> +handle. The size and alignment requirement are given in bytes. >> + >> +.creating a block of shared memory >> +[source,c] >> +---- >> +#define ALIGNMENT 128 >> +#define BLKNAME +shared_items+ >> > > "shared_items"? > > do you need this define at all? I think that is also understandable: > > shm = odp_shm_reserve("shm name", sizeof(shared_data_t), ALIGNMENT, 0); > I don't agree as the same name is used in the odp_shm_lookup() later on. Yes, the macro is redefined there as well (so that the example is complete), but I do think it make sense to keep the macro when multiple refs are done to the same string. > but the last argument I think it's better to write as flags. I.e.: > > uint32_t shm_flags = 0; > > shm = odp_shm_reserve("shm name", sizeof(shared_data_t), ALIGNMENT, > shm_flags); You are right. will be in v3. Christophe. > > > > > + >> +odp_shm_t shm; >> + >> +typedef struct { >> +... >> +} shared_data_t; >> + >> +shm = odp_shm_reserve(BLKNAME, sizeof(shared_data_t), ALIGNMENT, 0); >> +---- >> + >> +=== Getting the shared memory block address >> +The returned odp_shm_t handle can then be used to retrieve the actual >> +address (in the caller's ODP thread virtual address space) of the created >> +shared memory block. >> + >> +.getting the address of a shared memory block >> +[source,c] >> +---- >> +shared_data_t *shared_data; >> +shared_data = odp_shm_addr(shm); >> +---- >> + >> +The address returned by +odp_shm_addr()+ is valid only in the calling ODP >> +thread space: odp_shm_t handles can be shared between ODP threads and >> remain >> +valid within any threads, whereas the address returned by >> +odp_shm_addr(shm)+ >> +may differ from ODP threads to ODP threads (for the same 'shm' block), >> and >> +should therefore not be shared between ODP threads. >> +For instance, it would be correct to send a shm handle using IPC between >> two >> +ODP threads and let each of these thread do their own +odp_shm_addr()+ to >> +get the block address. Directly sending the address returned by >> ++odp_shm_addr()+ from one ODP thread to another would however possibly >> fail >> +(the address may have no sense in the receiver address space). >> + >> +The address returned by +odp_shm_addr()+ is nevertheless guaranteed to be >> +aligned according to the alignment requirements provided at block >> creation >> +time, even if the call to +odp_shm_addr()+ is performed by a different >> ODP >> +thread than the one which originally called +odp_shm_reserve()+. >> + >> +All shared memory blocks are contiguous in any ODP thread addressing >> space: >> +'address' to 'address'\+'size' (where 'size' is the shared memory block >> size, >> +as provided in the +odp_shm_reserve()+ call) is read and writeable and >> +mapping the shared memory block. There is no fragmentation. >> + >> +=== Memory behaviour >> +By default ODP threads are assumed to behave as cache coherent systems: >> +Any change performed on a shared memory block is guaranteed to eventually >> +become visible to other ODP threads sharing this memory block. >> +(this behaviour may be altered by flags to +odp_shm_reserve()+ in the >> future). >> +Nevertheless, there is no implicit memory barrier associated with any >> action >> +on shared memories: *When* a change performed by an ODP thread becomes >> visible >> +to another ODP thread is not known: An application using shared memory >> +blocks has to use some memory barrier provided by ODP to guarantee >> shared data >> +validity between ODP threads. >> + >> +=== Lookup by name >> +As mentioned, shared memory handles can be sent from ODP threads to ODP >> +threads using any IPC mechanism, and then the block address retrieved. >> +A simpler approach to get the shared memory block handle of an already >> created >> +block is to use the +odp_shm_lookup()+ API function call. >> +This nevertheless requires the calling ODP thread to provide the name of >> the >> +shared memory block: >> ++odp_shm_lookup()+ will return +ODP_SHM_INVALID+ if no shared memory >> block >> +with the provided name is known by ODP. >> + >> +.retrieving a block handle and address from another ODP task >> +[source,c] >> +---- >> +#define BLKNAME 'shared_items' >> + >> +odp_shm_t shm; >> +shared_data_t *shared_data; >> + >> +shm = odp_shm_lookup(BLKNAME); >> +if (shm != ODP_SHM_INVALID) { >> + shared_data = odp_shm_addr(shm); >> + ... >> +} >> +---- >> + >> +=== Freeing memory >> +Freeing shared memory is performed using the +odp_shm_free()+ API call. >> ++odp_shm_free()+ takes one single argument, the shared memory block >> handle. >> +Any ODP thread is allowed to perform a +odp_shm_free()+ on a shared >> memory >> +block (i.e. the thread performing the +odp_shm_free()+ may be different >> +from the thread which did the +odp_shm_reserve()+). Shared memory blocks >> should >> +be freed only once, and once freed, a shared memory block should no >> longer >> +be referenced by any ODP threads. >> + >> +.freeing a shared memory block >> +[source,c] >> +---- >> +if (odp_shm_free(shm) != 0) { >> + ...//handle error >> +} >> +---- >> + >> +=== Memory creation flags >> +The last argument to odp_shm_reserve() is a set of ORed flags. >> +Two flags are supported: >> + >> +==== ODP_SHM_PROC >> +When this flag is given, the allocated shared memory will become visible >> +outside ODP. Non ODP threads (e.g. usual linux process or linux threads) >> +will be able to access the memory using native (non ODP) OS calls such as >> +'shm_open()' and 'mmap' (for linux). >> +Each ODP implementation should provide a description on exactly how >> +this mapping should be done on that specific platform. >> + >> +==== ODP_SHM_SW_ONLY >> +This flag tells ODP that the shared memory will be used by the ODP >> application >> +software only: no HW (such as DMA, or other accelerator) will ever >> +try to access the memory. No other ODP call will be involved on this >> memory >> +(as ODP calls could implicitly involve HW, depending on the ODP >> +implementation), except for +odp_shm_lookup()+ and +odp_shm_free()+. >> +ODP implementations may use this flag as a hint for performance >> optimization, >> +or may as well ignore this flag. >> + >> == Queues >> Queues are the fundamental event sequencing mechanism provided by ODP >> and all >> ODP applications make use of them either explicitly or implicitly. >> Queues are >> > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/lng-odp >
diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index bbb53a7..d0eb7bc 100644 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -543,6 +543,135 @@ lookup. The lookup function is particularly useful to allow an ODP application that is divided into multiple processes to obtain the handle for the common resource. +== Shared memory +=== Allocating shared memory +Blocks of shared memory can be created using the +odp_shm_reserve()+ API +call. The call expects a shared memory block name, a block size, an alignment +requirement, and optional flags as parameters. It returns a +odp_shm_t+ +handle. The size and alignment requirement are given in bytes. + +.creating a block of shared memory +[source,c] +---- +#define ALIGNMENT 128 +#define BLKNAME +shared_items+ + +odp_shm_t shm; + +typedef struct { +... +} shared_data_t; + +shm = odp_shm_reserve(BLKNAME, sizeof(shared_data_t), ALIGNMENT, 0); +---- + +=== Getting the shared memory block address +The returned odp_shm_t handle can then be used to retrieve the actual +address (in the caller's ODP thread virtual address space) of the created +shared memory block. + +.getting the address of a shared memory block +[source,c] +---- +shared_data_t *shared_data; +shared_data = odp_shm_addr(shm); +---- + +The address returned by +odp_shm_addr()+ is valid only in the calling ODP +thread space: odp_shm_t handles can be shared between ODP threads and remain +valid within any threads, whereas the address returned by +odp_shm_addr(shm)+ +may differ from ODP threads to ODP threads (for the same 'shm' block), and +should therefore not be shared between ODP threads. +For instance, it would be correct to send a shm handle using IPC between two +ODP threads and let each of these thread do their own +odp_shm_addr()+ to +get the block address. Directly sending the address returned by ++odp_shm_addr()+ from one ODP thread to another would however possibly fail +(the address may have no sense in the receiver address space). + +The address returned by +odp_shm_addr()+ is nevertheless guaranteed to be +aligned according to the alignment requirements provided at block creation +time, even if the call to +odp_shm_addr()+ is performed by a different ODP +thread than the one which originally called +odp_shm_reserve()+. + +All shared memory blocks are contiguous in any ODP thread addressing space: +'address' to 'address'\+'size' (where 'size' is the shared memory block size, +as provided in the +odp_shm_reserve()+ call) is read and writeable and +mapping the shared memory block. There is no fragmentation. + +=== Memory behaviour +By default ODP threads are assumed to behave as cache coherent systems: +Any change performed on a shared memory block is guaranteed to eventually +become visible to other ODP threads sharing this memory block. +(this behaviour may be altered by flags to +odp_shm_reserve()+ in the future). +Nevertheless, there is no implicit memory barrier associated with any action +on shared memories: *When* a change performed by an ODP thread becomes visible +to another ODP thread is not known: An application using shared memory +blocks has to use some memory barrier provided by ODP to guarantee shared data +validity between ODP threads. + +=== Lookup by name +As mentioned, shared memory handles can be sent from ODP threads to ODP +threads using any IPC mechanism, and then the block address retrieved. +A simpler approach to get the shared memory block handle of an already created +block is to use the +odp_shm_lookup()+ API function call. +This nevertheless requires the calling ODP thread to provide the name of the +shared memory block: ++odp_shm_lookup()+ will return +ODP_SHM_INVALID+ if no shared memory block +with the provided name is known by ODP. + +.retrieving a block handle and address from another ODP task +[source,c] +---- +#define BLKNAME 'shared_items' + +odp_shm_t shm; +shared_data_t *shared_data; + +shm = odp_shm_lookup(BLKNAME); +if (shm != ODP_SHM_INVALID) { + shared_data = odp_shm_addr(shm); + ... +} +---- + +=== Freeing memory +Freeing shared memory is performed using the +odp_shm_free()+ API call. ++odp_shm_free()+ takes one single argument, the shared memory block handle. +Any ODP thread is allowed to perform a +odp_shm_free()+ on a shared memory +block (i.e. the thread performing the +odp_shm_free()+ may be different +from the thread which did the +odp_shm_reserve()+). Shared memory blocks should +be freed only once, and once freed, a shared memory block should no longer +be referenced by any ODP threads. + +.freeing a shared memory block +[source,c] +---- +if (odp_shm_free(shm) != 0) { + ...//handle error +} +---- + +=== Memory creation flags +The last argument to odp_shm_reserve() is a set of ORed flags. +Two flags are supported: + +==== ODP_SHM_PROC +When this flag is given, the allocated shared memory will become visible +outside ODP. Non ODP threads (e.g. usual linux process or linux threads) +will be able to access the memory using native (non ODP) OS calls such as +'shm_open()' and 'mmap' (for linux). +Each ODP implementation should provide a description on exactly how +this mapping should be done on that specific platform. + +==== ODP_SHM_SW_ONLY +This flag tells ODP that the shared memory will be used by the ODP application +software only: no HW (such as DMA, or other accelerator) will ever +try to access the memory. No other ODP call will be involved on this memory +(as ODP calls could implicitly involve HW, depending on the ODP +implementation), except for +odp_shm_lookup()+ and +odp_shm_free()+. +ODP implementations may use this flag as a hint for performance optimization, +or may as well ignore this flag. + == Queues Queues are the fundamental event sequencing mechanism provided by ODP and all ODP applications make use of them either explicitly or implicitly. Queues are
section regarding shared memo added. Signed-off-by: Christophe Milard <christophe.milard@linaro.org> Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org> --- doc/users-guide/users-guide.adoc | 129 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)