diff mbox

[RFC] Platform specific definitions and inlines

Message ID 1415111362-15080-1-git-send-email-ciprian.barbu@linaro.org
State New
Headers show

Commit Message

Ciprian Barbu Nov. 4, 2014, 2:29 p.m. UTC
Here is a first attempt to remove inlines from API files. I also moved some
defines and typedefs out of some of the API headers. There is still room for
improvement I guess, the inline implementation and defines could be split into
their own files, but I just tried to show the general idea.

I also tried to make the documentation look good, the platform inlines reference
the documentation in the corresponding API file.

I removed almost all of the individual API includes from C files, keeping only
odp.h, which I remember was desirable. This can still be discussed.

---
 example/ipsec/odp_ipsec.c                          |   2 -
 example/ipsec/odp_ipsec_cache.c                    |   2 -
 example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
 example/ipsec/odp_ipsec_loop_db.c                  |   2 -
 example/ipsec/odp_ipsec_sa_db.c                    |   2 -
 example/ipsec/odp_ipsec_sp_db.c                    |   2 -
 example/ipsec/odp_ipsec_stream.c                   |   3 -
 helper/include/odph_eth.h                          |   4 -
 helper/include/odph_icmp.h                         |   3 -
 helper/include/odph_ip.h                           |   3 -
 helper/include/odph_ipsec.h                        |   4 -
 helper/include/odph_udp.h                          |   3 -
 platform/linux-generic/include/api/odp.h           |   6 +
 platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
 platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
 platform/linux-generic/include/api/odp_coremask.h  |  47 +-
 .../include/api/odp_platform_defines.h             | 152 ++++++
 .../include/api/odp_platform_inlines.h             | 527 +++++++++++++++++++++
 platform/linux-generic/include/api/odp_version.h   |  44 +-
 platform/linux-generic/odp_barrier.c               |   3 +-
 platform/linux-generic/odp_buffer.c                |   2 +-
 platform/linux-generic/odp_buffer_pool.c           |   8 +-
 platform/linux-generic/odp_coremask.c              |   3 +-
 platform/linux-generic/odp_crypto.c                |   9 +-
 platform/linux-generic/odp_packet.c                |   4 +-
 platform/linux-generic/odp_packet_flags.c          |   2 +-
 platform/linux-generic/odp_packet_io.c             |  11 +-
 platform/linux-generic/odp_packet_socket.c         |   2 +-
 platform/linux-generic/odp_queue.c                 |  10 +-
 platform/linux-generic/odp_ring.c                  |   6 +-
 platform/linux-generic/odp_rwlock.c                |   3 +-
 platform/linux-generic/odp_schedule.c              |  11 +-
 platform/linux-generic/odp_thread.c                |   7 +-
 platform/linux-generic/odp_ticketlock.c            |   4 +-
 platform/linux-generic/odp_timer.c                 |   7 +-
 35 files changed, 849 insertions(+), 519 deletions(-)
 create mode 100644 platform/linux-generic/include/api/odp_platform_defines.h
 create mode 100644 platform/linux-generic/include/api/odp_platform_inlines.h

Comments

Taras Kondratiuk Nov. 4, 2014, 5:27 p.m. UTC | #1
On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
> Here is a first attempt to remove inlines from API files. I also moved some
> defines and typedefs out of some of the API headers. There is still room for
> improvement I guess, the inline implementation and defines could be split into
> their own files, but I just tried to show the general idea.
>
> I also tried to make the documentation look good, the platform inlines reference
> the documentation in the corresponding API file.
>
> I removed almost all of the individual API includes from C files, keeping only
> odp.h, which I remember was desirable. This can still be discussed.
>
> ---
>   example/ipsec/odp_ipsec.c                          |   2 -
>   example/ipsec/odp_ipsec_cache.c                    |   2 -
>   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
>   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
>   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
>   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
>   example/ipsec/odp_ipsec_stream.c                   |   3 -
>   helper/include/odph_eth.h                          |   4 -
>   helper/include/odph_icmp.h                         |   3 -
>   helper/include/odph_ip.h                           |   3 -
>   helper/include/odph_ipsec.h                        |   4 -
>   helper/include/odph_udp.h                          |   3 -
>   platform/linux-generic/include/api/odp.h           |   6 +
>   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
>   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
>   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
>   .../include/api/odp_platform_defines.h             | 152 ++++++
>   .../include/api/odp_platform_inlines.h             | 527 +++++++++++++++++++++
>   platform/linux-generic/include/api/odp_version.h   |  44 +-
>   platform/linux-generic/odp_barrier.c               |   3 +-
>   platform/linux-generic/odp_buffer.c                |   2 +-
>   platform/linux-generic/odp_buffer_pool.c           |   8 +-
>   platform/linux-generic/odp_coremask.c              |   3 +-
>   platform/linux-generic/odp_crypto.c                |   9 +-
>   platform/linux-generic/odp_packet.c                |   4 +-
>   platform/linux-generic/odp_packet_flags.c          |   2 +-
>   platform/linux-generic/odp_packet_io.c             |  11 +-
>   platform/linux-generic/odp_packet_socket.c         |   2 +-
>   platform/linux-generic/odp_queue.c                 |  10 +-
>   platform/linux-generic/odp_ring.c                  |   6 +-
>   platform/linux-generic/odp_rwlock.c                |   3 +-
>   platform/linux-generic/odp_schedule.c              |  11 +-
>   platform/linux-generic/odp_thread.c                |   7 +-
>   platform/linux-generic/odp_ticketlock.c            |   4 +-
>   platform/linux-generic/odp_timer.c                 |   7 +-
>   35 files changed, 849 insertions(+), 519 deletions(-)
>   create mode 100644 platform/linux-generic/include/api/odp_platform_defines.h
>   create mode 100644 platform/linux-generic/include/api/odp_platform_inlines.h

Having all 'inlines' in one file isn't a good idea. I assume most of
fast path APIs will be there as wrappers to vendor's SDK.
This approach will also face the same issues I've faced in my previous
try.

Current ODP headers contains following parts in each file:

1. Platform-specific
1.a. Handle typedefs: e.g. odp_queue_t
1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL

2. Platform-independent
2.a. Data structures, typedefs: e.g. odp_queue_param_t
2.b. Function prototypes:       e.g. odp_queue_create()

Splitting them into platform-specific and platform-independent
parts looks straight forward until one wants to implement some API as
inline but that API needs a platform-independent typedef (2.a).
According to current C standards 'static inline' implementation must be
ahead of its prototype if prototype doesn't have 'static inline'. This
is our case.
If (2.a) and (2.b) bundled together, then there is no way for
implementation to get only typedef (2.a), implement function and then
include API prototype (2.b) to pull-in documentation and verification
of the function prototype.

For now I see two ways to solve it:
1. ODP provides (2.a) and (2.b) as two separate include files, so
    implementation can use them as it wish. E.g. odp_queue_struct.h and
    odp_queue_func.h
2. (2.a) and (2.b) are in the same file, but there is a platform include
    hook between them. Similarly to plat/odp_*.h approach in my last
    series on this topic.

Unfortunately both approaches has its own pros and cons.
Bill Fischofer Nov. 4, 2014, 5:32 p.m. UTC | #2
It's unfortunate that C (and GCC) have these inlining limitations.  This,
BTW, is exactly the sort of thing that LLVM was designed to handle--and
without requiring the programmer to decide in advance which functions
should and should not be inlined.

We could wrapper the independent APIs in macros that the platforms could
override to determine which prototypes should be marked 'static inline'.
Would that work?

On Tue, Nov 4, 2014 at 11:27 AM, Taras Kondratiuk <
taras.kondratiuk@linaro.org> wrote:

> On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
>
>> Here is a first attempt to remove inlines from API files. I also moved
>> some
>> defines and typedefs out of some of the API headers. There is still room
>> for
>> improvement I guess, the inline implementation and defines could be split
>> into
>> their own files, but I just tried to show the general idea.
>>
>> I also tried to make the documentation look good, the platform inlines
>> reference
>> the documentation in the corresponding API file.
>>
>> I removed almost all of the individual API includes from C files, keeping
>> only
>> odp.h, which I remember was desirable. This can still be discussed.
>>
>> ---
>>   example/ipsec/odp_ipsec.c                          |   2 -
>>   example/ipsec/odp_ipsec_cache.c                    |   2 -
>>   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
>>   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
>>   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
>>   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
>>   example/ipsec/odp_ipsec_stream.c                   |   3 -
>>   helper/include/odph_eth.h                          |   4 -
>>   helper/include/odph_icmp.h                         |   3 -
>>   helper/include/odph_ip.h                           |   3 -
>>   helper/include/odph_ipsec.h                        |   4 -
>>   helper/include/odph_udp.h                          |   3 -
>>   platform/linux-generic/include/api/odp.h           |   6 +
>>   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
>>   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
>>   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
>>   .../include/api/odp_platform_defines.h             | 152 ++++++
>>   .../include/api/odp_platform_inlines.h             | 527
>> +++++++++++++++++++++
>>   platform/linux-generic/include/api/odp_version.h   |  44 +-
>>   platform/linux-generic/odp_barrier.c               |   3 +-
>>   platform/linux-generic/odp_buffer.c                |   2 +-
>>   platform/linux-generic/odp_buffer_pool.c           |   8 +-
>>   platform/linux-generic/odp_coremask.c              |   3 +-
>>   platform/linux-generic/odp_crypto.c                |   9 +-
>>   platform/linux-generic/odp_packet.c                |   4 +-
>>   platform/linux-generic/odp_packet_flags.c          |   2 +-
>>   platform/linux-generic/odp_packet_io.c             |  11 +-
>>   platform/linux-generic/odp_packet_socket.c         |   2 +-
>>   platform/linux-generic/odp_queue.c                 |  10 +-
>>   platform/linux-generic/odp_ring.c                  |   6 +-
>>   platform/linux-generic/odp_rwlock.c                |   3 +-
>>   platform/linux-generic/odp_schedule.c              |  11 +-
>>   platform/linux-generic/odp_thread.c                |   7 +-
>>   platform/linux-generic/odp_ticketlock.c            |   4 +-
>>   platform/linux-generic/odp_timer.c                 |   7 +-
>>   35 files changed, 849 insertions(+), 519 deletions(-)
>>   create mode 100644 platform/linux-generic/include/api/odp_platform_
>> defines.h
>>   create mode 100644 platform/linux-generic/include/api/odp_platform_
>> inlines.h
>>
>
> Having all 'inlines' in one file isn't a good idea. I assume most of
> fast path APIs will be there as wrappers to vendor's SDK.
> This approach will also face the same issues I've faced in my previous
> try.
>
> Current ODP headers contains following parts in each file:
>
> 1. Platform-specific
> 1.a. Handle typedefs: e.g. odp_queue_t
> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>
> 2. Platform-independent
> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
> 2.b. Function prototypes:       e.g. odp_queue_create()
>
> Splitting them into platform-specific and platform-independent
> parts looks straight forward until one wants to implement some API as
> inline but that API needs a platform-independent typedef (2.a).
> According to current C standards 'static inline' implementation must be
> ahead of its prototype if prototype doesn't have 'static inline'. This
> is our case.
> If (2.a) and (2.b) bundled together, then there is no way for
> implementation to get only typedef (2.a), implement function and then
> include API prototype (2.b) to pull-in documentation and verification
> of the function prototype.
>
> For now I see two ways to solve it:
> 1. ODP provides (2.a) and (2.b) as two separate include files, so
>    implementation can use them as it wish. E.g. odp_queue_struct.h and
>    odp_queue_func.h
> 2. (2.a) and (2.b) are in the same file, but there is a platform include
>    hook between them. Similarly to plat/odp_*.h approach in my last
>    series on this topic.
>
> Unfortunately both approaches has its own pros and cons.
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
Bill Fischofer Nov. 4, 2014, 5:35 p.m. UTC | #3
If the ODP prototypes simply all said 'static inline' then would that
permit the implementation to choose later which were actually static inline?

