bakery: Fix MISRA defects

Change-Id: I600bc13522ae977db355b6dc5a1695bce39ec130
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
This commit is contained in:
Antonio Nino Diaz 2018-10-31 15:55:57 +00:00
parent b8a02d53c0
commit f8b30ca89b
4 changed files with 82 additions and 53 deletions

View File

@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#ifndef __BAKERY_LOCK_H__ #ifndef BAKERY_LOCK_H
#define __BAKERY_LOCK_H__ #define BAKERY_LOCK_H
#include <platform_def.h> #include <platform_def.h>
@ -13,21 +13,39 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <cdefs.h> #include <cdefs.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <utils_def.h>
/***************************************************************************** /*****************************************************************************
* Internal helper macros used by the bakery lock implementation. * Internal helpers used by the bakery lock implementation.
****************************************************************************/ ****************************************************************************/
/* Convert a ticket to priority */ /* Convert a ticket to priority */
#define PRIORITY(t, pos) (((t) << 8) | (pos)) static inline unsigned int bakery_get_priority(unsigned int t, unsigned int pos)
{
return (t << 8) | pos;
}
#define CHOOSING_TICKET 0x1 #define CHOOSING_TICKET U(0x1)
#define CHOSEN_TICKET 0x0 #define CHOSEN_TICKET U(0x0)
#define bakery_is_choosing(info) (info & 0x1) static inline bool bakery_is_choosing(unsigned int info)
#define bakery_ticket_number(info) ((info >> 1) & 0x7FFF) {
#define make_bakery_data(choosing, number) \ return (info & 1U) == CHOOSING_TICKET;
(((choosing & 0x1) | (number << 1)) & 0xFFFF) }
static inline unsigned int bakery_ticket_number(unsigned int info)
{
return (info >> 1) & 0x7FFFU;
}
static inline uint16_t make_bakery_data(unsigned int choosing, unsigned int num)
{
unsigned int val = (choosing & 0x1U) | (num << 1);
return (uint16_t) val;
}
/***************************************************************************** /*****************************************************************************
* External bakery lock interface. * External bakery lock interface.
@ -83,4 +101,4 @@ void bakery_lock_release(bakery_lock_t *bakery);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __BAKERY_LOCK_H__ */ #endif /* BAKERY_LOCK_H */

View File

@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#ifndef __SPINLOCK_H__ #ifndef SPINLOCK_H
#define __SPINLOCK_H__ #define SPINLOCK_H
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
@ -26,4 +26,4 @@ void spin_unlock(spinlock_t *lock);
#endif #endif
#endif /* __SPINLOCK_H__ */ #endif /* SPINLOCK_H */

View File

