Phonon

packetpool.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2007-2008 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17
18*/
19
20#include "packetpool.h"
21#include "packetpool_p.h"
22#include "packet.h"
23#include "packet_p.h"
24
25namespace Phonon
26{
27
28int PacketPool::packetSize() const { return d_ptr->packetSize; }
29int PacketPool::poolSize() const { return d_ptr->poolSize; }
30int PacketPool::unusedPackets() const { return d_ptr->ringBufferSize.loadAcquire(); }
31
32PacketPoolPrivate::PacketPoolPrivate(int _packetSize, int _poolSize)
33 : freePackets(new PacketPrivate *[_poolSize]),
34 packetMemory(new char[_packetSize * _poolSize]),
35 readPosition(0), writePosition(0),
36 ringBufferSize(_poolSize),
37 packetSize(_packetSize),
38 poolSize(_poolSize)
39{
40 for (int i = 0; i < _poolSize; ++i) {
41 freePackets[i] = new PacketPrivate(&packetMemory[i * packetSize], this);
42 }
43}
44
45PacketPoolPrivate::~PacketPoolPrivate()
46{
47 Q_ASSERT(poolSize == ringBufferSize.loadAcquire());
48 for (int i = 0; i < poolSize; ++i) {
49 delete freePackets[i];
50 }
51 delete[] freePackets;
52 delete[] packetMemory;
53}
54
55void PacketPoolPrivate::releasePacket(const Packet &packet)
56{
57 const int _writePos = writePosition.fetchAndAddAcquire(1);
58 int pos = _writePos;
59 while (pos >= poolSize) {
60 pos -= poolSize;
61 }
62 writePosition.testAndSetRelease(_writePos, pos);
63 freePackets[pos] = packet.d_ptr;
64 ringBufferSize.ref();
65}
66
67Packet PacketPoolPrivate::acquirePacket()
68{
69 const int s = ringBufferSize.fetchAndAddRelaxed(-1);
70 if (s <= 0) {
71 ringBufferSize.fetchAndAddRelaxed(1);
72 return Packet();
73 }
74 const int _readPos = readPosition.fetchAndAddRelaxed(1);
75 int pos = _readPos;
76 while (pos >= poolSize) {
77 pos -= poolSize;
78 }
79 readPosition.testAndSetRelease(_readPos, pos);
80 freePackets[pos]->m_size = 0;
81 return Packet(*freePackets[pos]);
82}
83
84PacketPool::PacketPool(int packetSize, int _poolSize)
85 : d_ptr(new PacketPoolPrivate(packetSize, _poolSize))
86{
87 d_ptr->ref.ref();
88}
89
91 : d_ptr(rhs.d_ptr)
92{
93 d_ptr->ref.ref();
94}
95
97{
98 if (d_ptr != rhs.d_ptr) {
99 if (!d_ptr->ref.deref()) {
100 delete d_ptr;
101 }
102 d_ptr = rhs.d_ptr;
103 d_ptr->ref.ref();
104 }
105 return *this;
106}
107
109{
110 if (!d_ptr->ref.deref()) {
111 delete d_ptr;
112 }
113}
114
115} // namespace Phonon
Class to preallocate memory.
Definition packetpool.h:38
int poolSize() const
Returns the number of packets that was requested in the constructor.
int packetSize() const
Returns the packet size that was set in the constructor.
int unusedPackets() const
Returns the number of packets that are still available for use.
~PacketPool()
Destructs this object.
PacketPool(int packetSize, int numberOfPackets)
Allocates numberOfPackets packets of packetSize bytes each.
PacketPool & operator=(const PacketPool &)
Assignmen operator.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:58:26 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.