Пример #1
0
int pthread_cond_wait(struct pthread_cond_t *cond, struct mutex_t *mutex)
{
    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();
    queue_priority_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();
        queue_remove(&(cond->queue), &n);
        restoreIRQ(old_state);
    }

    mutex_lock(mutex);
    return 0;
}
Пример #2
0
int main(void)
{
    indicator = 0;
    count = 0;
    mutex_init(&mutex);

    thread_create(stack,
                  KERNEL_CONF_STACKSIZE_MAIN,
                  PRIORITY_MAIN - 1,
                  CREATE_WOUT_YIELD | CREATE_STACKTEST,
                  second_thread,
                  "second_thread");

    while (1) {
        mutex_lock(&mutex);
        thread_wakeup(2);
        indicator++;
        count++;

        if (indicator > 1 || indicator < -1) {
            //printf("Error, threads did not sleep properly. [indicator: %d]\n", indicator);
            return -1;
        }

        if ((count % 100000) == 0) {
            //printf("Still alive alternated [count: %dk] times.\n", count / 1000);
        }

        mutex_unlock_and_sleep(&mutex);
    }
}
Пример #3
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());
}
Пример #4
0
int main(void)
{
    uint32_t count = 0;

    indicator = 0;
    main_pid = thread_getpid();

    kernel_pid_t second_pid = thread_create(stack,
                  sizeof(stack),
                  THREAD_PRIORITY_MAIN - 1,
                  THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
                  second_thread,
                  NULL,
                  "second_thread");

    while (1) {
        mutex_lock(&mutex);
        thread_wakeup(second_pid);
        indicator++;
        count++;

        if ((indicator > 1) || (indicator < -1)) {
            printf("[ERROR] threads did not sleep properly (%d).\n", indicator);
            return 1;
        }
        if ((count % 100000) == 0) {
            printf("[ALIVE] alternated %"PRIu32"k times.\n", (count / 1000));
        }
        mutex_unlock_and_sleep(&mutex);
    }
}
Пример #5
0
int main(void)
{
    indicator = 0;
    count = 0;

    main_pid = thread_getpid();

    kernel_pid_t second_pid = thread_create(stack,
                  sizeof(stack),
                  THREAD_PRIORITY_MAIN - 1,
                  THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
                  second_thread,
                  NULL,
                  "second_thread");

    while (1) {
        mutex_lock(&mutex);
        thread_wakeup(second_pid);
        indicator++;
        count++;

        if (indicator > 1 || indicator < -1) {
            printf("Error, threads did not sleep properly. [indicator: %d]\n", indicator);
            return -1;
        }

        if ((count % 100000) == 0) {
            printf("Still alive alternated [count: %dk] times.\n", count / 1000);
        }

        mutex_unlock_and_sleep(&mutex);
    }
}
Пример #6
0
static void *run_get(void *arg)
{
    (void) arg;

    char next = 0;
    for (unsigned iteration = 0; iteration < ITERATIONS; ++iteration) {
        ++next; /* the first element of a stride is always overwritten */

        mutex_lock(&mutex);

        for (unsigned i = BUF_SIZE; i > 0; --i) {
            assert_avail(i);
            assert_get_one(next);
            assert_avail(i - 1);
            ++next;
        }

        assert_avail(0);
        assert_get_one(-1);
        assert_avail(0);

        thread_wakeup(pid_add);
        mutex_unlock_and_sleep(&mutex);
    }

    return NULL;
}
Пример #7
0
static void run_add(void)
{
    char next = 0;
    for (unsigned iteration = 0; iteration < ITERATIONS; ++iteration) {
        mutex_lock(&mutex);

        for (unsigned i = 0; i < BUF_SIZE; ++i) {
            assert_avail(i);
            assert_add_one(next, -1);
            assert_avail(i + 1);
            ++next;
        }

        /* Overwrite oldest element. It should be returned to us. */
        assert_avail(BUF_SIZE);
        assert_add_one(next, next - BUF_SIZE);
        assert_avail(BUF_SIZE);
        ++next;

        thread_wakeup(pid_get);
        mutex_unlock_and_sleep(&mutex);
    }

    thread_wakeup(pid_get);
}
Пример #8
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;
}
Пример #9
0
static void second_thread(void)
{
    while (1) {
        mutex_lock(&mutex);
        thread_wakeup(1);
        indicator--;
        mutex_unlock_and_sleep(&mutex);
    }
}
Пример #10
0
static void *second_thread(void *arg)
{
    (void) arg;
    while (1) {
        mutex_lock(&mutex);
        thread_wakeup(main_pid);
        indicator--;
        mutex_unlock_and_sleep(&mutex);
    }
    return NULL;
}
Пример #11
0
Файл: main.c Проект: JMR-b/RIOT
/**
 * @brief   This thread tries to lock the mutex to enter the critical section.
 *          Then it signals one waiting thread to check the condition and it goes to sleep again
 *          If is_finished is set to 1 second_thread ends
 */
static void *second_thread(void *arg)
{
    (void) arg;
    while (1) {
        mutex_lock(&mutex);

        if (is_finished == 1) {
            break;
        }

        pthread_cond_signal(&cv);
        mutex_unlock_and_sleep(&mutex);
    }
    return NULL;
}
Пример #12
0
int pthread_barrier_wait(pthread_barrier_t *barrier)
{
    /* Idea: the count is decreased by every thread that waits on the barrier.
     * If the value is bigger than zero afterwards, then the thread has to wait
     * to be woken up. Once the value reaches zero, everyone gets woken up. */

    mutex_lock(&barrier->mutex);
    DEBUG("%s: hit a synchronization barrier. pid=%" PRIkernel_pid"\n",
          sched_active_thread->name, sched_active_pid);

    int switch_prio = -1;

    if (--barrier->count > 0) {
        /* need to wait for further threads */

        DEBUG("%s: waiting for %u threads. pid=%" PRIkernel_pid "\n",
              sched_active_thread->name, barrier->count, sched_active_pid);

        pthread_barrier_waiting_node_t node;
        node.pid = sched_active_pid;
        node.next = barrier->next;
        node.cont = 0;

        barrier->next = &node;
        mutex_unlock(&barrier->mutex);

        while (1) {
            /* The mutex is reacquired before checking if we should continue,
             * so that the waiting thread don't accidentially run before the
             * wake up loop has ended. Otherwise the thread could run into the
             * the barrier again before `barrier->count` was reset. */
            mutex_lock(&barrier->mutex);
            if (node.cont) {
                break;
            }
            mutex_unlock_and_sleep(&barrier->mutex);
        }
    }
    else {
        /* all threads have arrived, wake everybody up */

        DEBUG("%s: waking every other thread up. pid=%" PRIkernel_pid "\n",
              sched_active_thread->name, sched_active_pid);

        int count = 1; /* Count number of woken up threads.
                        * The first thread is the current thread. */
        pthread_barrier_waiting_node_t *next;
        for (next = barrier->next; next; next = next->next) {
            ++count;
            next->cont = 1;

            thread_t *other = (thread_t *) sched_threads[next->pid];
            switch_prio = priority_min(switch_prio, other->priority);
            sched_set_status(other, STATUS_PENDING);
        }
        barrier->next = NULL;
        barrier->count = count;
    }

    mutex_unlock(&barrier->mutex);

    if (switch_prio != -1) {
        sched_switch(switch_prio);
    }

    return 0;
}