@ -35,9 +35,9 @@
*/ */
#define assert_bakery_entry_valid(_entry, _bakery) do { \ #define assert_bakery_entry_valid(_entry, _bakery) do { \
assert(_bakery); \ assert((_bakery) != NULL); \
assert(_entry < BAKERY_LOCK_MAX_CPUS); \ assert((_entry) < BAKERY_LOCK_MAX_CPUS); \
} while (0) } while (false)
/* Obtain a ticket for a given CPU */ /* Obtain a ticket for a given CPU */
static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me) static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me)
@ -46,7 +46,7 @@ static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me)
unsigned int they; unsigned int they;
/* Prevent recursive acquisition */ /* Prevent recursive acquisition */
assert(!bakery_ticket_number(bakery->lock_data[me])); assert(bakery_ticket_number(bakery->lock_data[me]) == 0U);
/* /*
* Flag that we're busy getting our ticket. All CPUs are iterated in the * Flag that we're busy getting our ticket. All CPUs are iterated in the
@ -58,9 +58,9 @@ static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me)
* ticket value. That's OK as the lock is acquired based on the priority * ticket value. That's OK as the lock is acquired based on the priority
* value, not the ticket value alone. * value, not the ticket value alone.
*/ */
my_ticket = 0; my_ticket = 0U;
bakery->lock_data[me] = make_bakery_data(CHOOSING_TICKET, my_ticket); bakery->lock_data[me] = make_bakery_data(CHOOSING_TICKET, my_ticket);
for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { for (they = 0U; they < BAKERY_LOCK_MAX_CPUS; they++) {
their_ticket = bakery_ticket_number(bakery->lock_data[they]); their_ticket = bakery_ticket_number(bakery->lock_data[they]);
if (their_ticket > my_ticket) if (their_ticket > my_ticket)
my_ticket = their_ticket; my_ticket = their_ticket;
@ -105,8 +105,8 @@ void bakery_lock_get(bakery_lock_t *bakery)
* Now that we got our ticket, compute our priority value, then compare * Now that we got our ticket, compute our priority value, then compare
* with that of others, and proceed to acquire the lock * with that of others, and proceed to acquire the lock
*/ */
my_prio = PRIORITY(my_ticket, me); my_prio = bakery_get_priority(my_ticket, me);
for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { for (they = 0U; they < BAKERY_LOCK_MAX_CPUS; they++) {
if (me == they) if (me == they)
continue; continue;
@ -120,7 +120,8 @@ void bakery_lock_get(bakery_lock_t *bakery)
* (valid) ticket value. If they do, compare priorities * (valid) ticket value. If they do, compare priorities
*/ */
their_ticket = bakery_ticket_number(their_bakery_data); their_ticket = bakery_ticket_number(their_bakery_data);
if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) { if ((their_ticket != 0U) &&
(bakery_get_priority(their_ticket, they) < my_prio)) {
/* /*
* They have higher priority (lower value). Wait for * They have higher priority (lower value). Wait for
* their ticket value to change (either release the lock * their ticket value to change (either release the lock
@ -148,7 +149,7 @@ void bakery_lock_release(bakery_lock_t *bakery)
unsigned int me = plat_my_core_pos(); unsigned int me = plat_my_core_pos();
assert_bakery_entry_valid(me, bakery); assert_bakery_entry_valid(me, bakery);
assert(bakery_ticket_number(bakery->lock_data[me])); assert(bakery_ticket_number(bakery->lock_data[me]) != 0U);
/* /*
* Ensure that other observers see any stores in the critical section * Ensure that other observers see any stores in the critical section
@ -156,7 +157,7 @@ void bakery_lock_release(bakery_lock_t *bakery)
* Then signal other waiting contenders. * Then signal other waiting contenders.
*/ */
dmbst(); dmbst();
bakery->lock_data[me] = 0; bakery->lock_data[me] = 0U;
dsb(); dsb();
sev(); sev();
} }

View File

@ -53,21 +53,31 @@ CASSERT((PLAT_PERCPU_BAKERY_LOCK_SIZE & (CACHE_WRITEBACK_GRANULE - 1)) == 0, \
IMPORT_SYM(uintptr_t, __PERCPU_BAKERY_LOCK_SIZE__, PERCPU_BAKERY_LOCK_SIZE); IMPORT_SYM(uintptr_t, __PERCPU_BAKERY_LOCK_SIZE__, PERCPU_BAKERY_LOCK_SIZE);
#endif #endif
#define get_bakery_info(_cpu_ix, _lock) \ static inline bakery_lock_t *get_bakery_info(unsigned int cpu_ix,
(bakery_info_t *)((uintptr_t)_lock + _cpu_ix * PERCPU_BAKERY_LOCK_SIZE) bakery_lock_t *lock)
{
return (bakery_info_t *)((uintptr_t)lock +
cpu_ix * PERCPU_BAKERY_LOCK_SIZE);
}
#define write_cache_op(_addr, _cached) \ static inline void write_cache_op(uintptr_t addr, bool cached)
do { \ {
(_cached ? dccvac((uintptr_t)_addr) :\ if (cached)
dcivac((uintptr_t)_addr));\ dccvac(addr);
dsbish();\ else
} while (0) dcivac(addr);
#define read_cache_op(_addr, _cached) if (_cached) \ dsbish();
dccivac((uintptr_t)_addr) }
static inline void read_cache_op(uintptr_t addr, bool cached)
{
if (cached)
dccivac(addr);
}
/* Helper function to check if the lock is acquired */ /* Helper function to check if the lock is acquired */
static inline int is_lock_acquired(const bakery_info_t *my_bakery_info, static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info,
int is_cached) int is_cached)
{ {
/* /*
@ -78,8 +88,8 @@ static inline int is_lock_acquired(const bakery_info_t *my_bakery_info,
* operations were not propagated to all the caches in the system. * operations were not propagated to all the caches in the system.
* Hence do a `read_cache_op()` prior to read. * Hence do a `read_cache_op()` prior to read.
*/ */
read_cache_op(my_bakery_info, is_cached); read_cache_op((uintptr_t)my_bakery_info, is_cached);
return !!(bakery_ticket_number(my_bakery_info->lock_data)); return bakery_ticket_number(my_bakery_info->lock_data) != 0U;
} }
static unsigned int bakery_get_ticket(bakery_lock_t *lock, static unsigned int bakery_get_ticket(bakery_lock_t *lock,
@ -94,7 +104,7 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
* it is not NULL. * it is not NULL.
*/ */
my_bakery_info = get_bakery_info(me, lock); my_bakery_info = get_bakery_info(me, lock);
assert(my_bakery_info); assert(my_bakery_info != NULL);
/* Prevent recursive acquisition.*/ /* Prevent recursive acquisition.*/
assert(!is_lock_acquired(my_bakery_info, is_cached)); assert(!is_lock_acquired(my_bakery_info, is_cached));
@ -103,16 +113,16 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
* Tell other contenders that we are through the bakery doorway i.e. * Tell other contenders that we are through the bakery doorway i.e.
* going to allocate a ticket for this cpu. * going to allocate a ticket for this cpu.
*/ */
my_ticket = 0; my_ticket = 0U;
my_bakery_info->lock_data = make_bakery_data(CHOOSING_TICKET, my_ticket); my_bakery_info->lock_data = make_bakery_data(CHOOSING_TICKET, my_ticket);
write_cache_op(my_bakery_info, is_cached); write_cache_op((uintptr_t)my_bakery_info, is_cached);
/* /*
* Iterate through the bakery information of each contender to allocate * Iterate through the bakery information of each contender to allocate
* the highest ticket number for this cpu. * the highest ticket number for this cpu.
*/ */
for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { for (they = 0U; they < BAKERY_LOCK_MAX_CPUS; they++) {
if (me == they) if (me == they)
continue; continue;
@ -121,9 +131,9 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
* ensure that a stale copy is not read. * ensure that a stale copy is not read.
*/ */
their_bakery_info = get_bakery_info(they, lock); their_bakery_info = get_bakery_info(they, lock);
assert(their_bakery_info); assert(their_bakery_info != NULL);
read_cache_op(their_bakery_info, is_cached); read_cache_op((uintptr_t)their_bakery_info, is_cached);
/* /*
* Update this cpu's ticket number if a higher ticket number is * Update this cpu's ticket number if a higher ticket number is
@ -141,7 +151,7 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
++my_ticket; ++my_ticket;
my_bakery_info->lock_data = make_bakery_data(CHOSEN_TICKET, my_ticket); my_bakery_info->lock_data = make_bakery_data(CHOSEN_TICKET, my_ticket);
write_cache_op(my_bakery_info, is_cached); write_cache_op((uintptr_t)my_bakery_info, is_cached);
return my_ticket; return my_ticket;
} }
@ -167,8 +177,8 @@ void bakery_lock_get(bakery_lock_t *lock)
* Now that we got our ticket, compute our priority value, then compare * Now that we got our ticket, compute our priority value, then compare
* with that of others, and proceed to acquire the lock * with that of others, and proceed to acquire the lock
*/ */
my_prio = PRIORITY(my_ticket, me); my_prio = bakery_get_priority(my_ticket, me);
for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { for (they = 0U; they < BAKERY_LOCK_MAX_CPUS; they++) {
if (me == they) if (me == they)
continue; continue;
@ -177,11 +187,11 @@ void bakery_lock_get(bakery_lock_t *lock)
* ensure that a stale copy is not read. * ensure that a stale copy is not read.
*/ */
their_bakery_info = get_bakery_info(they, lock); their_bakery_info = get_bakery_info(they, lock);
assert(their_bakery_info); assert(their_bakery_info != NULL);
/* Wait for the contender to get their ticket */ /* Wait for the contender to get their ticket */
do { do {
read_cache_op(their_bakery_info, is_cached); read_cache_op((uintptr_t)their_bakery_info, is_cached);
their_bakery_data = their_bakery_info->lock_data; their_bakery_data = their_bakery_info->lock_data;
} while (bakery_is_choosing(their_bakery_data)); } while (bakery_is_choosing(their_bakery_data));
@ -190,7 +200,7 @@ void bakery_lock_get(bakery_lock_t *lock)
* (valid) ticket value. If they do, compare priorities * (valid) ticket value. If they do, compare priorities
*/ */
their_ticket = bakery_ticket_number(their_bakery_data); their_ticket = bakery_ticket_number(their_bakery_data);
if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) { if (their_ticket && (bakery_get_priority(their_ticket, they) < my_prio)) {
/* /*
* They have higher priority (lower value). Wait for * They have higher priority (lower value). Wait for
* their ticket value to change (either release the lock * their ticket value to change (either release the lock
@ -199,7 +209,7 @@ void bakery_lock_get(bakery_lock_t *lock)
*/ */
do { do {
wfe(); wfe();
read_cache_op(their_bakery_info, is_cached); read_cache_op((uintptr_t)their_bakery_info, is_cached);
} while (their_ticket } while (their_ticket
== bakery_ticket_number(their_bakery_info->lock_data)); == bakery_ticket_number(their_bakery_info->lock_data));
} }
@ -231,7 +241,7 @@ void bakery_lock_release(bakery_lock_t *lock)
* Then signal other waiting contenders. * Then signal other waiting contenders.
*/ */
dmbst(); dmbst();
my_bakery_info->lock_data = 0; my_bakery_info->lock_data = 0U;
write_cache_op(my_bakery_info, is_cached); write_cache_op((uintptr_t)my_bakery_info, is_cached);
sev(); sev();
} }