[IMPROVE] Buffer: implement initialization with structure 32/14132/2
authorAlexander Aksenov <a.aksenov@samsung.com>
Mon, 23 Dec 2013 14:04:14 +0000 (18:04 +0400)
committerAlexander Aksenov <a.aksenov@samsung.com>
Wed, 25 Dec 2013 11:55:58 +0000 (15:55 +0400)
Structure adds threshold vars and callbacks

Change-Id: Ie5630e476c4dc11dd5d6422bcd14a9e093821cfe
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
buffer/swap_buffer_errors.h
buffer/swap_buffer_module.c
buffer/swap_buffer_module.h
driver/driver_to_buffer.c

index 516c00c..81bdb5f 100644 (file)
 #define __SWAP_BUFFER_ERRORS_H__
 
 enum _swap_buffer_errors {
-       E_SB_SUCCESS = 0,                  /* Success */
-       E_SB_UNRELEASED_BUFFERS = 1,    /* There are some unreleased buffers. Mainly
+       E_SB_SUCCESS = 0,               /* Success */
+       E_SB_UNRELEASED_BUFFERS = 1,    /* There are some unreleased buffers. Mainly
                                           returned by swap_buffer_uninit */
        E_SB_NO_WRITABLE_BUFFERS = 2,   /* No buffers for writing */
-       E_SB_WRONG_DATA_SIZE = 3,          /* Wrong data size: size == 0 or
+       E_SB_WRONG_DATA_SIZE = 3,       /* Wrong data size: size == 0 or
                                           size > subbuffer size */
-       E_SB_IS_STOPPED = 4,            /* Trying to write data after SWAP buffer
+       E_SB_IS_STOPPED = 4,            /* Trying to write data after SWAP buffer
                                           has been stopped. */
-       E_SB_OVERLAP = 5,                  /* Memory areas of data to be written and
+       E_SB_OVERLAP = 5,               /* Memory areas of data to be written and
                                           subbuffer itself are overlap */
        E_SB_NO_READABLE_BUFFERS = 6,   /* No buffers for reading */
-       E_SB_NO_CALLBACK = 7,      /* Callback function ptr == NULL */
-       E_SB_NO_MEM_QUEUE_BUSY = 8,      /* Memory for queue_busy wasn't allocated */
+       E_SB_NO_CALLBACK = 7,           /* Callback function ptr == NULL */
+       E_SB_NO_MEM_QUEUE_BUSY = 8,     /* Memory for queue_busy wasn't allocated */
        E_SB_NO_MEM_BUFFER_STRUCT = 9,  /* Memory for one of struct swap_buffer
                                           wasn't allocated */
        E_SB_NO_MEM_DATA_BUFFER = 10,   /* Memort for data buffer itself wasn't
                                           allocated */
        E_SB_NO_SUBBUFFER_IN_BUSY = 11, /* No such subbuffer in busy_list */
-       E_SB_NOT_ALLOC = 12              /* Subbuffers aren't allocated */
+       E_SB_NOT_ALLOC = 12,            /* Subbuffers aren't allocated */
+       E_SB_WRONG_THRESHOLD = 13       /* Thresholds > 100, top < lower */
 };
 
 #endif /* __SWAP_BUFFER_ERRORS_H__ */
index 17d8f70..e230907 100644 (file)
 enum _swap_buffer_status_mask {
        BUFFER_FREE = 0,
        BUFFER_ALLOC = 1,
-       BUFFER_STOP = 2,
+       BUFFER_PAUSE = 2,
        BUFFER_WORK = 4
 };
 
 /* Buffer status masks:
- *  0 - memory free
- *  1 - memory allocated 
- * 0  - buffer stop
- * 1  - buffer work
+ *   0 - memory free
+ *   1 - memory allocated
+ *  10 - buffer overflow
+ * 100 - buffer work
  * */
-static unsigned char swap_buffer_status = 0;
+static unsigned char swap_buffer_status = BUFFER_FREE;
 
 /* Callback type */
-typedef int(*subbuffer_callback_type)(void *);
+typedef int(*subbuffer_callback_type)(void);
 
 /* Callback that is called when full subbuffer appears */
 static subbuffer_callback_type subbuffer_callback = NULL;
@@ -58,6 +58,11 @@ static size_t subbuffers_size = 0;
 /* Subbuffers count */
 static unsigned int subbuffers_num = 0;
 
