chiark / gitweb /
Merge from dmanual branch
[disorder] / clients / playrtp-mem.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2007 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 /** @file clients/playrtp-mem.c
19  * @brief RTP player memory management
20  */
21
22 #include "common.h"
23
24 #include <pthread.h>
25
26 #include "mem.h"
27 #include "vector.h"
28 #include "heap.h"
29 #include "playrtp.h"
30
31 /** @brief Linked list of free packets
32  *
33  * This is a linked list of formerly used packets.  For preference we re-use
34  * packets that have already been used rather than unused ones, to limit the
35  * size of the program's working set.  If there are no free packets in the list
36  * we try @ref next_free_packet instead.
37  *
38  * Must hold @ref lock when accessing this.
39  */
40 static union free_packet *free_packets;
41
42 /** @brief Array of new free packets 
43  *
44  * There are @ref count_free_packets ready to use at this address.  If there
45  * are none left we allocate more memory.
46  *
47  * Must hold @ref lock when accessing this.
48  */
49 static union free_packet *next_free_packet;
50
51 /** @brief Count of new free packets at @ref next_free_packet
52  *
53  * Must hold @ref lock when accessing this.
54  */
55 static size_t count_free_packets;
56
57 /** @brief Lock protecting packet allocator */
58 static pthread_mutex_t mem_lock = PTHREAD_MUTEX_INITIALIZER;
59
60 /** @brief Return a new packet */
61 struct packet *playrtp_new_packet(void) {
62   struct packet *p;
63   
64   pthread_mutex_lock(&mem_lock);
65   if(free_packets) {
66     p = &free_packets->p;
67     free_packets = free_packets->next;
68   } else {
69     if(!count_free_packets) {
70       next_free_packet = xcalloc(1024, sizeof (union free_packet));
71       count_free_packets = 1024;
72     }
73     p = &(next_free_packet++)->p;
74     --count_free_packets;
75   }
76   pthread_mutex_unlock(&mem_lock);
77   return p;
78 }
79
80 /** @brief Free a packet */
81 void playrtp_free_packet(struct packet *p) {
82   union free_packet *u = (union free_packet *)p;
83   pthread_mutex_lock(&mem_lock);
84   u->next = free_packets;
85   free_packets = u;
86   pthread_mutex_unlock(&mem_lock);
87 }
88
89
90 /*
91 Local Variables:
92 c-basic-offset:2
93 comment-column:40
94 fill-column:79
95 indent-tabs-mode:nil
96 End:
97 */