Changeset 1099


Ignore:
Timestamp:
Nov 30, 2011, 4:01:20 PM (9 years ago)
Author:
sam
Message:

core: make the Queue object work with several producers, and get rid of
the idiotic memmove() we were using.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/thread/threadbase.h

    r1098 r1099  
    8383#if defined __linux__ || defined __native_client__
    8484        memset(m_values, 0, sizeof(m_values));
    85         m_waiting = 0;
    86         m_size = 0;
     85        m_start = m_count = 0;
     86        m_poppers = m_pushers = 0;
    8787        pthread_mutex_init(&m_mutex, NULL);
    88         pthread_cond_init(&m_cond, NULL);
     88        pthread_cond_init(&m_empty_cond, NULL);
     89        pthread_cond_init(&m_full_cond, NULL);
    8990#endif
    9091    }
     
    9394    {
    9495#if defined __linux__ || defined __native_client__
    95         pthread_cond_destroy(&m_cond);
     96        pthread_cond_destroy(&m_empty_cond);
     97        pthread_cond_destroy(&m_full_cond);
    9698        pthread_mutex_destroy(&m_mutex);
    9799#endif
     
    102104#if defined __linux__ || defined __native_client__
    103105        pthread_mutex_lock(&m_mutex);
    104         m_values[m_size] = value;
    105         m_size++;
    106         if (m_waiting)
    107             pthread_cond_signal(&m_cond);
     106        /* If queue is full, wait on the "full" cond var. */
     107        m_pushers++;
     108        while (m_count == 100)
     109            pthread_cond_wait(&m_full_cond, &m_mutex);
     110        m_pushers--;
     111        /* Push value */
     112        m_values[(m_start + m_count) % 100] = value;
     113        m_count++;
     114        /* If there were poppers waiting, signal the "empty" cond var. */
     115        if (m_poppers)
     116            pthread_cond_signal(&m_empty_cond);
    108117        pthread_mutex_unlock(&m_mutex);
    109118#endif
     
    114123#if defined __linux__ || defined __native_client__
    115124        pthread_mutex_lock(&m_mutex);
    116         /* Loop until there is something in the queue. Be careful, we
     125        /* Wait until there is something in the queue. Be careful, we
    117126         * could get woken up but another thread may have eaten the
    118127         * message in the meantime. */
    119         while (!m_size)
    120         {
    121             m_waiting++;
    122             pthread_cond_wait(&m_cond, &m_mutex);
    123             m_waiting--;
    124         }
    125         m_size--;
    126         int ret = m_values[0];
    127         memmove(m_values, m_values + 1, m_size * sizeof(m_values[0]));
     128        m_poppers++;
     129        while (m_count == 0)
     130            pthread_cond_wait(&m_empty_cond, &m_mutex);
     131        m_poppers--;
     132        /* Pop value */
     133        int ret = m_values[m_start];
     134        m_start = (m_start + 1) % 100;
     135        m_count--;
     136        /* If there were pushers waiting, signal the "full" cond var. */
     137        if (m_pushers)
     138            pthread_cond_signal(&m_full_cond);
    128139        pthread_mutex_unlock(&m_mutex);
    129140        return ret;
     
    134145#if defined __linux__ || defined __native_client__
    135146    int m_values[100];
    136     size_t m_waiting, m_size;
     147    size_t m_poppers, m_pushers, m_start, m_count;
    137148    pthread_mutex_t m_mutex;
    138     pthread_cond_t m_cond;
     149    pthread_cond_t m_empty_cond, m_full_cond;
    139150#endif
    140151};
Note: See TracChangeset for help on using the changeset viewer.