#include "buffer_queue.h"
#include "swap_buffer_to_buffer_queue.h"
#include "swap_buffer_errors.h"
+#include "kernel_operations.h"
/* Queue structure. Consist of pointers to the first and the last elements of
* queue. */
-struct queue {
+struct queue_t {
struct swap_subbuffer *start_ptr;
struct swap_subbuffer *end_ptr;
+ unsigned int subbuffers_count;
struct sync_t queue_sync;
};
/* Write queue */
-struct queue write_queue = {
+struct queue_t write_queue = {
.start_ptr = NULL,
.end_ptr = NULL,
+ .subbuffers_count = 0,
.queue_sync = {
.flags = 0x0
}
};
/* Read queue */
-struct queue read_queue = {
+struct queue_t read_queue = {
.start_ptr = NULL,
.end_ptr = NULL,
+ .subbuffers_count = 0,
.queue_sync = {
.flags = 0x0
}
sync_init(&buffer_busy_sync);
/* Memory allocation for queue_busy */
- queue_busy = memory_allocation(sizeof(**queue_busy) * queue_subbuffer_count);
+ queue_busy = memory_allocation(sizeof(*queue_busy) * queue_subbuffer_count);
if (!queue_busy) {
result = -E_SB_NO_MEM_QUEUE_BUSY;
queue_subbuffer_size);
}
+ /* All subbuffers are in write list */
+ write_queue.subbuffers_count = subbuffers_count;
+
return E_SB_SUCCESS;
/* In case of errors, this code is called */
return ((queue_subbuffer_size-subbuffer->full_buffer_part) >= size) ? 1 : 0;
}
+static void next_queue_element(struct queue_t *queue)
+{
+ /* If we reached the last elemenet, end pointer should point to NULL */
+ if (queue->start_ptr == queue->end_ptr)
+ queue->end_ptr = NULL;
+
+ queue->start_ptr = queue->start_ptr->next_in_queue;
+ --queue->subbuffers_count;
+}
+
/* Get first subbuffer from read list */
struct swap_subbuffer *get_from_read_list(void)
{
result = read_queue.start_ptr;
- /* If this is the last readable buffer, read_queue.start_ptr next time will
- * points to NULL and that case is handled in the beginning of function
- */
- if (read_queue.start_ptr == read_queue.end_ptr) {
- read_queue.end_ptr = NULL;
- }
- read_queue.start_ptr = read_queue.start_ptr->next_in_queue;
+ next_queue_element(&read_queue);
get_from_read_list_unlock:
/* Unlock read sync primitive */
/* Add subbuffer to read list */
void add_to_read_list(struct swap_subbuffer *subbuffer)
{
-
/* Lock read sync primitive */
sync_lock(&read_queue.queue_sync);
read_queue.end_ptr = subbuffer;
}
read_queue.end_ptr->next_in_queue = NULL;
+ ++read_queue.subbuffers_count;
/* Unlock read sync primitive */
sync_unlock(&read_queue.queue_sync);
return result;
}
+/* Returns subbuffers to read count */
+unsigned int get_readable_buf_cnt(void)
+{
+ return read_queue.subbuffers_count;
+}
+
+
/* Get first writable subbuffer from write list */
struct swap_subbuffer *get_from_write_list(size_t size, void **ptr_to_write)
{
struct swap_subbuffer *result = NULL;
/* Callbacks are called at the end of the function to prevent deadlocks */
- struct queue callback_queue = {
+ struct queue_t callback_queue = {
.start_ptr = NULL,
.end_ptr = NULL,
.queue_sync = {
sync_lock(&write_queue.queue_sync);
while (write_queue.start_ptr) {
- /* If start points to NULL => list is empty => exit */
- if (!write_queue.start_ptr) {
- result = NULL;
- goto get_from_write_list_unlock;
- }
/* We're found subbuffer */
if (is_buffer_enough(write_queue.start_ptr, size)) {
} else {
result = write_queue.start_ptr;
- /* If we reached end of the list */
- if (write_queue.start_ptr == write_queue.end_ptr) {
- write_queue.end_ptr = NULL;
- }
-
- /* Move start write pointer */
- write_queue.start_ptr = write_queue.start_ptr->next_in_queue;
+ next_queue_element(&write_queue);
/* Add to callback list */
if (!callback_queue.start_ptr)
}
}
-get_from_write_list_unlock:
/* Unlock write list sync primitive */
sync_unlock(&write_queue.queue_sync);
sync_lock(&write_queue.queue_sync);
/* Reinitialize */
- // TODO Useless memset
-// memset(buffer_address(subbuffer->data_buffer), 0, queue_subbuffer_size);
subbuffer->full_buffer_part = 0;
if (!write_queue.start_ptr)
write_queue.end_ptr = subbuffer;
}
write_queue.end_ptr->next_in_queue = NULL;
+ ++write_queue.subbuffers_count;
sync_unlock(&write_queue.queue_sync);
}
+/* Returns subbuffers to write count */
+unsigned int get_writable_buf_cnt(void)
+{
+ return write_queue.subbuffers_count;
+}
+
+
/* Add subbuffer to busy list when it is read from out of the buffer */
void add_to_busy_list(struct swap_subbuffer *subbuffer)
{
return result;
}
-/* Get subbuffers count in read list */
-/* XXX Think about locks */
-int get_full_buffers_count(void)
-{
- int result = 0;
- struct swap_subbuffer *buffer = read_queue.start_ptr;
-
- while (buffer && buffer->full_buffer_part) {
- result += 1;
- buffer = buffer->next_in_queue;
- }
-
- return result;
-}
-
/* Set all subbuffers in write list to read list */
void buffer_queue_flush(void)
{
sync_lock(&buffer->buffer_sync);
buffer = write_queue.start_ptr;
-
- /* If we reached end of the list */
- if (write_queue.start_ptr == write_queue.end_ptr) {
- write_queue.end_ptr = NULL;
- }
- write_queue.start_ptr = write_queue.start_ptr->next_in_queue;
-
+ next_queue_element(&write_queue);
add_to_read_list(buffer);
/* Unlock buffer sync primitive */