diff mbox

linux-generic: odp_ticketlock.h: implement trylock()

Message ID 1418208917-29915-1-git-send-email-ola.liljedahl@linaro.org
State Accepted
Commit a8614fddb5f577006daf7182f121f4ad0cd9e7ba
Headers show

Commit Message

Ola Liljedahl Dec. 10, 2014, 10:55 a.m. UTC
Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org>
---
(This document/code contribution attached is provided under the terms of
agreement LES-LTM-21309)
Implemented the missing odp_ticketlock_trylock().

 platform/linux-generic/odp_ticketlock.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Bill Fischofer Dec. 10, 2014, 1:29 p.m. UTC | #1
On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl <ola.liljedahl@linaro.org>
wrote:

> Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org>
>

Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>


> ---
> (This document/code contribution attached is provided under the terms of
> agreement LES-LTM-21309)
> Implemented the missing odp_ticketlock_trylock().
>
>  platform/linux-generic/odp_ticketlock.c | 30
> ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>
> diff --git a/platform/linux-generic/odp_ticketlock.c
> b/platform/linux-generic/odp_ticketlock.c
> index 682b01b..6525786 100644
> --- a/platform/linux-generic/odp_ticketlock.c
> +++ b/platform/linux-generic/odp_ticketlock.c
> @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
>                 odp_spin();
>  }
>
> +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
> +{
> +       /* We read 'next_ticket' and 'cur_ticket' non-atomically which
> should
> +        * not be a problem as they are not independent of each other.
> +        * 'cur_ticket' is always <= to 'next_ticket' and if we see an
> +        * older value of 'cur_ticket', this only means the lock will
> +        * look busy and trylock will fail. */
> +       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
> +       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
> +       /* First check that lock is available and possible to take without
> +        * spinning. */
> +       if (next == cur) {
> +               /* Then try to take the lock by incrementing 'next_ticket'
> +                * but only if it still has the original value which is
> +                * equal to 'cur_ticket'.
> +                * We don't have to include 'cur_ticket' in the comparison
> +                * because it cannot be larger than 'next_ticket' (only
> +                * smaller if the lock is busy).
> +                * If CAS fails, it means some other thread intercepted and
> +                * took a ticket which means the lock is not available
> +                * anymore */
> +               if
> (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
> +                                                      &next,
> +                                                      next + 1,
> +                                                      _ODP_MEMMODEL_ACQ,
> +                                                      _ODP_MEMMODEL_RLX))
> +                       return 1;
> +       }
> +       return 0;
> +}
>
>  void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>  {
> --
> 1.9.1
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
Mike Holmes Dec. 18, 2014, 6:02 p.m. UTC | #2
Maxim is this scheduled for 0.7 ? I think the tests from Yan,Barry,Mario
require it

On 10 December 2014 at 08:29, Bill Fischofer <bill.fischofer@linaro.org>
wrote:

>
>
> On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl <ola.liljedahl@linaro.org>
> wrote:
>
>> Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org>
>>
>
> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>
>
>
>> ---
>> (This document/code contribution attached is provided under the terms of
>> agreement LES-LTM-21309)
>> Implemented the missing odp_ticketlock_trylock().
>>
>>  platform/linux-generic/odp_ticketlock.c | 30
>> ++++++++++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>
>> diff --git a/platform/linux-generic/odp_ticketlock.c
>> b/platform/linux-generic/odp_ticketlock.c
>> index 682b01b..6525786 100644
>> --- a/platform/linux-generic/odp_ticketlock.c
>> +++ b/platform/linux-generic/odp_ticketlock.c
>> @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
>>                 odp_spin();
>>  }
>>
>> +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
>> +{
>> +       /* We read 'next_ticket' and 'cur_ticket' non-atomically which
>> should
>> +        * not be a problem as they are not independent of each other.
>> +        * 'cur_ticket' is always <= to 'next_ticket' and if we see an
>> +        * older value of 'cur_ticket', this only means the lock will
>> +        * look busy and trylock will fail. */
>> +       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
>> +       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
>> +       /* First check that lock is available and possible to take without
>> +        * spinning. */
>> +       if (next == cur) {
>> +               /* Then try to take the lock by incrementing 'next_ticket'
>> +                * but only if it still has the original value which is
>> +                * equal to 'cur_ticket'.
>> +                * We don't have to include 'cur_ticket' in the comparison
>> +                * because it cannot be larger than 'next_ticket' (only
>> +                * smaller if the lock is busy).
>> +                * If CAS fails, it means some other thread intercepted
>> and
>> +                * took a ticket which means the lock is not available
>> +                * anymore */
>> +               if
>> (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
>> +                                                      &next,
>> +                                                      next + 1,
>> +                                                      _ODP_MEMMODEL_ACQ,
>> +                                                      _ODP_MEMMODEL_RLX))
>> +                       return 1;
>> +       }
>> +       return 0;
>> +}
>>
>>  void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>>  {
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
Maxim Uvarov Dec. 18, 2014, 9:16 p.m. UTC | #3
On 12/18/2014 09:02 PM, Mike Holmes wrote:
> Maxim is this scheduled for 0.7 ? I think the tests from 
> Yan,Barry,Mario require it
>
If it's ready I think we don't need to wait and include it. Working on 
validation / merge...

Maxim.


> On 10 December 2014 at 08:29, Bill Fischofer 
> <bill.fischofer@linaro.org <mailto:bill.fischofer@linaro.org>> wrote:
>
>
>
>     On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl
>     <ola.liljedahl@linaro.org <mailto:ola.liljedahl@linaro.org>> wrote:
>
>         Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org
>         <mailto:ola.liljedahl@linaro.org>>
>
>
>     Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org
>     <mailto:bill.fischofer@linaro.org>>
>
>         ---
>         (This document/code contribution attached is provided under
>         the terms of
>         agreement LES-LTM-21309)
>         Implemented the missing odp_ticketlock_trylock().
>
>          platform/linux-generic/odp_ticketlock.c | 30
>         ++++++++++++++++++++++++++++++
>          1 file changed, 30 insertions(+)
>
>         diff --git a/platform/linux-generic/odp_ticketlock.c
>         b/platform/linux-generic/odp_ticketlock.c
>         index 682b01b..6525786 100644
>         --- a/platform/linux-generic/odp_ticketlock.c
>         +++ b/platform/linux-generic/odp_ticketlock.c
>         @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t
>         *ticketlock)
>                         odp_spin();
>          }
>
>         +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
>         +{
>         +       /* We read 'next_ticket' and 'cur_ticket'
>         non-atomically which should
>         +        * not be a problem as they are not independent of
>         each other.
>         +        * 'cur_ticket' is always <= to 'next_ticket' and if
>         we see an
>         +        * older value of 'cur_ticket', this only means the
>         lock will
>         +        * look busy and trylock will fail. */
>         +       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
>         +       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
>         +       /* First check that lock is available and possible to
>         take without
>         +        * spinning. */
>         +       if (next == cur) {
>         +               /* Then try to take the lock by incrementing
>         'next_ticket'
>         +                * but only if it still has the original value
>         which is
>         +                * equal to 'cur_ticket'.
>         +                * We don't have to include 'cur_ticket' in
>         the comparison
>         +                * because it cannot be larger than
>         'next_ticket' (only
>         +                * smaller if the lock is busy).
>         +                * If CAS fails, it means some other thread
>         intercepted and
>         +                * took a ticket which means the lock is not
>         available
>         +                * anymore */
>         +               if
>         (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
>         +       &next,
>         +       next + 1,
>         +       _ODP_MEMMODEL_ACQ,
>         +       _ODP_MEMMODEL_RLX))
>         +                       return 1;
>         +       }
>         +       return 0;
>         +}
>
>          void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>          {
>         --
>         1.9.1
>
>
>         _______________________________________________
>         lng-odp mailing list
>         lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>         http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
>     _______________________________________________
>     lng-odp mailing list
>     lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>     http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
>
> -- 
> *Mike Holmes*
> Linaro  Sr Technical Manager
> LNG - ODP
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Ola Liljedahl Dec. 18, 2014, 9:18 p.m. UTC | #4
On 18 December 2014 at 22:16, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:
> On 12/18/2014 09:02 PM, Mike Holmes wrote:
>>
>> Maxim is this scheduled for 0.7 ? I think the tests from Yan,Barry,Mario
>> require it
>>
> If it's ready I think we don't need to wait and include it. Working on
> validation / merge...
The patch is ready (including reviewed).
As it is a pure addition, it cannot break anything.


>
> Maxim.
>
>
>> On 10 December 2014 at 08:29, Bill Fischofer <bill.fischofer@linaro.org
>> <mailto:bill.fischofer@linaro.org>> wrote:
>>
>>
>>
>>     On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl
>>     <ola.liljedahl@linaro.org <mailto:ola.liljedahl@linaro.org>> wrote:
>>
>>         Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org
>>         <mailto:ola.liljedahl@linaro.org>>
>>
>>
>>     Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org
>>     <mailto:bill.fischofer@linaro.org>>
>>
>>         ---
>>         (This document/code contribution attached is provided under
>>         the terms of
>>         agreement LES-LTM-21309)
>>         Implemented the missing odp_ticketlock_trylock().
>>
>>          platform/linux-generic/odp_ticketlock.c | 30
>>         ++++++++++++++++++++++++++++++
>>          1 file changed, 30 insertions(+)
>>
>>         diff --git a/platform/linux-generic/odp_ticketlock.c
>>         b/platform/linux-generic/odp_ticketlock.c
>>         index 682b01b..6525786 100644
>>         --- a/platform/linux-generic/odp_ticketlock.c
>>         +++ b/platform/linux-generic/odp_ticketlock.c
>>         @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t
>>         *ticketlock)
>>                         odp_spin();
>>          }
>>
>>         +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
>>         +{
>>         +       /* We read 'next_ticket' and 'cur_ticket'
>>         non-atomically which should
>>         +        * not be a problem as they are not independent of
>>         each other.
>>         +        * 'cur_ticket' is always <= to 'next_ticket' and if
>>         we see an
>>         +        * older value of 'cur_ticket', this only means the
>>         lock will
>>         +        * look busy and trylock will fail. */
>>         +       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
>>         +       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
>>         +       /* First check that lock is available and possible to
>>         take without
>>         +        * spinning. */
>>         +       if (next == cur) {
>>         +               /* Then try to take the lock by incrementing
>>         'next_ticket'
>>         +                * but only if it still has the original value
>>         which is
>>         +                * equal to 'cur_ticket'.
>>         +                * We don't have to include 'cur_ticket' in
>>         the comparison
>>         +                * because it cannot be larger than
>>         'next_ticket' (only
>>         +                * smaller if the lock is busy).
>>         +                * If CAS fails, it means some other thread
>>         intercepted and
>>         +                * took a ticket which means the lock is not
>>         available
>>         +                * anymore */
>>         +               if
>>         (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
>>         +       &next,
>>         +       next + 1,
>>         +       _ODP_MEMMODEL_ACQ,
>>         +       _ODP_MEMMODEL_RLX))
>>         +                       return 1;
>>         +       }
>>         +       return 0;
>>         +}
>>
>>          void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>>          {
>>         --
>>         1.9.1
>>
>>
>>         _______________________________________________
>>         lng-odp mailing list
>>         lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>         http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>>
>>     _______________________________________________
>>     lng-odp mailing list
>>     lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>     http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>>
>>
>> --
>> *Mike Holmes*
>> Linaro  Sr Technical Manager
>> LNG - ODP
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Maxim Uvarov Dec. 18, 2014, 9:23 p.m. UTC | #5
Merged,

Maxim,

On 12/10/2014 01:55 PM, Ola Liljedahl wrote:
> Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org>
> ---
> (This document/code contribution attached is provided under the terms of
> agreement LES-LTM-21309)
> Implemented the missing odp_ticketlock_trylock().
>
>   platform/linux-generic/odp_ticketlock.c | 30 ++++++++++++++++++++++++++++++
>   1 file changed, 30 insertions(+)
>
> diff --git a/platform/linux-generic/odp_ticketlock.c b/platform/linux-generic/odp_ticketlock.c
> index 682b01b..6525786 100644
> --- a/platform/linux-generic/odp_ticketlock.c
> +++ b/platform/linux-generic/odp_ticketlock.c
> @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
>   		odp_spin();
>   }
>   
> +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
> +{
> +	/* We read 'next_ticket' and 'cur_ticket' non-atomically which should
> +	 * not be a problem as they are not independent of each other.
> +	 * 'cur_ticket' is always <= to 'next_ticket' and if we see an
> +	 * older value of 'cur_ticket', this only means the lock will
> +	 * look busy and trylock will fail. */
> +	uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
> +	uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
> +	/* First check that lock is available and possible to take without
> +	 * spinning. */
> +	if (next == cur) {
> +		/* Then try to take the lock by incrementing 'next_ticket'
> +		 * but only if it still has the original value which is
> +		 * equal to 'cur_ticket'.
> +		 * We don't have to include 'cur_ticket' in the comparison
> +		 * because it cannot be larger than 'next_ticket' (only
> +		 * smaller if the lock is busy).
> +		 * If CAS fails, it means some other thread intercepted and
> +		 * took a ticket which means the lock is not available
> +		 * anymore */
> +		if (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
> +						       &next,
> +						       next + 1,
> +						       _ODP_MEMMODEL_ACQ,
> +						       _ODP_MEMMODEL_RLX))
> +			return 1;
> +	}
> +	return 0;
> +}
>   
>   void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>   {
Maxim Uvarov Dec. 18, 2014, 9:25 p.m. UTC | #6
On 12/19/2014 12:18 AM, Ola Liljedahl wrote:
> On 18 December 2014 at 22:16, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:
>> On 12/18/2014 09:02 PM, Mike Holmes wrote:
>>> Maxim is this scheduled for 0.7 ? I think the tests from Yan,Barry,Mario
>>> require it
>>>
>> If it's ready I think we don't need to wait and include it. Working on
>> validation / merge...
> The patch is ready (including reviewed).
> As it is a pure addition, it cannot break anything.

As Linus said never never trust to "it cannot break anything" and always 
test patches before inclusion.
Even in odp I found several times that one line patch may not compile 
for non x86.

Maxim.

>
>> Maxim.
>>
>>
>>> On 10 December 2014 at 08:29, Bill Fischofer <bill.fischofer@linaro.org
>>> <mailto:bill.fischofer@linaro.org>> wrote:
>>>
>>>
>>>
>>>      On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl
>>>      <ola.liljedahl@linaro.org <mailto:ola.liljedahl@linaro.org>> wrote:
>>>
>>>          Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org
>>>          <mailto:ola.liljedahl@linaro.org>>
>>>
>>>
>>>      Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org
>>>      <mailto:bill.fischofer@linaro.org>>
>>>
>>>          ---
>>>          (This document/code contribution attached is provided under
>>>          the terms of
>>>          agreement LES-LTM-21309)
>>>          Implemented the missing odp_ticketlock_trylock().
>>>
>>>           platform/linux-generic/odp_ticketlock.c | 30
>>>          ++++++++++++++++++++++++++++++
>>>           1 file changed, 30 insertions(+)
>>>
>>>          diff --git a/platform/linux-generic/odp_ticketlock.c
>>>          b/platform/linux-generic/odp_ticketlock.c
>>>          index 682b01b..6525786 100644
>>>          --- a/platform/linux-generic/odp_ticketlock.c
>>>          +++ b/platform/linux-generic/odp_ticketlock.c
>>>          @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t
>>>          *ticketlock)
>>>                          odp_spin();
>>>           }
>>>
>>>          +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
>>>          +{
>>>          +       /* We read 'next_ticket' and 'cur_ticket'
>>>          non-atomically which should
>>>          +        * not be a problem as they are not independent of
>>>          each other.
>>>          +        * 'cur_ticket' is always <= to 'next_ticket' and if
>>>          we see an
>>>          +        * older value of 'cur_ticket', this only means the
>>>          lock will
>>>          +        * look busy and trylock will fail. */
>>>          +       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
>>>          +       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
>>>          +       /* First check that lock is available and possible to
>>>          take without
>>>          +        * spinning. */
>>>          +       if (next == cur) {
>>>          +               /* Then try to take the lock by incrementing
>>>          'next_ticket'
>>>          +                * but only if it still has the original value
>>>          which is
>>>          +                * equal to 'cur_ticket'.
>>>          +                * We don't have to include 'cur_ticket' in
>>>          the comparison
>>>          +                * because it cannot be larger than
>>>          'next_ticket' (only
>>>          +                * smaller if the lock is busy).
>>>          +                * If CAS fails, it means some other thread
>>>          intercepted and
>>>          +                * took a ticket which means the lock is not
>>>          available
>>>          +                * anymore */
>>>          +               if
>>>          (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
>>>          +       &next,
>>>          +       next + 1,
>>>          +       _ODP_MEMMODEL_ACQ,
>>>          +       _ODP_MEMMODEL_RLX))
>>>          +                       return 1;
>>>          +       }
>>>          +       return 0;
>>>          +}
>>>
>>>           void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>>>           {
>>>          --
>>>          1.9.1
>>>
>>>
>>>          _______________________________________________
>>>          lng-odp mailing list
>>>          lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>>          http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>>
>>>      _______________________________________________
>>>      lng-odp mailing list
>>>      lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>>      http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>>
>>>
>>> --
>>> *Mike Holmes*
>>> Linaro  Sr Technical Manager
>>> LNG - ODP
>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> lng-odp@lists.linaro.org
>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
Ola Liljedahl Dec. 18, 2014, 10:03 p.m. UTC | #7
On 18 December 2014 at 22:25, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:
> On 12/19/2014 12:18 AM, Ola Liljedahl wrote:
>>
>> On 18 December 2014 at 22:16, Maxim Uvarov <maxim.uvarov@linaro.org>
>> wrote:
>>>
>>> On 12/18/2014 09:02 PM, Mike Holmes wrote:
>>>>
>>>> Maxim is this scheduled for 0.7 ? I think the tests from Yan,Barry,Mario
>>>> require it
>>>>
>>> If it's ready I think we don't need to wait and include it. Working on
>>> validation / merge...
>>
>> The patch is ready (including reviewed).
>> As it is a pure addition, it cannot break anything.
>
>
> As Linus said never never trust to "it cannot break anything" and always
> test patches before inclusion.
> Even in odp I found several times that one line patch may not compile for
> non x86.
I test on x86-64 (but not 32-bit x86) and ARMv7 using GCC 4.8. If it
breaks on some other architecture or with some other compiler it has
to be detected elsewhere and someone post a patch.


>
> Maxim.
>
>>
>>> Maxim.
>>>
>>>
>>>> On 10 December 2014 at 08:29, Bill Fischofer <bill.fischofer@linaro.org
>>>> <mailto:bill.fischofer@linaro.org>> wrote:
>>>>
>>>>
>>>>
>>>>      On Wed, Dec 10, 2014 at 4:55 AM, Ola Liljedahl
>>>>      <ola.liljedahl@linaro.org <mailto:ola.liljedahl@linaro.org>> wrote:
>>>>
>>>>          Signed-off-by: Ola Liljedahl <ola.liljedahl@linaro.org
>>>>          <mailto:ola.liljedahl@linaro.org>>
>>>>
>>>>
>>>>      Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org
>>>>      <mailto:bill.fischofer@linaro.org>>
>>>>
>>>>
>>>>          ---
>>>>          (This document/code contribution attached is provided under
>>>>          the terms of
>>>>          agreement LES-LTM-21309)
>>>>          Implemented the missing odp_ticketlock_trylock().
>>>>
>>>>           platform/linux-generic/odp_ticketlock.c | 30
>>>>          ++++++++++++++++++++++++++++++
>>>>           1 file changed, 30 insertions(+)
>>>>
>>>>          diff --git a/platform/linux-generic/odp_ticketlock.c
>>>>          b/platform/linux-generic/odp_ticketlock.c
>>>>          index 682b01b..6525786 100644
>>>>          --- a/platform/linux-generic/odp_ticketlock.c
>>>>          +++ b/platform/linux-generic/odp_ticketlock.c
>>>>          @@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t
>>>>          *ticketlock)
>>>>                          odp_spin();
>>>>           }
>>>>
>>>>          +int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
>>>>          +{
>>>>          +       /* We read 'next_ticket' and 'cur_ticket'
>>>>          non-atomically which should
>>>>          +        * not be a problem as they are not independent of
>>>>          each other.
>>>>          +        * 'cur_ticket' is always <= to 'next_ticket' and if
>>>>          we see an
>>>>          +        * older value of 'cur_ticket', this only means the
>>>>          lock will
>>>>          +        * look busy and trylock will fail. */
>>>>          +       uint32_t next =
>>>> odp_atomic_load_u32(&tklock->next_ticket);
>>>>          +       uint32_t cur =
>>>> odp_atomic_load_u32(&tklock->cur_ticket);
>>>>          +       /* First check that lock is available and possible to
>>>>          take without
>>>>          +        * spinning. */
>>>>          +       if (next == cur) {
>>>>          +               /* Then try to take the lock by incrementing
>>>>          'next_ticket'
>>>>          +                * but only if it still has the original value
>>>>          which is
>>>>          +                * equal to 'cur_ticket'.
>>>>          +                * We don't have to include 'cur_ticket' in
>>>>          the comparison
>>>>          +                * because it cannot be larger than
>>>>          'next_ticket' (only
>>>>          +                * smaller if the lock is busy).
>>>>          +                * If CAS fails, it means some other thread
>>>>          intercepted and
>>>>          +                * took a ticket which means the lock is not
>>>>          available
>>>>          +                * anymore */
>>>>          +               if
>>>>          (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
>>>>          +       &next,
>>>>          +       next + 1,
>>>>          +       _ODP_MEMMODEL_ACQ,
>>>>          +       _ODP_MEMMODEL_RLX))
>>>>          +                       return 1;
>>>>          +       }
>>>>          +       return 0;
>>>>          +}
>>>>
>>>>           void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
>>>>           {
>>>>          --
>>>>          1.9.1
>>>>
>>>>
>>>>          _______________________________________________
>>>>          lng-odp mailing list
>>>>          lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>>>          http://lists.linaro.org/mailman/listinfo/lng-odp
>>>>
>>>>
>>>>
>>>>      _______________________________________________
>>>>      lng-odp mailing list
>>>>      lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>>>>      http://lists.linaro.org/mailman/listinfo/lng-odp
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> *Mike Holmes*
>>>> Linaro  Sr Technical Manager
>>>> LNG - ODP
>>>>
>>>>
>>>> _______________________________________________
>>>> lng-odp mailing list
>>>> lng-odp@lists.linaro.org
>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> lng-odp@lists.linaro.org
>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
diff mbox

Patch

diff --git a/platform/linux-generic/odp_ticketlock.c b/platform/linux-generic/odp_ticketlock.c
index 682b01b..6525786 100644
--- a/platform/linux-generic/odp_ticketlock.c
+++ b/platform/linux-generic/odp_ticketlock.c
@@ -34,6 +34,36 @@  void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
 		odp_spin();
 }
 
+int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
+{
+	/* We read 'next_ticket' and 'cur_ticket' non-atomically which should
+	 * not be a problem as they are not independent of each other.
+	 * 'cur_ticket' is always <= to 'next_ticket' and if we see an
+	 * older value of 'cur_ticket', this only means the lock will
+	 * look busy and trylock will fail. */
+	uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
+	uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
+	/* First check that lock is available and possible to take without
+	 * spinning. */
+	if (next == cur) {
+		/* Then try to take the lock by incrementing 'next_ticket'
+		 * but only if it still has the original value which is
+		 * equal to 'cur_ticket'.
+		 * We don't have to include 'cur_ticket' in the comparison
+		 * because it cannot be larger than 'next_ticket' (only
+		 * smaller if the lock is busy).
+		 * If CAS fails, it means some other thread intercepted and
+		 * took a ticket which means the lock is not available
+		 * anymore */
+		if (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
+						       &next,
+						       next + 1,
+						       _ODP_MEMMODEL_ACQ,
+						       _ODP_MEMMODEL_RLX))
+			return 1;
+	}
+	return 0;
+}
 
 void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
 {