Esempio n. 1
0
void vtimer_remove(vtimer_t *t)
{
    unsigned irq_state = disableIRQ();

    priority_queue_remove(&shortterm_priority_queue_root, timer_get_node(t));
    priority_queue_remove(&longterm_priority_queue_root, timer_get_node(t));
    update_shortterm();

    restoreIRQ(irq_state);

}
Esempio n. 2
0
void condition_variable::wait(unique_lock<mutex>& lock) noexcept {
#ifdef NOEXCEPTIONS
  lock.owns_lock();
#else
  if (!lock.owns_lock()) {
    throw std::system_error(
      std::make_error_code(std::errc::operation_not_permitted),
      "Mutex not locked.");
  }
#endif
  priority_queue_node_t n;
  n.priority = sched_active_thread->priority;
  n.data = sched_active_pid;
  n.next = NULL;
  // the signaling thread may not hold the mutex, the queue is not thread safe
  unsigned old_state = disableIRQ();
  priority_queue_add(&m_queue, &n);
  restoreIRQ(old_state);
  mutex_unlock_and_sleep(lock.mutex()->native_handle());
  if (n.data != -1u) {
    // on signaling n.data is set to -1u
    // if it isn't set, then the wakeup is either spurious or a timer wakeup
    old_state = disableIRQ();
    priority_queue_remove(&m_queue, &n);
    restoreIRQ(old_state);
  }
  mutex_lock(lock.mutex()->native_handle());
}
Esempio n. 3
0
int pthread_cond_wait(struct pthread_cond_t *cond, struct mutex_t *mutex)
{
    priority_queue_node_t n;
    n.priority = sched_active_thread->priority;
    n.data = sched_active_thread->pid;
    n.next = NULL;

    /* the signaling thread may not hold the mutex, the queue is not thread safe */
    unsigned old_state = disableIRQ();
    priority_queue_add(&(cond->queue), &n);
    restoreIRQ(old_state);

    mutex_unlock_and_sleep(mutex);

    if (n.data != -1u) {
        /* on signaling n.data is set to -1u */
        /* if it isn't set, then the wakeup is either spurious or a timer wakeup */
        old_state = disableIRQ();
        priority_queue_remove(&(cond->queue), &n);
        restoreIRQ(old_state);
    }

    mutex_lock(mutex);
    return 0;
}
Esempio n. 4
0
static int pthread_rwlock_lock(pthread_rwlock_t *rwlock,
                               bool (*is_blocked)(const pthread_rwlock_t *rwlock),
                               bool is_writer,
                               int incr_when_held,
                               bool allow_spurious)
{
    if (rwlock == NULL) {
        DEBUG("Thread %" PRIkernel_pid": pthread_rwlock_%s(): is_writer=%u, allow_spurious=%u %s\n",
              thread_getpid(), "lock", is_writer, allow_spurious, "rwlock=NULL");
        return EINVAL;
    }

    mutex_lock(&rwlock->mutex);
    if (!is_blocked(rwlock)) {
        DEBUG("Thread %" PRIkernel_pid ": pthread_rwlock_%s(): is_writer=%u, allow_spurious=%u %s\n",
              thread_getpid(), "lock", is_writer, allow_spurious, "is open");
        rwlock->readers += incr_when_held;
    }
    else {
        DEBUG("Thread %" PRIkernel_pid ": pthread_rwlock_%s(): is_writer=%u, allow_spurious=%u %s\n",
              thread_getpid(), "lock", is_writer, allow_spurious, "is locked");

        /* queue for the lock */
        __pthread_rwlock_waiter_node_t waiting_node = {
            .is_writer = is_writer,
            .thread = (thread_t *) sched_active_thread,
            .qnode = {
                .next = NULL,
                .data = (uintptr_t) &waiting_node,
                .priority = sched_active_thread->priority,
            },
            .continue_ = false,
        };
        priority_queue_add(&rwlock->queue, &waiting_node.qnode);

        while (1) {
            /* wait to be unlocked, so this thread can try to acquire the lock again */
            mutex_unlock_and_sleep(&rwlock->mutex);

            mutex_lock(&rwlock->mutex);
            if (waiting_node.continue_) {
                /* pthread_rwlock_unlock() already set rwlock->readers */
                DEBUG("Thread %" PRIkernel_pid ": pthread_rwlock_%s(): is_writer=%u, allow_spurious=%u %s\n",
                      thread_getpid(), "lock", is_writer, allow_spurious, "continued");
                break;
            }
            else if (allow_spurious) {
                DEBUG("Thread %" PRIkernel_pid ": pthread_rwlock_%s(): is_writer=%u, allow_spurious=%u %s\n",
                      thread_getpid(), "lock", is_writer, allow_spurious, "is timed out");
                priority_queue_remove(&rwlock->queue, &waiting_node.qnode);
                mutex_unlock(&rwlock->mutex);
                return ETIMEDOUT;
            }
        }
    }
    mutex_unlock(&rwlock->mutex);

    return 0;
}
Esempio n. 5
0
static int set_longterm(vtimer_t *timer)
{
    timer->priority_queue_entry.priority = timer->absolute.seconds;
    /* *** UGLY FIX BEGINS *** */
    /* Workaround for a bug in a so far undiscovered location which causes the
     * vtimer to add the same timer twice, locking the system in an infinite
     * loop inside priority_queue_add. */
    priority_queue_remove(&longterm_priority_queue_root, timer_get_node(timer));
    /* *** UGLY FIX ENDS *** */
    priority_queue_add(&longterm_priority_queue_root, timer_get_node(timer));
    return 0;
}
Esempio n. 6
0
static int set_shortterm(vtimer_t *timer)
{
    DEBUG("set_shortterm(): Absolute: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds);
    timer->priority_queue_entry.priority = timer->absolute.microseconds;
    /* *** UGLY FIX BEGINS *** */
    /* Workaround for a bug in a so far undiscovered location which causes the
     * vtimer to add the same timer twice, locking the system in an infinite
     * loop inside priority_queue_add. */
    priority_queue_remove(&shortterm_priority_queue_root, timer_get_node(timer));
    /* *** UGLY FIX ENDS *** */
    priority_queue_add(&shortterm_priority_queue_root, timer_get_node(timer));
    return 1;
}