I.e., if the common odp_xxx.h says

static inline void *odp_foo(...);

Then can the implementation can say;

static inline void *odp_foo(...) {  };

to make the function inline and just say

void *odp_foo(...) {  };

to make it an actual call?

On Tue, Nov 4, 2014 at 11:32 AM, Bill Fischofer <bill.fischofer@linaro.org>
wrote:

> It's unfortunate that C (and GCC) have these inlining limitations.  This,
> BTW, is exactly the sort of thing that LLVM was designed to handle--and
> without requiring the programmer to decide in advance which functions
> should and should not be inlined.
>
> We could wrapper the independent APIs in macros that the platforms could
> override to determine which prototypes should be marked 'static inline'.
> Would that work?
>
> On Tue, Nov 4, 2014 at 11:27 AM, Taras Kondratiuk <
> taras.kondratiuk@linaro.org> wrote:
>
>> On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
>>
>>> Here is a first attempt to remove inlines from API files. I also moved
>>> some
>>> defines and typedefs out of some of the API headers. There is still room
>>> for
>>> improvement I guess, the inline implementation and defines could be
>>> split into
>>> their own files, but I just tried to show the general idea.
>>>
>>> I also tried to make the documentation look good, the platform inlines
>>> reference
>>> the documentation in the corresponding API file.
>>>
>>> I removed almost all of the individual API includes from C files,
>>> keeping only
>>> odp.h, which I remember was desirable. This can still be discussed.
>>>
>>> ---
>>>   example/ipsec/odp_ipsec.c                          |   2 -
>>>   example/ipsec/odp_ipsec_cache.c                    |   2 -
>>>   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
>>>   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
>>>   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
>>>   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
>>>   example/ipsec/odp_ipsec_stream.c                   |   3 -
>>>   helper/include/odph_eth.h                          |   4 -
>>>   helper/include/odph_icmp.h                         |   3 -
>>>   helper/include/odph_ip.h                           |   3 -
>>>   helper/include/odph_ipsec.h                        |   4 -
>>>   helper/include/odph_udp.h                          |   3 -
>>>   platform/linux-generic/include/api/odp.h           |   6 +
>>>   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
>>>   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
>>>   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
>>>   .../include/api/odp_platform_defines.h             | 152 ++++++
>>>   .../include/api/odp_platform_inlines.h             | 527
>>> +++++++++++++++++++++
>>>   platform/linux-generic/include/api/odp_version.h   |  44 +-
>>>   platform/linux-generic/odp_barrier.c               |   3 +-
>>>   platform/linux-generic/odp_buffer.c                |   2 +-
>>>   platform/linux-generic/odp_buffer_pool.c           |   8 +-
>>>   platform/linux-generic/odp_coremask.c              |   3 +-
>>>   platform/linux-generic/odp_crypto.c                |   9 +-
>>>   platform/linux-generic/odp_packet.c                |   4 +-
>>>   platform/linux-generic/odp_packet_flags.c          |   2 +-
>>>   platform/linux-generic/odp_packet_io.c             |  11 +-
>>>   platform/linux-generic/odp_packet_socket.c         |   2 +-
>>>   platform/linux-generic/odp_queue.c                 |  10 +-
>>>   platform/linux-generic/odp_ring.c                  |   6 +-
>>>   platform/linux-generic/odp_rwlock.c                |   3 +-
>>>   platform/linux-generic/odp_schedule.c              |  11 +-
>>>   platform/linux-generic/odp_thread.c                |   7 +-
>>>   platform/linux-generic/odp_ticketlock.c            |   4 +-
>>>   platform/linux-generic/odp_timer.c                 |   7 +-
>>>   35 files changed, 849 insertions(+), 519 deletions(-)
>>>   create mode 100644 platform/linux-generic/include/api/odp_platform_
>>> defines.h
>>>   create mode 100644 platform/linux-generic/include/api/odp_platform_
>>> inlines.h
>>>
>>
>> Having all 'inlines' in one file isn't a good idea. I assume most of
>> fast path APIs will be there as wrappers to vendor's SDK.
>> This approach will also face the same issues I've faced in my previous
>> try.
>>
>> Current ODP headers contains following parts in each file:
>>
>> 1. Platform-specific
>> 1.a. Handle typedefs: e.g. odp_queue_t
>> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>>
>> 2. Platform-independent
>> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
>> 2.b. Function prototypes:       e.g. odp_queue_create()
>>
>> Splitting them into platform-specific and platform-independent
>> parts looks straight forward until one wants to implement some API as
>> inline but that API needs a platform-independent typedef (2.a).
>> According to current C standards 'static inline' implementation must be
>> ahead of its prototype if prototype doesn't have 'static inline'. This
>> is our case.
>> If (2.a) and (2.b) bundled together, then there is no way for
>> implementation to get only typedef (2.a), implement function and then
>> include API prototype (2.b) to pull-in documentation and verification
>> of the function prototype.
>>
>> For now I see two ways to solve it:
>> 1. ODP provides (2.a) and (2.b) as two separate include files, so
>>    implementation can use them as it wish. E.g. odp_queue_struct.h and
>>    odp_queue_func.h
>> 2. (2.a) and (2.b) are in the same file, but there is a platform include
>>    hook between them. Similarly to plat/odp_*.h approach in my last
>>    series on this topic.
>>
>> Unfortunately both approaches has its own pros and cons.
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>
>
Ciprian Barbu Nov. 4, 2014, 5:51 p.m. UTC | #4
On Tue, Nov 4, 2014 at 7:27 PM, Taras Kondratiuk
<taras.kondratiuk@linaro.org> wrote:
> On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
>>
>> Here is a first attempt to remove inlines from API files. I also moved
>> some
>> defines and typedefs out of some of the API headers. There is still room
>> for
>> improvement I guess, the inline implementation and defines could be split
>> into
>> their own files, but I just tried to show the general idea.
>>
>> I also tried to make the documentation look good, the platform inlines
>> reference
>> the documentation in the corresponding API file.
>>
>> I removed almost all of the individual API includes from C files, keeping
>> only
>> odp.h, which I remember was desirable. This can still be discussed.
>>
>> ---
>>   example/ipsec/odp_ipsec.c                          |   2 -
>>   example/ipsec/odp_ipsec_cache.c                    |   2 -
>>   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
>>   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
>>   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
>>   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
>>   example/ipsec/odp_ipsec_stream.c                   |   3 -
>>   helper/include/odph_eth.h                          |   4 -
>>   helper/include/odph_icmp.h                         |   3 -
>>   helper/include/odph_ip.h                           |   3 -
>>   helper/include/odph_ipsec.h                        |   4 -
>>   helper/include/odph_udp.h                          |   3 -
>>   platform/linux-generic/include/api/odp.h           |   6 +
>>   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
>>   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
>>   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
>>   .../include/api/odp_platform_defines.h             | 152 ++++++
>>   .../include/api/odp_platform_inlines.h             | 527
>> +++++++++++++++++++++
>>   platform/linux-generic/include/api/odp_version.h   |  44 +-
>>   platform/linux-generic/odp_barrier.c               |   3 +-
>>   platform/linux-generic/odp_buffer.c                |   2 +-
>>   platform/linux-generic/odp_buffer_pool.c           |   8 +-
>>   platform/linux-generic/odp_coremask.c              |   3 +-
>>   platform/linux-generic/odp_crypto.c                |   9 +-
>>   platform/linux-generic/odp_packet.c                |   4 +-
>>   platform/linux-generic/odp_packet_flags.c          |   2 +-
>>   platform/linux-generic/odp_packet_io.c             |  11 +-
>>   platform/linux-generic/odp_packet_socket.c         |   2 +-
>>   platform/linux-generic/odp_queue.c                 |  10 +-
>>   platform/linux-generic/odp_ring.c                  |   6 +-
>>   platform/linux-generic/odp_rwlock.c                |   3 +-
>>   platform/linux-generic/odp_schedule.c              |  11 +-
>>   platform/linux-generic/odp_thread.c                |   7 +-
>>   platform/linux-generic/odp_ticketlock.c            |   4 +-
>>   platform/linux-generic/odp_timer.c                 |   7 +-
>>   35 files changed, 849 insertions(+), 519 deletions(-)
>>   create mode 100644
>> platform/linux-generic/include/api/odp_platform_defines.h
>>   create mode 100644
>> platform/linux-generic/include/api/odp_platform_inlines.h
>
>
> Having all 'inlines' in one file isn't a good idea. I assume most of
> fast path APIs will be there as wrappers to vendor's SDK.

I already said in the comment that having all inlines in one file is
not the idea, I didn't want to spend a lot of time in making the
perfect solution, only to show the general idea.

> This approach will also face the same issues I've faced in my previous
> try.

Have you tried compiling it? There are no intermediate typedefs and
defines and yet you can compile everything in the form presented. Also
make doxygen-html and have a look at it.

>
> Current ODP headers contains following parts in each file:
>
> 1. Platform-specific
> 1.a. Handle typedefs: e.g. odp_queue_t
> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>
> 2. Platform-independent
> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
> 2.b. Function prototypes:       e.g. odp_queue_create()
>
> Splitting them into platform-specific and platform-independent
> parts looks straight forward until one wants to implement some API as
> inline but that API needs a platform-independent typedef (2.a).
> According to current C standards 'static inline' implementation must be
> ahead of its prototype if prototype doesn't have 'static inline'. This
> is our case.

This is solved in this patch by including odp_platform_defines.h and
odp_platform_inlines.h in odp.h first before anything else. All the
source files include only odp.h so the order is always preserved.

> If (2.a) and (2.b) bundled together, then there is no way for
> implementation to get only typedef (2.a), implement function and then
> include API prototype (2.b) to pull-in documentation and verification
> of the function prototype.
>
> For now I see two ways to solve it:
> 1. ODP provides (2.a) and (2.b) as two separate include files, so
>    implementation can use them as it wish. E.g. odp_queue_struct.h and
>    odp_queue_func.h

This crossed my mind too, it helps a lot with our problem. This would
translate into splitting odp_platform_defines.h into multiple files as
needed.

> 2. (2.a) and (2.b) are in the same file, but there is a platform include
>    hook between them. Similarly to plat/odp_*.h approach in my last
>    series on this topic.

I can't remember if we found a final form for this approach, one that
would work all the way. I would vote against it though, it makes the
APIs hard to follow.

