/** * Recursive lock of the malloc */ void __malloc_lock(struct _reent *ptr) { uint32_t timerenable, interruptenable; uint32_t id, old_owner; // Disable timer and interrupt exception, store TEE and IEE flag temporarily // to restore them later on unlock timerenable = or1k_timer_disable(); interruptenable = or1k_interrupts_disable(); // Now we cannot be disturbed by an interrupt or timer exception id = (uint32_t) ptr; // Our id is the address of the reentrancy data do { do { // Read current lock owner old_owner = or1k_sync_ll(&_malloc_lock_own); // .. and spin while it is locked and we are not the owner } while (old_owner && (old_owner != id)); } while (!or1k_sync_sc(&_malloc_lock_own, id)); // Store the TEE and IEE flags for later restore _malloc_lock_restore_timer = timerenable; _malloc_lock_restore_interrupts = interruptenable; // Increment counter. The lock may be accessed recursively _malloc_lock_cnt++; return; }
int main(void) { uint32_t ticks = 0; uint32_t timerstate; or1k_timer_init(100); gpio_init(); or1k_timer_enable(); while (1) { while (ticks == or1k_timer_get_ticks()) { } ticks++; timerstate = or1k_timer_disable(); // do something atomar or1k_timer_restore(timerstate); if (ticks == 100) { printf("A second elapsed\n"); // Increment the GPIO counter gpio_increment(); or1k_timer_reset_ticks(); ticks = 0; } } return 0; }
uint32_t or1k_critical_begin() { uint32_t iee = or1k_interrupts_disable(); uint32_t tee = or1k_timer_disable(); return (iee << 1) | tee; }