GKI cleanup - Replaced usage of GKI queue with OSI fixed_queue

* Added new functions to OSI:
  - fixed_queue_init()
  - fixed_queue_length()
  - fixed_queue_try_remove_from_queue()
  - fixed_queue_try_peek_last()

* Renamed fixed_queue_try_peek() to fixed_queue_try_peek_first()

* Replaced usage of GKI queue functions with OSI fixed_queue functions:
  - GKI_init_q() -> fixed_queue_new(SIZE_MAX)
    NOTE: unlike GKI_init_q(), fixed_queue_new() allocates memory /
    state that needs to be released by calling fixed_queue_free()
  - GKI_enqueue() -> fixed_queue_enqueue()
  - GKI_dequeue() -> fixed_queue_try_dequeue()
    NOTE: fixed_queue_try_dequeue() is non-blocking
  - GKI_queue_length() -> fixed_queue_length()
  - GKI_queue_is_empty() -> fixed_queue_is_empty()
  - GKI_getfirst() -> fixed_queue_try_peek_first()
  - GKI_getlast() -> fixed_queue_try_peek_last()
  - GKI_remove_from_queue() -> fixed_queue_try_remove_from_queue()
  - Queue elements iteration.
    In the fixed_queue implementation we have to use the underlying
    list_t mechanism to iterate over the elements.
    OLD:
      p = GKI_getfirst(queue);
      ...
      while ((p = GKI_getnext(p) != NULL) {
         ...
      }
    NEW:
      list_t *list = fixed_queue_get_list(queue);
      for (const list_node_t *node = list_begin(list);
           node != list_end(list); node = list_next(node)) {
          p = list_node(node);
      }

* Remove initialization of the GKI module, because it is not needed
  anymore

* Removed unused files in GKI:
  gki/common/gki_common.h
  gki/ulinux/gki_int.h
  gki/ulinux/gki_ulinux.c

Change-Id: I3ff9464db75252d6faf7476a9ca67c88e535c51c
diff --git a/osi/include/fixed_queue.h b/osi/include/fixed_queue.h
index 52862bf..6902d6b 100644
--- a/osi/include/fixed_queue.h
+++ b/osi/include/fixed_queue.h
@@ -21,6 +21,8 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
+#include "osi/include/list.h"
+
 struct fixed_queue_t;
 typedef struct fixed_queue_t fixed_queue_t;
 typedef struct reactor_t reactor_t;
@@ -28,6 +30,11 @@
 typedef void (*fixed_queue_free_cb)(void *data);
 typedef void (*fixed_queue_cb)(fixed_queue_t *queue, void *context);
 
+// Initializes a fixed |queue| with the given |capacity|. If more elements than
+// |capacity| are added to the queue, the caller is blocked until space is
+// made available in the queue. Returns false on failure.
+bool fixed_queue_init(fixed_queue_t *queue, size_t capacity);
+
 // Creates a new fixed queue with the given |capacity|. If more elements than
 // |capacity| are added to the queue, the caller is blocked until space is
 // made available in the queue. Returns NULL on failure. The caller must free
@@ -42,6 +49,9 @@
 // not be NULL.
 bool fixed_queue_is_empty(fixed_queue_t *queue);
 
+// Returns the length of the |queue|. |queue| may not be NULL.
+size_t fixed_queue_length(fixed_queue_t *queue);
+
 // Returns the maximum number of elements this queue may hold. |queue| may
 // not be NULL.
 size_t fixed_queue_capacity(fixed_queue_t *queue);
@@ -69,9 +79,27 @@
 void *fixed_queue_try_dequeue(fixed_queue_t *queue);
 
 // Returns the first element from |queue|, if present, without dequeuing it.
-// This function will never block the caller. Returns NULL if there are no elements
-// in the queue. |queue| may not be NULL.
-void *fixed_queue_try_peek(fixed_queue_t *queue);
+// This function will never block the caller. Returns NULL if there are no
+// elements in the queue. |queue| may not be NULL.
+void *fixed_queue_try_peek_first(fixed_queue_t *queue);
+
+// Returns the last element from |queue|, if present, without dequeuing it.
+// This function will never block the caller. Returns NULL if there are no
+// elements in the queue. |queue| may not be NULL.
+void *fixed_queue_try_peek_last(fixed_queue_t *queue);
+
+// Tries to remove a |data| element from the middle of the |queue|. This
+// function will never block the caller. If the |data| element is found
+// in the queue, a pointer to the removed data is returned, otherwise NULL.
+void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data);
+
+// Returns the iterateable list with all entries in the |queue|. This function
+// will never block the caller. |queue| may not be NULL.
+//
+// NOTE: The return result of this function is not thread safe: the list could
+// be modified by another thread, and the result would be unpredictable.
+// Hence, the usage of this function is discouraged.
+list_t *fixed_queue_get_list(fixed_queue_t *queue);
 
 // This function returns a valid file descriptor. Callers may perform one
 // operation on the fd: select(2). If |select| indicates that the file