>
> Unfortunately both approaches has its own pros and cons.
Savolainen, Petri (NSN - FI/Espoo) Nov. 5, 2014, 9:02 a.m. UTC | #5
> -----Original Message-----
> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
> bounces@lists.linaro.org] On Behalf Of ext Taras Kondratiuk
> Sent: Tuesday, November 04, 2014 7:28 PM
> To: Ciprian Barbu; lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [RFC PATCH] Platform specific definitions and
> inlines
> 
> On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
> > Here is a first attempt to remove inlines from API files. I also moved
> some
> > defines and typedefs out of some of the API headers. There is still room
> for
> > improvement I guess, the inline implementation and defines could be
> split into
> > their own files, but I just tried to show the general idea.
> >
> > I also tried to make the documentation look good, the platform inlines
> reference
> > the documentation in the corresponding API file.
> >
> > I removed almost all of the individual API includes from C files,
> keeping only
> > odp.h, which I remember was desirable. This can still be discussed.
> >
> > ---
> >   example/ipsec/odp_ipsec.c                          |   2 -
> >   example/ipsec/odp_ipsec_cache.c                    |   2 -
> >   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
> >   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
> >   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
> >   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
> >   example/ipsec/odp_ipsec_stream.c                   |   3 -
> >   helper/include/odph_eth.h                          |   4 -
> >   helper/include/odph_icmp.h                         |   3 -
> >   helper/include/odph_ip.h                           |   3 -
> >   helper/include/odph_ipsec.h                        |   4 -
> >   helper/include/odph_udp.h                          |   3 -
> >   platform/linux-generic/include/api/odp.h           |   6 +
> >   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
> >   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
> >   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
> >   .../include/api/odp_platform_defines.h             | 152 ++++++
> >   .../include/api/odp_platform_inlines.h             | 527
> +++++++++++++++++++++
> >   platform/linux-generic/include/api/odp_version.h   |  44 +-
> >   platform/linux-generic/odp_barrier.c               |   3 +-
> >   platform/linux-generic/odp_buffer.c                |   2 +-
> >   platform/linux-generic/odp_buffer_pool.c           |   8 +-
> >   platform/linux-generic/odp_coremask.c              |   3 +-
> >   platform/linux-generic/odp_crypto.c                |   9 +-
> >   platform/linux-generic/odp_packet.c                |   4 +-
> >   platform/linux-generic/odp_packet_flags.c          |   2 +-
> >   platform/linux-generic/odp_packet_io.c             |  11 +-
> >   platform/linux-generic/odp_packet_socket.c         |   2 +-
> >   platform/linux-generic/odp_queue.c                 |  10 +-
> >   platform/linux-generic/odp_ring.c                  |   6 +-
> >   platform/linux-generic/odp_rwlock.c                |   3 +-
> >   platform/linux-generic/odp_schedule.c              |  11 +-
> >   platform/linux-generic/odp_thread.c                |   7 +-
> >   platform/linux-generic/odp_ticketlock.c            |   4 +-
> >   platform/linux-generic/odp_timer.c                 |   7 +-
> >   35 files changed, 849 insertions(+), 519 deletions(-)
> >   create mode 100644 platform/linux-
> generic/include/api/odp_platform_defines.h
> >   create mode 100644 platform/linux-
> generic/include/api/odp_platform_inlines.h
> 
> Having all 'inlines' in one file isn't a good idea. I assume most of
> fast path APIs will be there as wrappers to vendor's SDK.
> This approach will also face the same issues I've faced in my previous
> try.
> 
> Current ODP headers contains following parts in each file:
> 
> 1. Platform-specific
> 1.a. Handle typedefs: e.g. odp_queue_t
> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
> 
> 2. Platform-independent
> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
> 2.b. Function prototypes:       e.g. odp_queue_create()
> 
> Splitting them into platform-specific and platform-independent
> parts looks straight forward until one wants to implement some API as
> inline but that API needs a platform-independent typedef (2.a).
> According to current C standards 'static inline' implementation must be
> ahead of its prototype if prototype doesn't have 'static inline'. This
> is our case.
> If (2.a) and (2.b) bundled together, then there is no way for
> implementation to get only typedef (2.a), implement function and then
> include API prototype (2.b) to pull-in documentation and verification
> of the function prototype.
> 
> For now I see two ways to solve it:
> 1. ODP provides (2.a) and (2.b) as two separate include files, so
>     implementation can use them as it wish. E.g. odp_queue_struct.h and
>     odp_queue_func.h
> 2. (2.a) and (2.b) are in the same file, but there is a platform include
>     hook between them. Similarly to plat/odp_*.h approach in my last
>     series on this topic.
> 
> Unfortunately both approaches has its own pros and cons.
> 


Ciprian, your patch is not done against the tip of linux-generic. E.g. example/ipsec/odp_ipsec.c does not currently include other API headers than  odp.h (and helpers).

I suggest that we keep the reference (linux-generic/include/api) simple. I'd remove all inlines from there and make sure that the documentation is only showing the normative API (not the implementation). Then every implementation would solve the reuse problem as it wishes.

It's much more important that reference API definition and documentation are clean/clear, than provide some level of (speculative) help for implementation reuse.

-Petri
Ciprian Barbu Nov. 5, 2014, 10:07 a.m. UTC | #6
On Wed, Nov 5, 2014 at 11:02 AM, Savolainen, Petri (NSN - FI/Espoo)
<petri.savolainen@nsn.com> wrote:
>
>
>> -----Original Message-----
>> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
>> bounces@lists.linaro.org] On Behalf Of ext Taras Kondratiuk
>> Sent: Tuesday, November 04, 2014 7:28 PM
>> To: Ciprian Barbu; lng-odp@lists.linaro.org
>> Subject: Re: [lng-odp] [RFC PATCH] Platform specific definitions and
>> inlines
>>
>> On 11/04/2014 04:29 PM, Ciprian Barbu wrote:
>> > Here is a first attempt to remove inlines from API files. I also moved
>> some
>> > defines and typedefs out of some of the API headers. There is still room
>> for
>> > improvement I guess, the inline implementation and defines could be
>> split into
>> > their own files, but I just tried to show the general idea.
>> >
>> > I also tried to make the documentation look good, the platform inlines
>> reference
>> > the documentation in the corresponding API file.
>> >
>> > I removed almost all of the individual API includes from C files,
>> keeping only
>> > odp.h, which I remember was desirable. This can still be discussed.
>> >
>> > ---
>> >   example/ipsec/odp_ipsec.c                          |   2 -
>> >   example/ipsec/odp_ipsec_cache.c                    |   2 -
>> >   example/ipsec/odp_ipsec_fwd_db.c                   |   1 -
>> >   example/ipsec/odp_ipsec_loop_db.c                  |   2 -
>> >   example/ipsec/odp_ipsec_sa_db.c                    |   2 -
>> >   example/ipsec/odp_ipsec_sp_db.c                    |   2 -
>> >   example/ipsec/odp_ipsec_stream.c                   |   3 -
>> >   helper/include/odph_eth.h                          |   4 -
>> >   helper/include/odph_icmp.h                         |   3 -
>> >   helper/include/odph_ip.h                           |   3 -
>> >   helper/include/odph_ipsec.h                        |   4 -
>> >   helper/include/odph_udp.h                          |   3 -
>> >   platform/linux-generic/include/api/odp.h           |   6 +
>> >   platform/linux-generic/include/api/odp_atomic.h    | 282 ++++-------
>> >   platform/linux-generic/include/api/odp_byteorder.h | 187 ++------
>> >   platform/linux-generic/include/api/odp_coremask.h  |  47 +-
>> >   .../include/api/odp_platform_defines.h             | 152 ++++++
>> >   .../include/api/odp_platform_inlines.h             | 527
>> +++++++++++++++++++++
>> >   platform/linux-generic/include/api/odp_version.h   |  44 +-
>> >   platform/linux-generic/odp_barrier.c               |   3 +-
>> >   platform/linux-generic/odp_buffer.c                |   2 +-
>> >   platform/linux-generic/odp_buffer_pool.c           |   8 +-
>> >   platform/linux-generic/odp_coremask.c              |   3 +-
>> >   platform/linux-generic/odp_crypto.c                |   9 +-
>> >   platform/linux-generic/odp_packet.c                |   4 +-
>> >   platform/linux-generic/odp_packet_flags.c          |   2 +-
>> >   platform/linux-generic/odp_packet_io.c             |  11 +-
>> >   platform/linux-generic/odp_packet_socket.c         |   2 +-
>> >   platform/linux-generic/odp_queue.c                 |  10 +-
>> >   platform/linux-generic/odp_ring.c                  |   6 +-
>> >   platform/linux-generic/odp_rwlock.c                |   3 +-
>> >   platform/linux-generic/odp_schedule.c              |  11 +-
>> >   platform/linux-generic/odp_thread.c                |   7 +-
>> >   platform/linux-generic/odp_ticketlock.c            |   4 +-
>> >   platform/linux-generic/odp_timer.c                 |   7 +-
>> >   35 files changed, 849 insertions(+), 519 deletions(-)
>> >   create mode 100644 platform/linux-
>> generic/include/api/odp_platform_defines.h
>> >   create mode 100644 platform/linux-
>> generic/include/api/odp_platform_inlines.h
>>
>> Having all 'inlines' in one file isn't a good idea. I assume most of
>> fast path APIs will be there as wrappers to vendor's SDK.
>> This approach will also face the same issues I've faced in my previous
>> try.
>>
>> Current ODP headers contains following parts in each file:
>>
>> 1. Platform-specific
>> 1.a. Handle typedefs: e.g. odp_queue_t
>> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>>
>> 2. Platform-independent
>> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
>> 2.b. Function prototypes:       e.g. odp_queue_create()
>>
>> Splitting them into platform-specific and platform-independent
>> parts looks straight forward until one wants to implement some API as
>> inline but that API needs a platform-independent typedef (2.a).
>> According to current C standards 'static inline' implementation must be
>> ahead of its prototype if prototype doesn't have 'static inline'. This
>> is our case.
>> If (2.a) and (2.b) bundled together, then there is no way for
>> implementation to get only typedef (2.a), implement function and then
>> include API prototype (2.b) to pull-in documentation and verification
>> of the function prototype.
>>
>> For now I see two ways to solve it:
>> 1. ODP provides (2.a) and (2.b) as two separate include files, so
>>     implementation can use them as it wish. E.g. odp_queue_struct.h and
>>     odp_queue_func.h
>> 2. (2.a) and (2.b) are in the same file, but there is a platform include
>>     hook between them. Similarly to plat/odp_*.h approach in my last
>>     series on this topic.
>>
>> Unfortunately both approaches has its own pros and cons.
>>
>
>
> Ciprian, your patch is not done against the tip of linux-generic. E.g. example/ipsec/odp_ipsec.c does not currently include other API headers than  odp.h (and helpers).

I can always spend a bit more time and rebase it to latest version, I
think I used an old version. But it seems we wont be actually going
forward with this thread.

>
> I suggest that we keep the reference (linux-generic/include/api) simple. I'd remove all inlines from there and make sure that the documentation is only showing the normative API (not the implementation). Then every implementation would solve the reuse problem as it wishes.
>
> It's much more important that reference API definition and documentation are clean/clear, than provide some level of (speculative) help for implementation reuse.
>
> -Petri
>
>
>
>
Taras Kondratiuk Nov. 5, 2014, 12:32 p.m. UTC | #7
On 11/04/2014 07:35 PM, Bill Fischofer wrote:
> If the ODP prototypes simply all said 'static inline' then would that
> permit the implementation to choose later which were actually static inline?
>
> I.e., if the common odp_xxx.h says
>
> static inline void *odp_foo(...);
>
> Then can the implementation can say;
>
> static inline void *odp_foo(...) {  };
>
> to make the function inline and just say
>
> void *odp_foo(...) {  };
>
> to make it an actual call?

