Explorar el Código

core: make the Queue object work with several producers, and get rid of

the idiotic memmove() we were using.
legacy
Sam Hocevar sam hace 13 años
padre
commit
c2a8082c09
Se han modificado 1 ficheros con 31 adiciones y 20 borrados
  1. +31
    -20
      src/thread/threadbase.h

+ 31
- 20
src/thread/threadbase.h Ver fichero

@@ -82,17 +82,19 @@ public:
{
#if defined __linux__ || defined __native_client__
memset(m_values, 0, sizeof(m_values));
m_waiting = 0;
m_size = 0;
m_start = m_count = 0;
m_poppers = m_pushers = 0;
pthread_mutex_init(&m_mutex, NULL);
pthread_cond_init(&m_cond, NULL);
pthread_cond_init(&m_empty_cond, NULL);
pthread_cond_init(&m_full_cond, NULL);
#endif
}

~QueueBase()
{
#if defined __linux__ || defined __native_client__
pthread_cond_destroy(&m_cond);
pthread_cond_destroy(&m_empty_cond);
pthread_cond_destroy(&m_full_cond);
pthread_mutex_destroy(&m_mutex);
#endif
}
@@ -101,10 +103,17 @@ public:
{
#if defined __linux__ || defined __native_client__
pthread_mutex_lock(&m_mutex);
m_values[m_size] = value;
m_size++;
if (m_waiting)
pthread_cond_signal(&m_cond);
/* If queue is full, wait on the "full" cond var. */
m_pushers++;
while (m_count == 100)
pthread_cond_wait(&m_full_cond, &m_mutex);
m_pushers--;
/* Push value */
m_values[(m_start + m_count) % 100] = value;
m_count++;
/* If there were poppers waiting, signal the "empty" cond var. */
if (m_poppers)
pthread_cond_signal(&m_empty_cond);
pthread_mutex_unlock(&m_mutex);
#endif
}
@@ -113,18 +122,20 @@ public:
{
#if defined __linux__ || defined __native_client__
pthread_mutex_lock(&m_mutex);
/* Loop until there is something in the queue. Be careful, we
/* Wait until there is something in the queue. Be careful, we
* could get woken up but another thread may have eaten the
* message in the meantime. */
while (!m_size)
{
m_waiting++;
pthread_cond_wait(&m_cond, &m_mutex);
m_waiting--;
}
m_size--;
int ret = m_values[0];
memmove(m_values, m_values + 1, m_size * sizeof(m_values[0]));
m_poppers++;
while (m_count == 0)
pthread_cond_wait(&m_empty_cond, &m_mutex);
m_poppers--;
/* Pop value */
int ret = m_values[m_start];
m_start = (m_start + 1) % 100;
m_count--;
/* If there were pushers waiting, signal the "full" cond var. */
if (m_pushers)
pthread_cond_signal(&m_full_cond);
pthread_mutex_unlock(&m_mutex);
return ret;
#endif
@@ -133,9 +144,9 @@ public:
private:
#if defined __linux__ || defined __native_client__
int m_values[100];
size_t m_waiting, m_size;
size_t m_poppers, m_pushers, m_start, m_count;
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
pthread_cond_t m_empty_cond, m_full_cond;
#endif
};



Cargando…
Cancelar
Guardar