#if USE_COHERENT_MEM
typedef struct bakery_lock {
- int owner;
/*
* The lock_data is a bit-field of 2 members:
* Bit[0] : choosing. This field is set when the CPU is
volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS];
} bakery_lock_t;
-#define NO_OWNER (-1)
-
void bakery_lock_init(bakery_lock_t *bakery);
void bakery_lock_get(bakery_lock_t *bakery);
void bakery_lock_release(bakery_lock_t *bakery);
assert(entry < BAKERY_LOCK_MAX_CPUS); \
} while (0)
-/* Initialize Bakery Lock to reset ownership and all ticket values */
+/* Initialize Bakery Lock to reset all ticket values */
void bakery_lock_init(bakery_lock_t *bakery)
{
assert(bakery);
/* All ticket values need to be 0 */
memset(bakery, 0, sizeof(*bakery));
- bakery->owner = NO_OWNER;
}
unsigned int my_ticket, their_ticket;
unsigned int they;
+ /* Prevent recursive acquisition */
+ assert(!bakery_ticket_number(bakery->lock_data[me]));
+
/*
* Flag that we're busy getting our ticket. All CPUs are iterated in the
* order of their ordinal position to decide the maximum ticket value
assert_bakery_entry_valid(me, bakery);
- /* Prevent recursive acquisition */
- assert(bakery->owner != me);
-
/* Get a ticket */
my_ticket = bakery_get_ticket(bakery, me);
bakery_ticket_number(bakery->lock_data[they]));
}
}
-
/* Lock acquired */
- bakery->owner = me;
}
unsigned int me = platform_get_core_pos(read_mpidr_el1());
assert_bakery_entry_valid(me, bakery);
- assert(bakery->owner == me);
+ assert(bakery_ticket_number(bakery->lock_data[me]));
/*
- * Release lock by resetting ownership and ticket. Then signal other
+ * Release lock by resetting ticket. Then signal other
* waiting contenders
*/
- bakery->owner = NO_OWNER;
bakery->lock_data[me] = 0;
dsb();
sev();
my_bakery_info = get_my_bakery_info(offset, id);
assert(my_bakery_info);
+ /*
+ * Prevent recursive acquisition.
+ * Since lock data is written to and cleaned by the owning cpu, it
+ * doesn't require any cache operations prior to reading the lock data.
+ */
+ assert(!bakery_ticket_number(my_bakery_info->lock_data));
+
/*
* Tell other contenders that we are through the bakery doorway i.e.
* going to allocate a ticket for this cpu.
== bakery_ticket_number(their_bakery_info->lock_data));
}
}
+ /* Lock acquired */
}
void bakery_lock_release(unsigned int id, unsigned int offset)
unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT;
my_bakery_info = get_my_bakery_info(offset, id);
+ assert(bakery_ticket_number(my_bakery_info->lock_data));
+
my_bakery_info->lock_data = 0;
write_cache_op(my_bakery_info, is_cached);
sev();