7 * chunk can be accessed by either consumer OR producer, not both at same time
11 char data
[CHUNK_SIZE
];
13 /* index to data, first filled byte */
16 /* index to data, last filled byte + 1
18 * there are h - l bytes available (filled)
22 /* if chunk is marked filled it can only be accessed by consumer
23 * otherwise only producer is allowed to access the chunk
25 unsigned int filled
: 1;
28 unsigned int buffer_nr_chunks
;
30 static pthread_mutex_t buffer_mutex
= CMUS_MUTEX_INITIALIZER
;
31 static struct chunk
*buffer_chunks
= NULL
;
32 static unsigned int buffer_ridx
;
33 static unsigned int buffer_widx
;
35 void buffer_init(void)
38 buffer_chunks
= xnew(struct chunk
, buffer_nr_chunks
);
43 * @pos: returned pointer to available data
45 * Returns number of bytes available at @pos
47 * After reading bytes mark them consumed calling buffer_consume().
49 int buffer_get_rpos(char **pos
)
54 cmus_mutex_lock(&buffer_mutex
);
55 c
= &buffer_chunks
[buffer_ridx
];
58 *pos
= c
->data
+ c
->l
;
60 cmus_mutex_unlock(&buffer_mutex
);
66 * @pos: pointer to buffer position where data can be written
68 * Returns number of bytes can be written to @pos. If the return value is
69 * non-zero it is guaranteed to be >= 1024.
71 * After writing bytes mark them filled calling buffer_fill().
73 int buffer_get_wpos(char **pos
)
78 cmus_mutex_lock(&buffer_mutex
);
79 c
= &buffer_chunks
[buffer_widx
];
81 size
= CHUNK_SIZE
- c
->h
;
82 *pos
= c
->data
+ c
->h
;
84 cmus_mutex_unlock(&buffer_mutex
);
89 void buffer_consume(int count
)
94 cmus_mutex_lock(&buffer_mutex
);
95 c
= &buffer_chunks
[buffer_ridx
];
103 buffer_ridx
%= buffer_nr_chunks
;
105 cmus_mutex_unlock(&buffer_mutex
);
108 /* chunk is marked filled if free bytes < 1024 or count == 0 */
109 int buffer_fill(int count
)
114 cmus_mutex_lock(&buffer_mutex
);
115 c
= &buffer_chunks
[buffer_widx
];
119 if (CHUNK_SIZE
- c
->h
< 1024 || (count
== 0 && c
->h
> 0)) {
122 buffer_widx
%= buffer_nr_chunks
;
126 cmus_mutex_unlock(&buffer_mutex
);
130 void buffer_reset(void)
134 cmus_mutex_lock(&buffer_mutex
);
137 for (i
= 0; i
< buffer_nr_chunks
; i
++) {
138 buffer_chunks
[i
].l
= 0;
139 buffer_chunks
[i
].h
= 0;
140 buffer_chunks
[i
].filled
= 0;
142 cmus_mutex_unlock(&buffer_mutex
);
145 int buffer_get_filled_chunks(void)
149 cmus_mutex_lock(&buffer_mutex
);
150 if (buffer_ridx
< buffer_widx
) {
158 c
= buffer_widx
- buffer_ridx
;
159 } else if (buffer_ridx
> buffer_widx
) {
167 c
= buffer_nr_chunks
- buffer_ridx
+ buffer_widx
;
178 if (buffer_chunks
[buffer_ridx
].filled
) {
179 c
= buffer_nr_chunks
;
184 cmus_mutex_unlock(&buffer_mutex
);