diff --git a/osi/src/fixed_queue.c b/osi/src/fixed_queue.c
index 4ab5b92..03a252c 100644
--- a/osi/src/fixed_queue.c
+++ b/osi/src/fixed_queue.c
@@ -18,6 +18,7 @@
 
 #include <assert.h>
 #include <pthread.h>
+#include <string.h>
 
 #include "osi/include/allocator.h"
 #include "osi/include/fixed_queue.h"
@@ -40,6 +41,36 @@
 
 static void internal_dequeue_ready(void *context);
 
+bool fixed_queue_init(fixed_queue_t *queue, size_t capacity) {
+  if (queue == NULL)
+    return false;
+  memset(queue, 0, sizeof(*queue));
+
+  pthread_mutex_init(&queue->lock, NULL);
+  queue->capacity = capacity;
+
+  queue->list = list_new(NULL);
+  if (!queue->list)
+    goto error;
+
+  queue->enqueue_sem = semaphore_new(capacity);
+  if (!queue->enqueue_sem)
+    goto error;
+
+  queue->dequeue_sem = semaphore_new(0);
+  if (!queue->dequeue_sem)
+    goto error;
+
+  return true;
+
+error:
+  list_free(queue->list);
+  semaphore_free(queue->enqueue_sem);
+  semaphore_free(queue->dequeue_sem);
+  pthread_mutex_destroy(&queue->lock);
+  return false;
+}
+
 fixed_queue_t *fixed_queue_new(size_t capacity) {
   fixed_queue_t *ret = osi_calloc(sizeof(fixed_queue_t));
   if (!ret)
@@ -62,7 +93,7 @@
 
   return ret;
 
-error:;
+error:
   fixed_queue_free(ret, NULL);
   return NULL;
 }
@@ -94,6 +125,16 @@
   return is_empty;
 }
 
+size_t fixed_queue_length(fixed_queue_t *queue) {
+  assert(queue != NULL);
+
+  pthread_mutex_lock(&queue->lock);
+  size_t length = list_length(queue->list);
+  pthread_mutex_unlock(&queue->lock);
+
+  return length;
+}
+
 size_t fixed_queue_capacity(fixed_queue_t *queue) {
   assert(queue != NULL);
 
@@ -159,17 +200,47 @@
   return ret;
 }
 
-void *fixed_queue_try_peek(fixed_queue_t *queue) {
+void *fixed_queue_try_peek_first(fixed_queue_t *queue) {
   assert(queue != NULL);
 
   pthread_mutex_lock(&queue->lock);
-  // Because protected by the lock, the empty and front calls are atomic and not a race condition
   void *ret = list_is_empty(queue->list) ? NULL : list_front(queue->list);
   pthread_mutex_unlock(&queue->lock);
 
   return ret;
 }
 
+void *fixed_queue_try_peek_last(fixed_queue_t *queue) {
+  assert(queue != NULL);
+
+  pthread_mutex_lock(&queue->lock);
+  void *ret = list_is_empty(queue->list) ? NULL : list_back(queue->list);
+  pthread_mutex_unlock(&queue->lock);
+
+  return ret;
+}
+
+void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data) {
+  assert(queue != NULL);
+
+  pthread_mutex_lock(&queue->lock);
+  bool removed = list_remove(queue->list, data);
+  pthread_mutex_unlock(&queue->lock);
+
+  if (removed)
+    return data;
+  return NULL;
+}
+
+list_t *fixed_queue_get_list(fixed_queue_t *queue) {
+  assert(queue != NULL);
+
+  // NOTE: This function is not thread safe, and there is no point for
+  // callint pthread_mutex_lock() / pthread_mutex_unlock()
+  return queue->list;
+}
+
+
 int fixed_queue_get_dequeue_fd(const fixed_queue_t *queue) {
   assert(queue != NULL);
   return semaphore_get_fd(queue->dequeue_sem);