Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
1.9KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. SafeQueue.cpp - Yet Another Lockless Ringbuffer
  4. Copyright (C) 2016 Mark McCurry
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. */
  10. template<class T>
  11. SafeQueue<T>::SafeQueue(size_t maxlen)
  12. :writePtr(0), readPtr(0), bufSize(maxlen)
  13. {
  14. w_space.init(PTHREAD_PROCESS_PRIVATE, maxlen - 1);
  15. r_space.init(PTHREAD_PROCESS_PRIVATE, 0);
  16. buffer = new T[maxlen];
  17. }
  18. template<class T>
  19. SafeQueue<T>::~SafeQueue()
  20. {
  21. delete [] buffer;
  22. }
  23. template<class T>
  24. unsigned int SafeQueue<T>::size() const
  25. {
  26. return rSpace();
  27. }
  28. template<class T>
  29. unsigned int SafeQueue<T>::rSpace() const
  30. {
  31. return r_space.getvalue();
  32. }
  33. template<class T>
  34. unsigned int SafeQueue<T>::wSpace() const
  35. {
  36. return w_space.getvalue();
  37. }
  38. template<class T>
  39. int SafeQueue<T>::push(const T &in)
  40. {
  41. if(!wSpace())
  42. return -1;
  43. //ok, there is space to write
  44. size_t w = (writePtr + 1) % bufSize;
  45. buffer[w] = in;
  46. writePtr = w;
  47. //adjust ranges
  48. w_space.wait(); //guaranteed not to wait
  49. r_space.post();
  50. return 0;
  51. }
  52. template<class T>
  53. int SafeQueue<T>::peak(T &out) const
  54. {
  55. if(!rSpace())
  56. return -1;
  57. //ok, there is space to read
  58. size_t r = (readPtr + 1) % bufSize;
  59. out = buffer[r];
  60. return 0;
  61. }
  62. template<class T>
  63. int SafeQueue<T>::pop(T &out)
  64. {
  65. if(!rSpace())
  66. return -1;
  67. //ok, there is space to read
  68. size_t r = (readPtr + 1) % bufSize;
  69. out = buffer[r];
  70. readPtr = r;
  71. //adjust ranges
  72. r_space.wait(); //guaranteed not to wait
  73. w_space.post();
  74. return 0;
  75. }
  76. template<class T>
  77. void SafeQueue<T>::clear()
  78. {
  79. //thread unsafe
  80. while(!r_space.trywait())
  81. w_space.post();
  82. readPtr = writePtr;
  83. }