+static unsigned int enough_writable_bufs = 0;
+static unsigned int min_writable_bufs = 0;
+static int (*low_mem_cb)(void) = NULL;
+static int (*enough_mem_cb)(void) = NULL;
+
 
 static inline int areas_overlap(const void *area1,const void *area2, size_t size)
 {
@@ -70,27 +75,44 @@ static inline int areas_overlap(const void *area1,const void *area2, size_t size
        return 0;
 }
 
-int swap_buffer_init(size_t subbuffer_size, unsigned int nr_subbuffers,
-                    int (*subbuffer_full_callback)(void))
+static inline unsigned int percent_to_count(unsigned char percent,
+                                            unsigned int cnt)
+{
+       return (percent * cnt) / 100;
+}
+
+int swap_buffer_init(struct buffer_init_t *buf_init)
 {
        int result = -1;
 
        swap_buffer_status &= ~BUFFER_WORK;
        print_debug("status buffer stop = %d\n", swap_buffer_status);
 
+       if ((buf_init->top_threshold > 100) || (buf_init->lower_threshold > 100) ||
+           (buf_init->top_threshold < buf_init->lower_threshold))
+               return -E_SB_WRONG_THRESHOLD;
+
+       min_writable_bufs = percent_to_count(buf_init->lower_threshold,
+                                            buf_init->nr_subbuffers);
+
+       enough_writable_bufs = percent_to_count(buf_init->top_threshold,
+                                               buf_init->nr_subbuffers);
+
+       low_mem_cb = buf_init->low_mem_cb;
+       enough_mem_cb = buf_init->enough_mem_cb;
+
        if ((swap_buffer_status & BUFFER_ALLOC) &&
-               (subbuffers_size == subbuffer_size) &&
-               (subbuffers_num == nr_subbuffers) &&
-               ((subbuffer_callback_type)subbuffer_full_callback ==
-                subbuffer_callback)) {
+               (subbuffers_size == buf_init->subbuffer_size) &&
+               (subbuffers_num == buf_init->nr_subbuffers) &&
+               ((subbuffer_callback_type)subbuffer_callback ==
+                                 buf_init->subbuffer_full_cb)) {
                result = buffer_queue_reset();
                goto swap_buffer_init_work;
        }
 
-       // TODO Test if wrong function type
-       subbuffer_callback = (subbuffer_callback_type)subbuffer_full_callback;
-       subbuffers_size = subbuffer_size;
-       subbuffers_num = nr_subbuffers;
+       subbuffer_callback = buf_init->subbuffer_full_cb;
+       subbuffers_size = buf_init->subbuffer_size;
+       subbuffers_num = buf_init->nr_subbuffers;
 
        result = buffer_queue_allocation(subbuffers_size, subbuffers_num);
        if (result < 0)
@@ -130,6 +152,10 @@ int swap_buffer_uninit(void)
        subbuffer_callback = NULL;
        subbuffers_size = 0;
        subbuffers_num = 0;
+       min_writable_bufs = 0;
+       enough_writable_bufs = 0;
+       low_mem_cb = NULL;
+       enough_mem_cb = NULL;
 
        swap_buffer_status &= ~BUFFER_ALLOC;
        print_debug("status buffer dealloc = %d\n", swap_buffer_status);
@@ -247,7 +273,7 @@ int swap_buffer_callback(void *buffer)
                return -E_SB_NO_CALLBACK;
        }
 
-       result = subbuffer_callback(buffer);
+       result = subbuffer_callback();
        if (result < 0)
                print_err("Callback error! Error code: %d\n", result);
 
index 88e6ec1..4ccb68c 100644 (file)
 
 struct swap_subbuffer;
 
+struct buffer_init_t {
+       size_t subbuffer_size;
+       unsigned int nr_subbuffers;
+       int (*subbuffer_full_cb)(void);
+
+       /* Lower threshold in percent. When buffers fall below this limit
+        * low_mem_cb is called and swap_buffer is suspended. */
+       unsigned char lower_threshold;
+       int (*low_mem_cb)(void);
+
+       /* Top threshold in percent. When buffers exceed this limit
+        * enough_mem_cb is called */
+       unsigned char top_threshold;
+       int (*enough_mem_cb)(void);
+};
+
 /* SWAP Buffer initialization function. Call it before using buffer.
  * Returns memory pages count (>0) in one subbuffer on success, or error code
  * (<0) otherwise. */
-int swap_buffer_init(size_t subbuffer_size, unsigned int nr_subbuffers,
-                    int (*subbuffer_full_callback)(void));
+int swap_buffer_init(struct buffer_init_t *buf_init);
 
 /* SWAP Buffer uninitialization function. Call it every time before removing
  * this module. 
index b9b2113..1578da7 100644 (file)
@@ -188,15 +188,10 @@ ssize_t driver_to_buffer_read(char __user *buf, size_t count)
 /* Flush swap_buffer */
 int driver_to_buffer_flush(void)
 {
-       int result;
-
-       result = swap_buffer_flush();
-
-       if (result >= 0)
-               set_buffers_to_read(result);
-       else if (result < 0)
-               return -E_SD_BUFFER_ERROR;
+       unsigned int flushed;
 
+       flushed = swap_buffer_flush();
+       set_buffers_to_read(flushed);
        swap_device_wake_up_process();
 
        return E_SD_SUCCESS;
@@ -251,12 +246,21 @@ int driver_to_buffer_buffer_to_read(void)
 int driver_to_buffer_initialize(size_t size, unsigned int count)
 {
        int result;
+       struct buffer_init_t buf_init = {
+               .subbuffer_size = size,
+               .nr_subbuffers = count,
+               .subbuffer_full_cb = driver_to_buffer_callback,
+               .lower_threshold = 20,
+               .low_mem_cb = NULL,
+               .top_threshold = 80,
+               .enough_mem_cb = NULL,
+       };
 
        if (size == 0 && count == 0) {
                return -E_SD_WRONG_ARGS;
        }
 
-       result = swap_buffer_init(size, count, (void*)&driver_to_buffer_callback);
+       result = swap_buffer_init(&buf_init);
        if (result == -E_SB_NO_MEM_QUEUE_BUSY
                || result == -E_SB_NO_MEM_BUFFER_STRUCT) {
                return -E_SD_NO_MEMORY;