Unfortunately GCC throws -Werror=unused-function on this in each place
where this header included, but no function implemented.
Bill Fischofer Nov. 5, 2014, 12:35 p.m. UTC | #8
I suspected as much.  We should experiment to see if LLVM does a better
job, but that's post v1.0.

On Wed, Nov 5, 2014 at 6:32 AM, Taras Kondratiuk <
taras.kondratiuk@linaro.org> wrote:

> On 11/04/2014 07:35 PM, Bill Fischofer wrote:
>
>> If the ODP prototypes simply all said 'static inline' then would that
>> permit the implementation to choose later which were actually static
>> inline?
>>
>> I.e., if the common odp_xxx.h says
>>
>> static inline void *odp_foo(...);
>>
>> Then can the implementation can say;
>>
>> static inline void *odp_foo(...) {  };
>>
>> to make the function inline and just say
>>
>> void *odp_foo(...) {  };
>>
>> to make it an actual call?
>>
>
> Unfortunately GCC throws -Werror=unused-function on this in each place
> where this header included, but no function implemented.
>
Taras Kondratiuk Nov. 5, 2014, 12:47 p.m. UTC | #9
On 11/04/2014 07:51 PM, Ciprian Barbu wrote:
> On Tue, Nov 4, 2014 at 7:27 PM, Taras Kondratiuk
> <taras.kondratiuk@linaro.org> wrote:
>>
>> Current ODP headers contains following parts in each file:
>>
>> 1. Platform-specific
>> 1.a. Handle typedefs: e.g. odp_queue_t
>> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>>
>> 2. Platform-independent
>> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
>> 2.b. Function prototypes:       e.g. odp_queue_create()
>>
>> Splitting them into platform-specific and platform-independent
>> parts looks straight forward until one wants to implement some API as
>> inline but that API needs a platform-independent typedef (2.a).
>> According to current C standards 'static inline' implementation must be
>> ahead of its prototype if prototype doesn't have 'static inline'. This
>> is our case.
>
> This is solved in this patch by including odp_platform_defines.h and
> odp_platform_inlines.h in odp.h first before anything else. All the
> source files include only odp.h so the order is always preserved.

It seems the issue is present there. Just try to implement
odp_queue_create() as 'static inline' in odp_platform_inlines.h. I
understand that there is no reason to inline odp_queue_create(), but
this is just a good example of the issue.
Mike Holmes Nov. 5, 2014, 1:28 p.m. UTC | #10
A thought, we should not burn too many cycles at this point on a feature we
are postponing until after 1.0

On 5 November 2014 07:47, Taras Kondratiuk <taras.kondratiuk@linaro.org>
wrote:

> On 11/04/2014 07:51 PM, Ciprian Barbu wrote:
>
>> On Tue, Nov 4, 2014 at 7:27 PM, Taras Kondratiuk
>> <taras.kondratiuk@linaro.org> wrote:
>>
>>>
>>> Current ODP headers contains following parts in each file:
>>>
>>> 1. Platform-specific
>>> 1.a. Handle typedefs: e.g. odp_queue_t
>>> 1.b. Macros, enums:   e.g. ODP_SCHED_PRIO_NORMAL
>>>
>>> 2. Platform-independent
>>> 2.a. Data structures, typedefs: e.g. odp_queue_param_t
>>> 2.b. Function prototypes:       e.g. odp_queue_create()
>>>
>>> Splitting them into platform-specific and platform-independent
>>> parts looks straight forward until one wants to implement some API as
>>> inline but that API needs a platform-independent typedef (2.a).
>>> According to current C standards 'static inline' implementation must be
>>> ahead of its prototype if prototype doesn't have 'static inline'. This
>>> is our case.
>>>
>>
>> This is solved in this patch by including odp_platform_defines.h and
>> odp_platform_inlines.h in odp.h first before anything else. All the
>> source files include only odp.h so the order is always preserved.
>>
>
> It seems the issue is present there. Just try to implement
> odp_queue_create() as 'static inline' in odp_platform_inlines.h. I
> understand that there is no reason to inline odp_queue_create(), but
> this is just a good example of the issue.
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
diff mbox

Patch

diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index ec6c87a..fe91446 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -16,8 +16,6 @@ 
 #include <unistd.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
 #include <odph_linux.h>
 #include <odph_packet.h>
 #include <odph_eth.h>
diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c
index 01650d0..d508377 100644
--- a/example/ipsec/odp_ipsec_cache.c
+++ b/example/ipsec/odp_ipsec_cache.c
@@ -8,8 +8,6 @@ 
 #include <string.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
 #include <odph_ipsec.h>
 
 #include <odp_ipsec_cache.h>
diff --git a/example/ipsec/odp_ipsec_fwd_db.c b/example/ipsec/odp_ipsec_fwd_db.c
index 9ed5d00..d4e3583 100644
--- a/example/ipsec/odp_ipsec_fwd_db.c
+++ b/example/ipsec/odp_ipsec_fwd_db.c
@@ -8,7 +8,6 @@ 
 #include <string.h>
 
 #include <odp.h>
-#include <odp_align.h>
 #include <odp_crypto.h>
 
 #include <odp_ipsec_fwd_db.h>
diff --git a/example/ipsec/odp_ipsec_loop_db.c b/example/ipsec/odp_ipsec_loop_db.c
index f773352..af4590a 100644
--- a/example/ipsec/odp_ipsec_loop_db.c
+++ b/example/ipsec/odp_ipsec_loop_db.c
@@ -8,8 +8,6 @@ 
 #include <string.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
 
 #include <odp_ipsec_loop_db.h>
 
diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c
index f6da623..e8679db 100644
--- a/example/ipsec/odp_ipsec_sa_db.c
+++ b/example/ipsec/odp_ipsec_sa_db.c
@@ -8,8 +8,6 @@ 
 #include <string.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
 
 #include <odp_ipsec_sa_db.h>
 
diff --git a/example/ipsec/odp_ipsec_sp_db.c b/example/ipsec/odp_ipsec_sp_db.c
index f288dfe..8edc0fa 100644
--- a/example/ipsec/odp_ipsec_sp_db.c
+++ b/example/ipsec/odp_ipsec_sp_db.c
@@ -8,8 +8,6 @@ 
 #include <string.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
 
 #include <odp_ipsec_sp_db.h>
 
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
index fba425c..3260b53 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec/odp_ipsec_stream.c
@@ -13,9 +13,6 @@ 
 #include <openssl/evp.h>
 
 #include <odp.h>
-#include <odp_align.h>
-#include <odp_crypto.h>
-#include <odp_packet.h>
 #include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
diff --git a/helper/include/odph_eth.h b/helper/include/odph_eth.h
index 55a2b1e..12a7af5 100644
--- a/helper/include/odph_eth.h
+++ b/helper/include/odph_eth.h
@@ -18,10 +18,6 @@ 
 extern "C" {
 #endif
 
-#include <odp_std_types.h>
-#include <odp_byteorder.h>
-#include <odp_align.h>
-#include <odp_debug.h>
 
 #define ODPH_ETHADDR_LEN     6    /**< Ethernet address length */
 #define ODPH_ETHHDR_LEN      14   /**< Ethernet header length */
diff --git a/helper/include/odph_icmp.h b/helper/include/odph_icmp.h
index 8414d7e..7570f4d 100644
--- a/helper/include/odph_icmp.h
+++ b/helper/include/odph_icmp.h
@@ -18,9 +18,6 @@ 
 extern "C" {
 #endif
 
-#include <odp_align.h>
-#include <odp_debug.h>
-#include <odp_byteorder.h>
 
 /** ICMP header length */
 #define ODPH_ICMPHDR_LEN 8
diff --git a/helper/include/odph_ip.h b/helper/include/odph_ip.h
index ca71c44..fd74909 100644
--- a/helper/include/odph_ip.h
+++ b/helper/include/odph_ip.h
@@ -18,9 +18,6 @@ 
 extern "C" {
 #endif
 
-#include <odp_align.h>
-#include <odp_debug.h>
-#include <odp_byteorder.h>
 #include <odph_chksum.h>
 
 #include <string.h>
diff --git a/helper/include/odph_ipsec.h b/helper/include/odph_ipsec.h
index f547b90..780fc2a 100644
--- a/helper/include/odph_ipsec.h
+++ b/helper/include/odph_ipsec.h
@@ -18,10 +18,6 @@ 
 extern "C" {
 #endif
 
-#include <odp_std_types.h>
-#include <odp_byteorder.h>
-#include <odp_align.h>
-#include <odp_debug.h>
 
 #define ODPH_ESPHDR_LEN      8    /**< IPSec ESP header length */
 #define ODPH_ESPTRL_LEN      2    /**< IPSec ESP trailer length */
diff --git a/helper/include/odph_udp.h b/helper/include/odph_udp.h
index 3970f00..567fffe 100644
--- a/helper/include/odph_udp.h
+++ b/helper/include/odph_udp.h
@@ -18,9 +18,6 @@ 
 extern "C" {
 #endif
 
-#include <odp_align.h>
-#include <odp_debug.h>
-#include <odp_byteorder.h>
 
 /** UDP header length */
 #define ODPH_UDPHDR_LEN 8
diff --git a/platform/linux-generic/include/api/odp.h b/platform/linux-generic/include/api/odp.h
index 0ee3faf..7a6af95 100644
--- a/platform/linux-generic/include/api/odp.h
+++ b/platform/linux-generic/include/api/odp.h
@@ -18,6 +18,9 @@ 
 extern "C" {
 #endif
 
+#include <odp_platform_defines.h>
+#include <odp_platform_inlines.h>
+
 #include <odp_config.h>
 
 #include <odp_version.h>
@@ -32,6 +35,7 @@  extern "C" {
 #include <odp_barrier.h>
 #include <odp_spinlock.h>
 #include <odp_atomic.h>
+#include <odp_rwlock.h>
 
 #include <odp_init.h>
 #include <odp_system_info.h>
@@ -49,6 +53,8 @@  extern "C" {
 #include <odp_packet_flags.h>
 #include <odp_packet_io.h>
 
+#include <odp_crypto.h>
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/include/api/odp_atomic.h b/platform/linux-generic/include/api/odp_atomic.h
index 0cc4cf4..e0f70e3 100644
--- a/platform/linux-generic/include/api/odp_atomic.h
+++ b/platform/linux-generic/include/api/odp_atomic.h
@@ -23,34 +23,19 @@  extern "C" {
 
 
 /**
- * Atomic integer
- */
-typedef volatile int32_t odp_atomic_int_t;
-
-/**
- * Atomic unsigned integer 64 bits
- */
-typedef volatile uint64_t odp_atomic_u64_t;
-
-/**
- * Atomic unsigned integer 32 bits
- */
-typedef volatile uint32_t odp_atomic_u32_t;
-
-
-/**
+ * @anchor odp_atomic_init_int
+ *
  * Initialize atomic integer
  *
  * @param ptr    An integer atomic variable
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_init_int(odp_atomic_int_t *ptr)
-{
-	*ptr = 0;
-}
+void odp_atomic_init_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_load_int
+ *
  * Load value of atomic integer
  *
  * @param ptr    An atomic variable
@@ -59,12 +44,11 @@  static inline void odp_atomic_init_int(odp_atomic_int_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline int odp_atomic_load_int(odp_atomic_int_t *ptr)
-{
-	return *ptr;
-}
+int odp_atomic_load_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_store_int
+ *
  * Store value to atomic integer
  *
  * @param ptr        An atomic variable
@@ -72,12 +56,11 @@  static inline int odp_atomic_load_int(odp_atomic_int_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value)
-{
-	*ptr = new_value;
-}
+void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value);
 
 /**
+ * @anchor odp_fetch_add_int
+ *
  * Fetch and add atomic integer
  *
  * @param ptr    An atomic variable
@@ -85,12 +68,11 @@  static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value)
  *
  * @return Value of the variable before the operation
  */
-static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value)
-{
-	return __sync_fetch_and_add(ptr, value);
-}
+int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value);
 
 /**
+ * @anchor odp_atomic_fetch_sub_int
+ *
  * Fetch and subtract atomic integer
  *
  * @param ptr    An atomic integer variable
@@ -98,70 +80,64 @@  static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value)
  *
  * @return Value of the variable before the operation
  */
-static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value)
-{
-	return __sync_fetch_and_sub(ptr, value);
-}
+int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value);
 
 /**
+ * @anchor odp_atomic_fetch_inc_int
+ *
  * Fetch and increment atomic integer by 1
  *
  * @param ptr    An atomic variable
  *
  * @return Value of the variable before the operation
  */
-static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr)
-{
-	return odp_atomic_fetch_add_int(ptr, 1);
-}
+int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_inc_int
+ *
  * Increment atomic integer by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr)
-{
-	odp_atomic_fetch_add_int(ptr, 1);
-}
+void odp_atomic_inc_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_fetch_dec_int
+ *
  * Fetch and decrement atomic integer by 1
  *
  * @param ptr    An atomic int variable
  *
  * @return Value of the variable before the operation
  */
-static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr)
-{
-	return odp_atomic_fetch_sub_int(ptr, 1);
-}
+int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_dec_int
+ *
  * Decrement atomic integer by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr)
-{
-	odp_atomic_fetch_sub_int(ptr, 1);
-}
+void odp_atomic_dec_int(odp_atomic_int_t *ptr);
 
 /**
+ * @anchor odp_atomic_init_u32
+ *
  * Initialize atomic uint32
  *
  * @param ptr    An atomic variable
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr)
-{
-	*ptr = 0;
-}
+void odp_atomic_init_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_load_u32
+ *
  * Load value of atomic uint32
  *
  * @param ptr    An atomic variable
@@ -170,12 +146,11 @@  static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr)
-{
-	return *ptr;
-}
+uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_store_u32
+ *
  * Store value to atomic uint32
  *
  * @param ptr        An atomic variable
@@ -183,13 +158,12 @@  static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr,
-					uint32_t new_value)
-{
-	*ptr = new_value;
-}
+void odp_atomic_store_u32(odp_atomic_u32_t *ptr,
+					uint32_t new_value);
 
 /**
+ * @anchor odp_atomic_fetch_add_u32
+ *
  * Fetch and add atomic uint32
  *
  * @param ptr    An atomic variable
@@ -197,13 +171,12 @@  static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr,
  *
  * @return Value of the variable before the operation
  */
-static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr,
-						uint32_t value)
-{
-	return __sync_fetch_and_add(ptr, value);
-}
+uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr,
+						uint32_t value);
 
 /**
+ * @anchor odp_atomic_fetch_sub_u32
+ *
  * Fetch and subtract uint32
  *
  * @param ptr    An atomic variable
@@ -211,76 +184,54 @@  static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr,
  *
  * @return Value of the variable before the operation
  */
