SCM Library
Spherical Cube Map rendering library
 All Classes Files Functions Variables Friends Pages
scm-queue.hpp
1 // Copyright (C) 2011-2012 Robert Kooima
2 //
3 // LIBSCM is free software; you can redistribute it and/or modify it under the
4 // terms of the GNU General Public License as published by the Free Software
5 // Foundation; either version 2 of the License, or (at your option) any later
6 // version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITH-
9 // OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 // more details.
12 
13 #ifndef SCM_QUEUE_HPP
14 #define SCM_QUEUE_HPP
15 
16 #include <SDL.h>
17 #include <SDL_thread.h>
18 
19 #include <set>
20 
21 //------------------------------------------------------------------------------
22 
35 
36 template <typename T> class scm_queue
37 {
38 public:
39 
40  scm_queue(int n);
41  ~scm_queue();
42 
43  bool try_insert(T&);
44  bool try_remove(T&);
45 
46  void insert(T);
47  T remove( );
48 
49 private:
50 
51  SDL_sem *full_slots;
52  SDL_sem *free_slots;
53  SDL_mutex *data_mutex;
54 
55  std::set<T> S;
56 };
57 
58 //------------------------------------------------------------------------------
59 
62 
63 template <typename T> scm_queue<T>::scm_queue(int n)
64 {
65  full_slots = SDL_CreateSemaphore(0);
66  free_slots = SDL_CreateSemaphore(n);
67  data_mutex = SDL_CreateMutex();
68 }
69 
71 
72 template <typename T> scm_queue<T>::~scm_queue()
73 {
74  SDL_DestroyMutex (data_mutex);
75  SDL_DestroySemaphore(free_slots);
76  SDL_DestroySemaphore(full_slots);
77 }
78 
79 //------------------------------------------------------------------------------
80 
82 
83 template <typename T> bool scm_queue<T>::try_insert(T& d)
84 {
85  if (SDL_SemTryWait(free_slots) == 0)
86  {
87  SDL_LockMutex(data_mutex);
88  {
89  S.insert(d);
90  }
91  SDL_UnlockMutex(data_mutex);
92  SDL_SemPost(full_slots);
93  return true;
94  }
95  return false;
96 }
97 
99 
100 template <typename T> bool scm_queue<T>::try_remove(T& d)
101 {
102  if (SDL_SemTryWait(full_slots) == 0)
103  {
104  SDL_LockMutex(data_mutex);
105  {
106  d = *(S.begin());
107  S.erase(S.begin());
108  }
109  SDL_UnlockMutex(data_mutex);
110  SDL_SemPost(free_slots);
111  return true;
112  }
113  return false;
114 }
115 
116 //------------------------------------------------------------------------------
117 
119 
120 template <typename T> void scm_queue<T>::insert(T d)
121 {
122  SDL_SemWait(free_slots);
123  SDL_LockMutex(data_mutex);
124  {
125  S.insert(d);
126  }
127  SDL_UnlockMutex(data_mutex);
128  SDL_SemPost(full_slots);
129 }
130 
132 
133 template <typename T> T scm_queue<T>::remove()
134 {
135  T d;
136 
137  SDL_SemWait(full_slots);
138  SDL_LockMutex(data_mutex);
139  {
140  d = *(S.begin());
141  S.erase(S.begin());
142  }
143  SDL_UnlockMutex(data_mutex);
144  SDL_SemPost(free_slots);
145 
146  return d;
147 }
148 
149 //------------------------------------------------------------------------------
150 
151 #endif
T remove()
Blocking dequeue for use by the loader threads.
Definition: scm-queue.hpp:133
bool try_remove(T &)
Non-blocking dequeue for use by the render thread.
Definition: scm-queue.hpp:100
An scm_queue implements a templated producer-consumer priority queue.
Definition: scm-queue.hpp:36
void insert(T)
Blocking enqueue for use by the loader threads.
Definition: scm-queue.hpp:120
scm_queue(int n)
Create a new queue with n slots. Initialize counting semaphores for full slots and empty slots...
Definition: scm-queue.hpp:63
bool try_insert(T &)
Non-blocking enqueue for use by the render thread.
Definition: scm-queue.hpp:83
~scm_queue()
Finalize a queue and release its mutex and semaphores.
Definition: scm-queue.hpp:72