Changeset 1101


Ignore:
Timestamp:
Nov 30, 2011, 7:31:34 PM (9 years ago)
Author:
gary
Message:

core: implement Queue on Win32 and on the PS3.

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/platform/ps3/threadbase.h

    r1097 r1101  
    5353};
    5454
    55 class ConditionBase
     55class QueueBase
    5656{
    5757public:
    58     ConditionBase()
     58    QueueBase()
    5959    {
     60        m_start = m_count = 0;
     61        m_poppers = m_pushers = 0;
     62
     63        sys_lwmutex_attribute_t mattr;
     64        sys_lwmutex_attribute_initialize(mattr);
     65        sys_lwmutex_create(&m_mutex, &mattr);
     66
     67        sys_lwcond_attribute_t cattr;
     68        sys_lwcond_attribute_initialize(cattr);
     69        sys_lwcond_create(&m_empty_cond, &m_mutex, &cattr);
     70        sys_lwcond_create(&m_full_cond, &m_mutex, &cattr);
    6071    }
    6172
    62     ~ConditionBase()
     73    ~QueueBase()
    6374    {
     75        while (sys_lwcond_destroy(&m_empty_cond) == EBUSY)
     76            ;
     77        while (sys_lwcond_destroy(&m_full_cond) == EBUSY)
     78            ;
     79        while (sys_lwmutex_destroy(&m_mutex) == EBUSY)
     80            ;
    6481    }
    6582
    66     void Acquire()
     83    void Push(int value)
    6784    {
     85        /* FIXME: this is a copy of the pthread implementation, but we
     86         * should really use libsync2 instead. */
     87        sys_lwmutex_lock(&m_mutex, 0);
     88        m_pushers++;
     89        while (m_count == CAPACITY)
     90            sys_lwcond_wait(&m_full_cond, 0);
     91        m_pushers--;
     92        m_values[(m_start + m_count) % CAPACITY] = value;
     93        m_count++;
     94        if (m_poppers)
     95            sys_lwcond_signal(&m_empty_cond);
     96        sys_lwmutex_unlock(&m_mutex);
    6897    }
    6998
    70     void Release()
     99    int Pop()
    71100    {
    72     }
    73 
    74     void Wait()
    75     {
    76     }
    77 
    78     void Notify()
    79     {
     101        sys_lwmutex_lock(&m_mutex, 0);
     102        m_poppers++;
     103        while (m_count == 0)
     104            sys_lwcond_wait(&m_empty_cond, 0);
     105        m_poppers--;
     106        int ret = m_values[m_start];
     107        m_start = (m_start + 1) % CAPACITY;
     108        m_count--;
     109        if (m_pushers)
     110            sys_lwcond_signal(&m_full_cond);
     111        sys_lwmutex_unlock(&m_mutex);
     112        return ret;
    80113    }
    81114
    82115private:
     116    static size_t const CAPACITY = 100;
     117    int m_values[CAPACITY];
     118    size_t m_start, m_count;
     119    size_t m_poppers, m_pushers;
     120    sys_lwmutex_t m_mutex;
     121    sys_lwcond_t m_empty_cond, m_full_cond;
    83122};
    84123
  • trunk/src/thread/threadbase.h

    r1099 r1101  
    8181    QueueBase()
    8282    {
    83 #if defined __linux__ || defined __native_client__
    84         memset(m_values, 0, sizeof(m_values));
    8583        m_start = m_count = 0;
     84#if defined __linux__ || defined __native_client__
    8685        m_poppers = m_pushers = 0;
    8786        pthread_mutex_init(&m_mutex, NULL);
    8887        pthread_cond_init(&m_empty_cond, NULL);
    8988        pthread_cond_init(&m_full_cond, NULL);
     89#elif defined _WIN32
     90        m_empty_sem = CreateSemaphore(NULL, CAPACITY, CAPACITY, NULL);
     91        m_full_sem = CreateSemaphore(NULL, 0, CAPACITY, NULL);
     92        InitializeCriticalSection(&m_mutex);
    9093#endif
    9194    }
     
    97100        pthread_cond_destroy(&m_full_cond);
    98101        pthread_mutex_destroy(&m_mutex);
     102#elif defined _WIN32
     103        CloseHandle(m_empty_sem);
     104        CloseHandle(m_full_sem);
     105        DeleteCriticalSection(&m_mutex);
    99106#endif
    100107    }
     
    106113        /* If queue is full, wait on the "full" cond var. */
    107114        m_pushers++;
    108         while (m_count == 100)
     115        while (m_count == CAPACITY)
    109116            pthread_cond_wait(&m_full_cond, &m_mutex);
    110117        m_pushers--;
     118#elif defined _WIN32
     119        WaitForSingleObject(m_empty_sem, INFINITE);
     120        EnterCriticalSection(&m_mutex);
     121#endif
     122
    111123        /* Push value */
    112         m_values[(m_start + m_count) % 100] = value;
     124        m_values[(m_start + m_count) % CAPACITY] = value;
    113125        m_count++;
     126
     127#if defined __linux__ || defined __native_client__
    114128        /* If there were poppers waiting, signal the "empty" cond var. */
    115129        if (m_poppers)
    116130            pthread_cond_signal(&m_empty_cond);
    117131        pthread_mutex_unlock(&m_mutex);
     132#elif defined _WIN32
     133        LeaveCriticalSection(&m_mutex);
     134        ReleaseSemaphore(m_full_sem, 1, NULL);
    118135#endif
    119136    }
     
    130147            pthread_cond_wait(&m_empty_cond, &m_mutex);
    131148        m_poppers--;
     149#elif defined _WIN32
     150        WaitForSingleObject(m_full_sem, INFINITE);
     151        EnterCriticalSection(&m_mutex);
     152#endif
     153
    132154        /* Pop value */
    133155        int ret = m_values[m_start];
    134         m_start = (m_start + 1) % 100;
     156        m_start = (m_start + 1) % CAPACITY;
    135157        m_count--;
     158
     159#if defined __linux__ || defined __native_client__
    136160        /* If there were pushers waiting, signal the "full" cond var. */
    137161        if (m_pushers)
    138162            pthread_cond_signal(&m_full_cond);
    139163        pthread_mutex_unlock(&m_mutex);
     164#else
     165        LeaveCriticalSection(&m_mutex);
     166        ReleaseSemaphore(m_empty_sem, 1, NULL);
     167#endif
     168
    140169        return ret;
    141 #endif
    142170    }
    143171
    144172private:
    145 #if defined __linux__ || defined __native_client__
    146     int m_values[100];
    147     size_t m_poppers, m_pushers, m_start, m_count;
     173    static size_t const CAPACITY = 100;
     174    int m_values[CAPACITY];
     175    size_t m_start, m_count;
     176#if defined __linux__ || defined __native_client__
     177    size_t m_poppers, m_pushers;
    148178    pthread_mutex_t m_mutex;
    149179    pthread_cond_t m_empty_cond, m_full_cond;
     180#elif defined _WIN32
     181    HANDLE m_empty_sem, m_full_sem;
     182    CRITICAL_SECTION m_mutex;
    150183#endif
    151184};
Note: See TracChangeset for help on using the changeset viewer.