-static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr,
-						uint32_t value)
-{
-	return __sync_fetch_and_sub(ptr, value);
-}
+uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr,
+						uint32_t value);
 
 /**
+ * @anchor odp_atomic_fetch_inc_u32
+ *
  * Fetch and increment atomic uint32 by 1
  *
  * @param ptr    An atomic variable
  *
  * @return Value of the variable before the operation
  */
-#if defined __OCTEON__
-
-static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr)
-{
-	uint32_t ret;
-
-	__asm__ __volatile__ ("syncws");
-	__asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) :
-			      "r" (ptr));
-
-	return ret;
-}
-
-#else
-
-static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr)
-{
-	return odp_atomic_fetch_add_u32(ptr, 1);
-}
-
-#endif
+uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_inc_u32
+ *
  * Increment atomic uint32 by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr)
-{
-	odp_atomic_fetch_add_u32(ptr, 1);
-}
+void odp_atomic_inc_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_fetch_dec_u32
+ *
  * Fetch and decrement uint32 by 1
  *
  * @param ptr    An atomic variable
  *
  * @return Value of the variable before the operation
  */
-static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr)
-{
-	return odp_atomic_fetch_sub_u32(ptr, 1);
-}
+uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_dec_u32
+ *
  * Decrement atomic uint32 by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr)
-{
-	odp_atomic_fetch_sub_u32(ptr, 1);
-}
+void odp_atomic_dec_u32(odp_atomic_u32_t *ptr);
 
 /**
+ * @anchor odp_atomic_cmpset_u32
+ *
  * Atomic compare and set for 32bit
  *
  * @param dst destination location into which the value will be written.
@@ -288,25 +239,23 @@  static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr)
  * @param src new value.
  * @return Non-zero on success; 0 on failure.
  */
-static inline int
-odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src)
-{
-	return __sync_bool_compare_and_swap(dst, exp, src);
-}
+int
+odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src);
 
 /**
+ * @anchor odp_atomic_init_u64
+ *
  * Initialize atomic uint64
  *
  * @param ptr    An atomic variable
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr)
-{
-	*ptr = 0;
-}
+void odp_atomic_init_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_load_u64
+ *
  * Load value of atomic uint64
  *
  * @param ptr    An atomic variable
@@ -315,12 +264,11 @@  static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr)
-{
-	return *ptr;
-}
+uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_store_u64
+ *
  * Store value to atomic uint64
  *
  * @param ptr        An atomic variable
@@ -328,25 +276,23 @@  static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr)
  *
  * @note The operation is not synchronized with other threads
  */
-static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr,
-					uint64_t new_value)
-{
-	*ptr = new_value;
-}
+void odp_atomic_store_u64(odp_atomic_u64_t *ptr,
+					uint64_t new_value);
 
 /**
+ * @anchor odp_atomic_add_u64
+ *
  * Add atomic uint64
  *
  * @param ptr    An atomic variable
  * @param value  A value to be added to the variable
  *
  */
-static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value)
-{
-	__sync_fetch_and_add(ptr, value);
-}
+void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value);
 
 /**
+ * @anchor odp_atomic_fetch_add_u64
+ *
  * Fetch and add atomic uint64
  *
  * @param ptr    An atomic variable
@@ -354,34 +300,21 @@  static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value)
  *
  * @return Value of the variable before the operation
  */
-
-#if defined __powerpc__ && !defined __powerpc64__
-static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr,
-						uint64_t value)
-{
-	return __sync_fetch_and_add((odp_atomic_u32_t *)ptr,
-				    (uint32_t)value);
-}
-#else
-static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr,
-						uint64_t value)
-{
-	return __sync_fetch_and_add(ptr, value);
-}
-#endif
+uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, uint64_t value);
 /**
+ * @anchor odp_atomic_sub_u64
+ *
  * Subtract atomic uint64
  *
  * @param ptr    An atomic variable
  * @param value  A value to be subtracted from the variable
  *
  */
-static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value)
-{
-	__sync_fetch_and_sub(ptr, value);
-}
+void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value);
 
 /**
+ * @anchor odp_atomic_fetch_sub_u64
+ *
  * Fetch and subtract atomic uint64
  *
  * @param ptr    An atomic variable
@@ -389,67 +322,52 @@  static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value)
  *
  * @return Value of the variable before the operation
  */
-#if defined __powerpc__ && !defined __powerpc64__
-static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr,
-						uint64_t value)
-{
-	return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr,
-				    (uint32_t)value);
-}
-#else
-static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr,
-						uint64_t value)
-{
-	return __sync_fetch_and_sub(ptr, value);
-}
-#endif
+uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, uint64_t value);
 /**
+ * @anchor odp_atomic_fetch_inc_u64
+ *
  * Fetch and increment atomic uint64 by 1
  *
  * @param ptr    An atomic variable
  *
  * @return Value of the variable before the operation
  */
-static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr)
-{
-	return odp_atomic_fetch_add_u64(ptr, 1);
-}
+uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_inc_u64
+ *
  * Increment atomic uint64 by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr)
-{
-	odp_atomic_fetch_add_u64(ptr, 1);
-}
+void odp_atomic_inc_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_fetch_dec_u64
+ *
  * Fetch and decrement atomic uint64 by 1
  *
  * @param ptr    An atomic variable
  *
  * @return Value of the variable before the operation
  */
-static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr)
-{
-	return odp_atomic_fetch_sub_u64(ptr, 1);
-}
+uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_dec_u64
+ *
  * Decrement atomic uint64 by 1
  *
  * @param ptr    An atomic variable
  *
  */
-static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr)
-{
-	odp_atomic_fetch_sub_u64(ptr, 1);
-}
+void odp_atomic_dec_u64(odp_atomic_u64_t *ptr);
 
 /**
+ * @anchor odp_atomic_cmpset_u64
+ *
  * Atomic compare and set for 64bit
  *
  * @param dst destination location into which the value will be written.
@@ -457,11 +375,7 @@  static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr)
  * @param src new value.
  * @return Non-zero on success; 0 on failure.
  */
-static inline int
-odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src)
-{
-	return __sync_bool_compare_and_swap(dst, exp, src);
-}
+int odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src);
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-generic/include/api/odp_byteorder.h b/platform/linux-generic/include/api/odp_byteorder.h
index e0f7a17..71e1d3b 100644
--- a/platform/linux-generic/include/api/odp_byteorder.h
+++ b/platform/linux-generic/include/api/odp_byteorder.h
@@ -22,102 +22,34 @@  extern "C" {
 #include <odp_std_types.h>
 #include <odp_compiler.h>
 
-#ifndef __BYTE_ORDER
-#error __BYTE_ORDER not defined!
-#endif
-
-#ifndef __BIG_ENDIAN
-#error __BIG_ENDIAN not defined!
-#endif
-
-#ifndef __LITTLE_ENDIAN
-#error __LITTLE_ENDIAN not defined!
-#endif
-
-/** Big endian byte order */
-#define ODP_BIG_ENDIAN    __BIG_ENDIAN
-
-/** Little endian byte order */
-#define ODP_LITTLE_ENDIAN __LITTLE_ENDIAN
-
-/** Selected byte order */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define ODP_BYTE_ORDER ODP_LITTLE_ENDIAN
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define ODP_BYTE_ORDER ODP_BIG_ENDIAN
-#endif
-
-
-/* for use with type checkers such as sparse */
-#ifdef __CHECKER__
-/** @internal bitwise attribute */
-#define __odp_bitwise	__attribute__((bitwise))
-/** @internal force attribute */
-#define __odp_force     __attribute__((force))
-#else
-/** @internal bitwise attribute */
-#define __odp_bitwise
-/** @internal force attribute */
-#define __odp_force
-#endif
-
-
-typedef uint16_t __odp_bitwise	uint16le_t; /**< unsigned 16bit little endian */
-typedef uint16_t __odp_bitwise	uint16be_t; /**< unsigned 16bit big endian */
-
-typedef uint32_t __odp_bitwise	uint32le_t; /**< unsigned 32bit little endian */
-typedef uint32_t __odp_bitwise	uint32be_t; /**< unsigned 32bit big endian */
-
-typedef uint64_t __odp_bitwise	uint64le_t; /**< unsigned 64bit little endian */
-typedef uint64_t __odp_bitwise	uint64be_t; /**< unsigned 64bit big endian */
-
-typedef uint16_t __odp_bitwise  uint16sum_t; /**< unsigned 16bit bitwise */
-typedef uint32_t __odp_bitwise  uint32sum_t; /**< unsigned 32bit bitwise */
-/*
- * Big Endian -> CPU byte order:
- */
+#include <odp_platform_defines.h>
 
 /**
+ * @anchor odp_be_to_cpu_16
+ *
  * Convert 16bit big endian to cpu native uint16_t
  * @param be16  big endian 16bit
  * @return  cpu native uint16_t
  */
-static inline uint16_t odp_be_to_cpu_16(uint16be_t be16)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return __odp_builtin_bswap16((__odp_force uint16_t)be16);
-#else
-	return (__odp_force uint16_t)be16;
-#endif
-}
+uint16_t odp_be_to_cpu_16(uint16be_t be16);
 
 /**
+ * @anchor odp_be_to_cpu_32
+ *
  * Convert 32bit big endian to cpu native uint32_t
  * @param be32  big endian 32bit
  * @return  cpu native uint32_t
  */
