static int spi_read(struct bathos_pipe *pipe, char *buf, int len) { struct spi_data *data = &spi_data; int flags; int l; interrupt_disable(flags); l = min(len, CIRC_CNT_TO_END(data->cbufrx.head, data->cbufrx.tail, SPI_BUF_SIZE)); if (!l) { interrupt_restore(flags); return -EAGAIN; } memcpy(buf, &data->bufrx[data->cbufrx.tail], l); data->cbufrx.tail = (data->cbufrx.tail + l) & (SPI_BUF_SIZE - 1); data->overrun = 0; if (CIRC_CNT(data->cbufrx.head, data->cbufrx.tail, SPI_BUF_SIZE)) pipe_dev_trigger_event(&__spi_dev, &evt_pipe_input_ready, EVT_PRIO_MAX); interrupt_restore(flags); return l; }
void sema_down (struct semaphore* sema) { ASSERT (sema != NULL); enum interrupt_state state = interrupt_off (); /* All accesses to this semaphore must be synchronized using the semaphore's internal spinlock. */ spinlock_acquire (&sema->sync); /* If the semaphore's value is at 0, then we must block the thread */ while (sema->val == 0) { list_push_back (&sema->waiters, &thread_current ()->elem); // spinlock_release (&sema->sync); thread_block (); // spinlock_acquire (&sema->sync); } /* Decrement the semaphore's value */ sema->val--; spinlock_release (&sema->sync); interrupt_restore (state); interrupt_on (); };
void sema_up (struct semaphore* sema) { ASSERT (sema != NULL); enum interrupt_state state = interrupt_off (); // spinlock_acquire (&sema->sync); sema->val++; struct thread* t = LIST_ENTRY ( list_pop_back (&sema->waiters), struct thread, elem); // spinlock_release (&sema->sync); thread_unblock (t); interrupt_restore (state); };
bool sema_try_down (struct semaphore* sema) { bool result = true; ASSERT (sema != NULL); enum interrupt_state state = interrupt_off (); // spinlock_acquire (&sema->sync); result = (sema->val > 0); if (result) { sema->val--; } // spinlock_release (&sema->sync); interrupt_restore (state); return result; };