-static inline uint32_t odp_be_to_cpu_32(uint32be_t be32)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return __builtin_bswap32((__odp_force uint32_t)be32);
-#else
-	return (__odp_force uint32_t)be32;
-#endif
-}
+uint32_t odp_be_to_cpu_32(uint32be_t be32);
 
 /**
+ * @anchor odp_be_to_cpu_64
+ *
  * Convert 64bit big endian to cpu native uint64_t
  * @param be64  big endian 64bit
  * @return  cpu native uint64_t
  */
-static inline uint64_t odp_be_to_cpu_64(uint64be_t be64)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return __builtin_bswap64((__odp_force uint64_t)be64);
-#else
-	return (__odp_force uint64_t)be64;
-#endif
-}
+uint64_t odp_be_to_cpu_64(uint64be_t be64);
 
 
 /*
@@ -125,46 +57,31 @@  static inline uint64_t odp_be_to_cpu_64(uint64be_t be64)
  */
 
 /**
+ * @anchor odp_cpu_to_be_16
+ *
  * Convert cpu native uint16_t to 16bit big endian
  * @param cpu16  uint16_t in cpu native format
  * @return  big endian 16bit
  */
-static inline uint16be_t odp_cpu_to_be_16(uint16_t cpu16)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint16be_t)__odp_builtin_bswap16(cpu16);
-#else
-	return (__odp_force uint16be_t)cpu16;
-#endif
-}
+uint16be_t odp_cpu_to_be_16(uint16_t cpu16);
 
 /**
+ * @anchor odp_cpu_to_be_32
+ *
  * Convert cpu native uint32_t to 32bit big endian
  * @param cpu32  uint32_t in cpu native format
  * @return  big endian 32bit
  */
-static inline uint32be_t odp_cpu_to_be_32(uint32_t cpu32)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint32be_t)__builtin_bswap32(cpu32);
-#else
-	return (__odp_force uint32be_t)cpu32;
-#endif
-}
+uint32be_t odp_cpu_to_be_32(uint32_t cpu32);
 
 /**
+ * @anchor odp_cpu_to_be_64
+ *
  * Convert cpu native uint64_t to 64bit big endian
  * @param cpu64  uint64_t in cpu native format
  * @return  big endian 64bit
  */
-static inline uint64be_t odp_cpu_to_be_64(uint64_t cpu64)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint64be_t)__builtin_bswap64(cpu64);
-#else
-	return (__odp_force uint64be_t)cpu64;
-#endif
-}
+uint64be_t odp_cpu_to_be_64(uint64_t cpu64);
 
 
 /*
@@ -172,46 +89,31 @@  static inline uint64be_t odp_cpu_to_be_64(uint64_t cpu64)
  */
 
 /**
+ * @anchor odp_le_to_cpu_16
+ *
  * Convert 16bit little endian to cpu native uint16_t
  * @param le16  little endian 16bit
  * @return  cpu native uint16_t
  */
-static inline uint16_t odp_le_to_cpu_16(uint16le_t le16)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint16_t)le16;
-#else
-	return __odp_builtin_bswap16((__odp_force uint16_t)le16);
-#endif
-}
+uint16_t odp_le_to_cpu_16(uint16le_t le16);
 
 /**
+ * @anchor odp_le_to_cpu_32
+ *
  * Convert 32bit little endian to cpu native uint32_t
  * @param le32  little endian 32bit
  * @return  cpu native uint32_t
  */
-static inline uint32_t odp_le_to_cpu_32(uint32le_t le32)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint32_t)le32;
-#else
-	return __builtin_bswap32((__odp_force uint32_t)le32);
-#endif
-}
+uint32_t odp_le_to_cpu_32(uint32le_t le32);
 
 /**
+ * @anchor odp_le_to_cpu_64
+ *
  * Convert 64bit little endian to cpu native uint64_t
  * @param le64  little endian 64bit
  * @return  cpu native uint64_t
  */
-static inline uint64_t odp_le_to_cpu_64(uint64le_t le64)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint64_t)le64;
-#else
-	return __builtin_bswap64((__odp_force uint64_t)le64);
-#endif
-}
+uint64_t odp_le_to_cpu_64(uint64le_t le64);
 
 
 /*
@@ -219,46 +121,31 @@  static inline uint64_t odp_le_to_cpu_64(uint64le_t le64)
  */
 
 /**
+ * @anchor odp_cpu_to_le_16
+ *
  * Convert cpu native uint16_t to 16bit little endian
  * @param cpu16  uint16_t in cpu native format
  * @return  little endian 16bit
  */
-static inline uint16le_t odp_cpu_to_le_16(uint16_t cpu16)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint16le_t)cpu16;
-#else
-	return (__odp_force uint16le_t)__odp_builtin_bswap16(cpu16);
-#endif
-}
+uint16le_t odp_cpu_to_le_16(uint16_t cpu16);
 
 /**
+ * @anchor odp_cpu_to_le_32
+ *
  * Convert cpu native uint32_t to 32bit little endian
  * @param cpu32  uint32_t in cpu native format
  * @return  little endian 32bit
  */
-static inline uint32le_t odp_cpu_to_le_32(uint32_t cpu32)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint32le_t)cpu32;
-#else
-	return (__odp_force uint32le_t)__builtin_bswap32(cpu32);
-#endif
-}
+uint32le_t odp_cpu_to_le_32(uint32_t cpu32);
 
 /**
+ * @anchor odp_cpu_to_le_64
+ *
  * Convert cpu native uint64_t to 64bit little endian
  * @param cpu64  uint64_t in cpu native format
  * @return  little endian 64bit
  */
-static inline uint64le_t odp_cpu_to_le_64(uint64_t cpu64)
-{
-#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
-	return (__odp_force uint64le_t)cpu64;
-#else
-	return (__odp_force uint64le_t)__builtin_bswap64(cpu64);
-#endif
-}
+uint64le_t odp_cpu_to_le_64(uint64_t cpu64);
 
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/include/api/odp_coremask.h b/platform/linux-generic/include/api/odp_coremask.h
index 141cb6a..aa21cc9 100644
--- a/platform/linux-generic/include/api/odp_coremask.h
+++ b/platform/linux-generic/include/api/odp_coremask.h
@@ -22,20 +22,6 @@  extern "C" {
 
 #include <odp_std_types.h>
 
-/** @internal */
-#define ODP_COREMASK_SIZE_U64  1
-
-/**
- * Core mask
- *
- * Don't access directly, use access functions.
- */
-typedef struct odp_coremask_t {
-	uint64_t _u64[ODP_COREMASK_SIZE_U64]; /**< @private Mask*/
-
-} odp_coremask_t;
-
-
 
 /**
  * Add core mask bits from a string
@@ -86,10 +72,7 @@  void odp_coremask_from_u64(const uint64_t *u64, int num, odp_coremask_t *mask);
  * Clear entire mask
  * @param mask	Core mask to flush with zero value
  */
-static inline void odp_coremask_zero(odp_coremask_t *mask)
-{
-	mask->_u64[0] = 0;
-}
+void odp_coremask_zero(odp_coremask_t *mask);
 
 /**
  * Add core to mask
@@ -129,11 +112,8 @@  int odp_coremask_count(const odp_coremask_t *mask);
  * @param src1    Source mask 1
  * @param src2    Source mask 2
  */
-static inline void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
-				    odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] & src2->_u64[0];
-}
+void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
+				    odp_coremask_t *src2);
 
 /**
  * Logical OR over two source masks.
@@ -142,11 +122,8 @@  static inline void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
  * @param src1    Source mask 1
  * @param src2    Source mask 2
  */
-static inline void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
-				   odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] | src2->_u64[0];
-}
+void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
+				   odp_coremask_t *src2);
 
 /**
  * Logical XOR over two source masks.
@@ -155,20 +132,14 @@  static inline void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
  * @param src1    Source mask 1
  * @param src2    Source mask 2
  */
-static inline void odp_coremask_xor(odp_coremask_t *dest, odp_coremask_t *src1,
-				    odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] ^ src2->_u64[0];
-}
+void odp_coremask_xor(odp_coremask_t *dest, odp_coremask_t *src1,
+				    odp_coremask_t *src2);
 
 /**
  * Test if two masks contain the same cores
  */
-static inline int odp_coremask_equal(odp_coremask_t *mask1,
-				     odp_coremask_t *mask2)
-{
-	return (mask1->_u64[0] == mask2->_u64[0]);
-}
+int odp_coremask_equal(odp_coremask_t *mask1,
+				     odp_coremask_t *mask2);
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-generic/include/api/odp_platform_defines.h b/platform/linux-generic/include/api/odp_platform_defines.h
new file mode 100644
index 0000000..24d355d
--- /dev/null
+++ b/platform/linux-generic/include/api/odp_platform_defines.h
@@ -0,0 +1,152 @@ 
+/**
+ * @file
+ *
+ * ODP platform defines and typedefs
+ */
+
+/******************************************************************************
+ * odp_version.h
+*******************************************************************************/
+
+#ifndef ODP_PLATFORM_DEFINES_H_
+#define ODP_PLATFORM_DEFINES_H_
+/**
+ * ODP API main version
+ *
+ * Introduction of major new features or changes. APIs with different major
+ * versions are likely not backward compatible.
+ */
+#define ODP_VERSION_API_MAIN  0
+
+/**
+ * ODP API sub version
+ *
+ * Introduction of additional features or minor changes. APIs with common
+ * major version and different sub versions may be backward compatible (if only
+ * additions).
+ */
+#define ODP_VERSION_API_SUB   0
+
+/**
+ * ODP API bug correction version
+ *
+ * Bug corrections to the API files. APIs with the same major and sub
+ * versions, but different bug correction versions are backward compatible.
+ */
+#define ODP_VERSION_API_BUG   1
+
+
+/** @internal Version string expand */
+#define ODP_VERSION_STR_EXPAND(x)  #x
+
+/** @internal Version to string */
+#define ODP_VERSION_TO_STR(x)      ODP_VERSION_STR_EXPAND(x)
+
+/** @internal API version string */
+#define ODP_VERSION_API_STR \
+ODP_VERSION_TO_STR(ODP_VERSION_API_MAIN) "."\
+ODP_VERSION_TO_STR(ODP_VERSION_API_SUB) "."\
+ODP_VERSION_TO_STR(ODP_VERSION_API_BUG)
+
+
+/******************************************************************************
+ * odp_byte_order.h
+*******************************************************************************/
+
+#include <endian.h>
+#include <odp_std_types.h>
+#include <odp_compiler.h>
+
+#ifndef __BYTE_ORDER
+#error __BYTE_ORDER not defined!
+#endif
+
+#ifndef __BIG_ENDIAN
+#error __BIG_ENDIAN not defined!
+#endif
+
+#ifndef __LITTLE_ENDIAN
+#error __LITTLE_ENDIAN not defined!
+#endif
+
+/** Big endian byte order */
+#define ODP_BIG_ENDIAN    __BIG_ENDIAN
+
+/** Little endian byte order */
+#define ODP_LITTLE_ENDIAN __LITTLE_ENDIAN
+
+/** Selected byte order */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ODP_BYTE_ORDER ODP_LITTLE_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define ODP_BYTE_ORDER ODP_BIG_ENDIAN
+#endif
+
+/* for use with type checkers such as sparse */
+#ifdef __CHECKER__
+/** @internal bitwise attribute */
+#define __odp_bitwise	__attribute__((bitwise))
+/** @internal force attribute */
+#define __odp_force     __attribute__((force))
+#else
+/** @internal bitwise attribute */
+#define __odp_bitwise
+/** @internal force attribute */
+#define __odp_force
+#endif
+
+
+typedef uint16_t __odp_bitwise	uint16le_t; /**< unsigned 16bit little endian */
+typedef uint16_t __odp_bitwise	uint16be_t; /**< unsigned 16bit big endian */
+
+typedef uint32_t __odp_bitwise	uint32le_t; /**< unsigned 32bit little endian */
+typedef uint32_t __odp_bitwise	uint32be_t; /**< unsigned 32bit big endian */
+
+typedef uint64_t __odp_bitwise	uint64le_t; /**< unsigned 64bit little endian */
+typedef uint64_t __odp_bitwise	uint64be_t; /**< unsigned 64bit big endian */
+
+typedef uint16_t __odp_bitwise  uint16sum_t; /**< unsigned 16bit bitwise */
+typedef uint32_t __odp_bitwise  uint32sum_t; /**< unsigned 32bit bitwise */
+/*
+ * Big Endian -> CPU byte order:
+ */
+
+/******************************************************************************
+ * odp_coremask.h
+*******************************************************************************/
+
+/** @internal */
+#define ODP_COREMASK_SIZE_U64  1
+
+/**
+ * Core mask
+ *
+ * Don't access directly, use access functions.
+ */
+typedef struct odp_coremask_t {
+	uint64_t _u64[ODP_COREMASK_SIZE_U64]; /**< @private Mask*/
+
+} odp_coremask_t;
+
+
+/******************************************************************************
+ * odp_atomic.h
+*******************************************************************************/
+
+/**
+ * Atomic integer
+ */
+typedef volatile int32_t odp_atomic_int_t;
+
+/**
+ * Atomic unsigned integer 64 bits
+ */
+typedef volatile uint64_t odp_atomic_u64_t;
+
+/**
+ * Atomic unsigned integer 32 bits
+ */
+typedef volatile uint32_t odp_atomic_u32_t;
+
+
+#endif
diff --git a/platform/linux-generic/include/api/odp_platform_inlines.h b/platform/linux-generic/include/api/odp_platform_inlines.h
new file mode 100644
index 0000000..7efa4b4
--- /dev/null
+++ b/platform/linux-generic/include/api/odp_platform_inlines.h
@@ -0,0 +1,527 @@ 
+/**
+ * @file
+ *
+ * ODP platform inline implementations
+ */
+
+#ifndef ODP_PLATFORM_INLINES_H_
+#define ODP_PLATFORM_INLINES_H_
+
+#include <odp_std_types.h>
+#include <odp_compiler.h>
+#include <odp_platform_defines.h>
+
+/******************************************************************************
+ * odp_version.h
+*******************************************************************************/
+/**
+ *  odp_version_api_str
+ */
+static inline const char *odp_version_api_str(void)
+{
+	return ODP_VERSION_API_STR;
+}
+
+
+/******************************************************************************
+ * odp_byte_order.h
+*******************************************************************************/
+
+/**
+ * Platform specific inline implementation of @ref odp_be_to_cpu_16
+ */
+static inline uint16_t odp_be_to_cpu_16(uint16be_t be16)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return __odp_builtin_bswap16((__odp_force uint16_t)be16);
+#else
+	return (__odp_force uint16_t)be16;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_be_to_cpu_32
+ */
+static inline uint32_t odp_be_to_cpu_32(uint32be_t be32)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return __builtin_bswap32((__odp_force uint32_t)be32);
+#else
+	return (__odp_force uint32_t)be32;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_be_to_cpu_64
+ */
+static inline uint64_t odp_be_to_cpu_64(uint64be_t be64)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return __builtin_bswap64((__odp_force uint64_t)be64);
+#else
+	return (__odp_force uint64_t)be64;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_be_16
+ */
+static inline uint16be_t odp_cpu_to_be_16(uint16_t cpu16)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint16be_t)__odp_builtin_bswap16(cpu16);
+#else
+	return (__odp_force uint16be_t)cpu16;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_be_32
+ */
+static inline uint32be_t odp_cpu_to_be_32(uint32_t cpu32)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint32be_t)__builtin_bswap32(cpu32);
+#else
+	return (__odp_force uint32be_t)cpu32;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_be_64
+ */
+static inline uint64be_t odp_cpu_to_be_64(uint64_t cpu64)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint64be_t)__builtin_bswap64(cpu64);
+#else
+	return (__odp_force uint64be_t)cpu64;
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_le_to_cpu_16
+ */
+static inline uint16_t odp_le_to_cpu_16(uint16le_t le16)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint16_t)le16;
+#else
+	return __odp_builtin_bswap16((__odp_force uint16_t)le16);
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_le_to_cpu_32
+ */
+static inline uint32_t odp_le_to_cpu_32(uint32le_t le32)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint32_t)le32;
+#else
+	return __builtin_bswap32((__odp_force uint32_t)le32);
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_le_to_cpu_64
+ */
+static inline uint64_t odp_le_to_cpu_64(uint64le_t le64)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint64_t)le64;
+#else
+	return __builtin_bswap64((__odp_force uint64_t)le64);
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_le_16
+ */
+static inline uint16le_t odp_cpu_to_le_16(uint16_t cpu16)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint16le_t)cpu16;
+#else
+	return (__odp_force uint16le_t)__odp_builtin_bswap16(cpu16);
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_le_32
+ */
+static inline uint32le_t odp_cpu_to_le_32(uint32_t cpu32)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint32le_t)cpu32;
+#else
+	return (__odp_force uint32le_t)__builtin_bswap32(cpu32);
+#endif
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_cpu_to_le_64
+ */
+static inline uint64le_t odp_cpu_to_le_64(uint64_t cpu64)
+{
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+	return (__odp_force uint64le_t)cpu64;
+#else
+	return (__odp_force uint64le_t)__builtin_bswap64(cpu64);
+#endif
+}
+
+
+/******************************************************************************
+ * odp_coremask.h
+*******************************************************************************/
+
+/**
+ * Platform specific inline implementation of @ref odp_coremask_zero
+ */
+static inline void odp_coremask_zero(odp_coremask_t *mask)
+{
+	mask->_u64[0] = 0;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_coremask_and
+ */
+static inline void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
+				    odp_coremask_t *src2)
+{
+	dest->_u64[0] = src1->_u64[0] & src2->_u64[0];
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_coremask_or
+ */
+static inline void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
+				   odp_coremask_t *src2)
+{
+	dest->_u64[0] = src1->_u64[0] | src2->_u64[0];
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_coremask_xor
+ */
+static inline void odp_coremask_xor(odp_coremask_t *dest, odp_coremask_t *src1,
+				    odp_coremask_t *src2)
+{
+	dest->_u64[0] = src1->_u64[0] ^ src2->_u64[0];
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_coremask_equal
+ */
+static inline int odp_coremask_equal(odp_coremask_t *mask1,
+				     odp_coremask_t *mask2)
+{
+	return (mask1->_u64[0] == mask2->_u64[0]);
+}
+
+/******************************************************************************
+ * odp_atomic.h
+*******************************************************************************/
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_init_int
+ */
+static inline void odp_atomic_init_int(odp_atomic_int_t *ptr)
+{
+	*ptr = 0;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_store_int
+ */
+static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value)
+{
+	*ptr = new_value;
+}
+/**
+ * Platform specific inline implementation of @ref odp_atomic_load_int
+ */
+static inline int odp_atomic_load_int(odp_atomic_int_t *ptr)
+{
+	return *ptr;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_add_int
+ */
+static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value)
+{
+	return __sync_fetch_and_add(ptr, value);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_sub_int
+ */
+static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value)
+{
+	return __sync_fetch_and_sub(ptr, value);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_inc_int
+ */
+static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr)
+{
+	return odp_atomic_fetch_add_int(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_inc_int
+ */
+static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr)
+{
+	odp_atomic_fetch_add_int(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_dec_int
+ */
+static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr)
+{
+	return odp_atomic_fetch_sub_int(ptr, 1);
+}
+
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_dec_int
+ */
+static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr)
+{
+	odp_atomic_fetch_sub_int(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_init_u32
+ */
+static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr)
+{
+	*ptr = 0;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_load_u32
+ */
+static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr)
+{
+	return *ptr;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_store_u32
+ */
+static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr,
+					uint32_t new_value)
+{
+	*ptr = new_value;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_add_u32
+ */
+static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr,
+						uint32_t value)
+{
+	return __sync_fetch_and_add(ptr, value);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_sub_u32
+ */
+static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr,
+						uint32_t value)
+{
+	return __sync_fetch_and_sub(ptr, value);
+}
+
+#if defined __OCTEON__
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_inc_u32
+ */
+static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr)
+{
+	uint32_t ret;
+
+	__asm__ __volatile__ ("syncws");
+	__asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) :
+			      "r" (ptr));
+
+	return ret;
+}
+
+#else
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_inc_u32
+ */
+static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr)
+{
+	return odp_atomic_fetch_add_u32(ptr, 1);
+}
+
+#endif
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_inc_u32
+ */
+static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr)
+{
+	odp_atomic_fetch_add_u32(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_dec_u32
+ */
+static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr)
+{
+	return odp_atomic_fetch_sub_u32(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_dec_u32
+ */
+static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr)
+{
+	odp_atomic_fetch_sub_u32(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_cmpset_u32
+ */
+static inline int
+odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src)
+{
+	return __sync_bool_compare_and_swap(dst, exp, src);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_init_u64
+ */
+static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr)
+{
+	*ptr = 0;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_load_u64
+ */
+static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr)
+{
+	return *ptr;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_store_u64
+ */
+static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr,
+					uint64_t new_value)
+{
+	*ptr = new_value;
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_add_u64
+ */
+static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value)
+{
+	__sync_fetch_and_add(ptr, value);
+}
+
+#if defined __powerpc__ && !defined __powerpc64__
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_add_u64
+ */
+static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr,
+						uint64_t value)
+{
+	return __sync_fetch_and_add((odp_atomic_u32_t *)ptr,
+				    (uint32_t)value);
+}
+#else
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_add_u64
+ */
+static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr,
+						uint64_t value)
+{
+	return __sync_fetch_and_add(ptr, value);
+}
+#endif
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_sub_u64
+ */
+static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value)
+{
+	__sync_fetch_and_sub(ptr, value);
+}
+
+#if defined __powerpc__ && !defined __powerpc64__
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_sub_u64
+ */
+static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr,
+						uint64_t value)
+{
+	return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr,
+				    (uint32_t)value);
+}
+#else
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_sub_u64
+ */
+static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr,
+						uint64_t value)
+{
+	return __sync_fetch_and_sub(ptr, value);
+}
+#endif
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_inc_u64
+ */
+static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr)
+{
+	return odp_atomic_fetch_add_u64(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_inc_u64
+ */
+static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr)
+{
+	odp_atomic_fetch_add_u64(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_fetch_dec_u64
+ */
+static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr)
+{
+	return odp_atomic_fetch_sub_u64(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_dec_u64
+ */
+static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr)
+{
+	odp_atomic_fetch_sub_u64(ptr, 1);
+}
+
+/**
+ * Platform specific inline implementation of @ref odp_atomic_cmpset_u64
+ */
+static inline int
+odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src)
+{
+	return __sync_bool_compare_and_swap(dst, exp, src);
+}
+
+#endif
diff --git a/platform/linux-generic/include/api/odp_version.h b/platform/linux-generic/include/api/odp_version.h
index c823e2d..ba4b507 100644
--- a/platform/linux-generic/include/api/odp_version.h
+++ b/platform/linux-generic/include/api/odp_version.h
@@ -20,51 +20,11 @@  extern "C" {
 
 
 /**
- * ODP API main version
+ * @anchor odp_version_api_str
  *
- * Introduction of major new features or changes. APIs with different major
- * versions are likely not backward compatible.
- */
-#define ODP_VERSION_API_MAIN  0
-
-/**
- * ODP API sub version
- *
- * Introduction of additional features or minor changes. APIs with common
- * major version and different sub versions may be backward compatible (if only
- * additions).
- */
-#define ODP_VERSION_API_SUB   0
-
-/**
- * ODP API bug correction version
- *
- * Bug corrections to the API files. APIs with the same major and sub
- * versions, but different bug correction versions are backward compatible.
- */
-#define ODP_VERSION_API_BUG   1
-
-
-/** @internal Version string expand */
-#define ODP_VERSION_STR_EXPAND(x)  #x
-
-/** @internal Version to string */
-#define ODP_VERSION_TO_STR(x)      ODP_VERSION_STR_EXPAND(x)
-
-/** @internal API version string */
-#define ODP_VERSION_API_STR \
-ODP_VERSION_TO_STR(ODP_VERSION_API_MAIN) "."\
-ODP_VERSION_TO_STR(ODP_VERSION_API_SUB) "."\
-ODP_VERSION_TO_STR(ODP_VERSION_API_BUG)
-
-
-/**
  * Returns ODP API version string
  */
-static inline const char *odp_version_api_str(void)
-{
-	return ODP_VERSION_API_STR;
-}
+const char *odp_version_api_str(void);
 
 
 
diff --git a/platform/linux-generic/odp_barrier.c b/platform/linux-generic/odp_barrier.c
index a82b294..fb93d84 100644
--- a/platform/linux-generic/odp_barrier.c
+++ b/platform/linux-generic/odp_barrier.c
@@ -4,8 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_barrier.h>
-#include <odp_sync.h>
+#include <odp.h>
 #include <odp_spin_internal.h>
 
 void odp_barrier_init_count(odp_barrier_t *barrier, int count)
diff --git a/platform/linux-generic/odp_buffer.c b/platform/linux-generic/odp_buffer.c
index e54e0e7..330c26c 100644
--- a/platform/linux-generic/odp_buffer.c
+++ b/platform/linux-generic/odp_buffer.c
@@ -4,7 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_buffer.h>
+#include <odp.h>
 #include <odp_buffer_internal.h>
 #include <odp_buffer_pool_internal.h>
 
diff --git a/platform/linux-generic/odp_buffer_pool.c b/platform/linux-generic/odp_buffer_pool.c
index a48d7d6..02893b9 100644
--- a/platform/linux-generic/odp_buffer_pool.c
+++ b/platform/linux-generic/odp_buffer_pool.c
@@ -4,18 +4,12 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_std_types.h>
-#include <odp_buffer_pool.h>
+#include <odp.h>
 #include <odp_buffer_pool_internal.h>
 #include <odp_buffer_internal.h>
 #include <odp_packet_internal.h>
 #include <odp_timer_internal.h>
-#include <odp_shared_memory.h>
-#include <odp_align.h>
 #include <odp_internal.h>
-#include <odp_config.h>
-#include <odp_hints.h>
-#include <odp_debug.h>
 
 #include <string.h>
 #include <stdlib.h>
diff --git a/platform/linux-generic/odp_coremask.c b/platform/linux-generic/odp_coremask.c
index c7438cc..4d8d956 100644
--- a/platform/linux-generic/odp_coremask.c
+++ b/platform/linux-generic/odp_coremask.c
@@ -4,8 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_coremask.h>
-#include <odp_debug.h>
+#include <odp.h>
 
 #include <stdlib.h>
 #include <string.h>
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index b37ad6b..79fd128 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -4,16 +4,9 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_crypto.h>
+#include <odp.h>
 #include <odp_internal.h>
-#include <odp_atomic.h>
-#include <odp_spinlock.h>
-#include <odp_sync.h>
-#include <odp_debug.h>
-#include <odp_align.h>
-#include <odp_shared_memory.h>
 #include <odp_crypto_internal.h>
-#include <odp_hints.h>
 #include <odph_packet.h>
 
 #include <string.h>
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 435bc8b..c7187d4 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -4,10 +4,8 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_packet.h>
+#include <odp.h>
 #include <odp_packet_internal.h>
-#include <odp_hints.h>
-#include <odp_byteorder.h>
 
 #include <odph_eth.h>
 #include <odph_ip.h>
diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c
index 06fdeed..ef63e9c 100644
--- a/platform/linux-generic/odp_packet_flags.c
+++ b/platform/linux-generic/odp_packet_flags.c
@@ -4,7 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_packet_flags.h>
+#include <odp.h>
 #include <odp_packet_internal.h>
 
 
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 0c30f0f..ffa0fcb 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -4,20 +4,15 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_packet_io.h>
+#include <odp.h>
 #include <odp_packet_io_internal.h>
-#include <odp_packet_io_queue.h>
-#include <odp_packet.h>
 #include <odp_packet_internal.h>
+/** XXX: This should probably be odp_packet_io_queue_internal.h> */
+#include <odp_packet_io_queue.h>
 #include <odp_internal.h>
-#include <odp_spinlock.h>
-#include <odp_shared_memory.h>
 #include <odp_packet_socket.h>
-#include <odp_hints.h>
-#include <odp_config.h>
 #include <odp_queue_internal.h>
 #include <odp_schedule_internal.h>
-#include <odp_debug.h>
 
 #include <string.h>
 
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c
index 006d7bd..49ac9ef 100644
--- a/platform/linux-generic/odp_packet_socket.c
+++ b/platform/linux-generic/odp_packet_socket.c
@@ -34,9 +34,9 @@ 
 #include <errno.h>
 #include <sys/syscall.h>
 
+#include <odp.h>
 #include <odp_packet_socket.h>
 #include <odp_packet_internal.h>
-#include <odp_hints.h>
 
 #include <odph_eth.h>
 #include <odph_ip.h>
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index 1318bcd..c92b1fc 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -4,22 +4,14 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_queue.h>
+#include <odp.h>
 #include <odp_queue_internal.h>
-#include <odp_std_types.h>
-#include <odp_align.h>
-#include <odp_buffer.h>
 #include <odp_buffer_internal.h>
 #include <odp_buffer_pool_internal.h>
 #include <odp_internal.h>
-#include <odp_shared_memory.h>
 #include <odp_schedule_internal.h>
-#include <odp_config.h>
 #include <odp_packet_io_internal.h>
 #include <odp_packet_io_queue.h>
-#include <odp_debug.h>
-#include <odp_hints.h>
-#include <odp_sync.h>
 
 #ifdef USE_TICKETLOCK
 #include <odp_ticketlock.h>
diff --git a/platform/linux-generic/odp_ring.c b/platform/linux-generic/odp_ring.c
index 632aa66..d3a8483 100644
--- a/platform/linux-generic/odp_ring.c
+++ b/platform/linux-generic/odp_ring.c
@@ -69,17 +69,13 @@ 
  *
  ***************************************************************************/
 
-#include <odp_shared_memory.h>
+#include <odp.h>
 #include <odp_internal.h>
 #include <odp_spin_internal.h>
-#include <odp_spinlock.h>
-#include <odp_align.h>
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
-#include <odp_debug.h>
-#include <odp_rwlock.h>
 #include <odph_ring.h>
 
 static TAILQ_HEAD(, odph_ring) odp_ring_list;
diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c
index 11c8dd7..c48d3b9 100644
--- a/platform/linux-generic/odp_rwlock.c
+++ b/platform/linux-generic/odp_rwlock.c
@@ -4,8 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_atomic.h>
-#include <odp_rwlock.h>
+#include <odp.h>
 
 #include <odp_spin_internal.h>
 
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 1bf819b..63d91cc 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -4,20 +4,11 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_schedule.h>
+#include <odp.h>
 #include <odp_schedule_internal.h>
-#include <odp_align.h>
-#include <odp_queue.h>
-#include <odp_shared_memory.h>
-#include <odp_buffer.h>
-#include <odp_buffer_pool.h>
 #include <odp_internal.h>
-#include <odp_config.h>
-#include <odp_debug.h>
 #include <odp_thread.h>
 #include <odp_time.h>
-#include <odp_spinlock.h>
-#include <odp_hints.h>
 
 #include <odp_queue_internal.h>
 
diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c
index b869b27..1264205 100644
--- a/platform/linux-generic/odp_thread.c
+++ b/platform/linux-generic/odp_thread.c
@@ -9,13 +9,8 @@ 
 #endif
 #include <sched.h>
 
-#include <odp_thread.h>
+#include <odp.h>
 #include <odp_internal.h>
-#include <odp_atomic.h>
-#include <odp_config.h>
-#include <odp_debug.h>
-#include <odp_shared_memory.h>
-#include <odp_align.h>
 
 #include <string.h>
 #include <stdio.h>
diff --git a/platform/linux-generic/odp_ticketlock.c b/platform/linux-generic/odp_ticketlock.c
index be5b885..18a0306 100644
--- a/platform/linux-generic/odp_ticketlock.c
+++ b/platform/linux-generic/odp_ticketlock.c
@@ -4,9 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_ticketlock.h>
-#include <odp_atomic.h>
-#include <odp_sync.h>
+#include <odp.h>
 #include <odp_spin_internal.h>
 
 
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 313c713..9c2b366 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -4,15 +4,10 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_timer.h>
+#include <odp.h>
 #include <odp_timer_internal.h>
-#include <odp_time.h>
 #include <odp_buffer_pool_internal.h>
 #include <odp_internal.h>
-#include <odp_atomic.h>
-#include <odp_spinlock.h>
-#include <odp_sync.h>
-#include <odp_debug.h>
 
 #include <signal.h>
 #include <time.h>