summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2021-02-18 03:12:25 -0800
committerVito Caputo <vcaputo@pengaru.com>2021-02-18 03:36:37 -0800
commit0536326f814739a4ee6136f4156431e77fe45769 (patch)
treee911431e878f2fa0ee6f102bfdc10cfe1202c2cb
parent561bc18c2ff6ba42d4640eccb097b7f4bc8fecc3 (diff)
fb: make inactive pages list doubly-linked
This introduces a previous pointer to _fb_page_t, but it's only used on the inactive list. This is a preparatory commit to facilitate adding inactive pages at the head and consuming inactive pages off the tail, without having to always iterate the list for the new tail. Rebuilding pages on resize needs to happen somewhere, and the inactive list seems like the right place to do it. And to do it with a simple per-fb pages-needing-rebuild counter requires turning the inactive list into a FIFO queue.
-rw-r--r--src/fb.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/src/fb.c b/src/fb.c
index f24e4fe..e17ffd9 100644
--- a/src/fb.c
+++ b/src/fb.c
@@ -58,7 +58,7 @@ typedef struct _fb_page_t _fb_page_t;
struct _fb_page_t {
void *ops_page;
- _fb_page_t *next;
+ _fb_page_t *next, *previous;
fb_page_t public_page;
};
@@ -75,7 +75,8 @@ typedef struct fb_t {
pthread_mutex_t inactive_mutex;
pthread_cond_t inactive_cond;
- _fb_page_t *inactive_pages; /* finished pages available for (re)use */
+ _fb_page_t *inactive_pages_head; /* finished pages available for (re)use */
+ _fb_page_t *inactive_pages_tail;
unsigned put_pages_count;
} fb_t;
@@ -114,8 +115,13 @@ int fb_flip(fb_t *fb)
/* now that we're displaying a new page, make the previously active one inactive so rendering can reuse it */
pthread_mutex_lock(&fb->inactive_mutex);
- fb->active_page->next = fb->inactive_pages;
- fb->inactive_pages = fb->active_page;
+ fb->active_page->next = fb->inactive_pages_head;
+ fb->inactive_pages_head = fb->active_page;
+ fb->inactive_pages_head->previous = NULL;
+ if (fb->inactive_pages_head->next)
+ fb->inactive_pages_head->next->previous = fb->inactive_pages_head;
+ else
+ fb->inactive_pages_tail = fb->inactive_pages_head;
pthread_cond_signal(&fb->inactive_cond);
pthread_mutex_unlock(&fb->inactive_mutex);
@@ -144,8 +150,18 @@ static int fb_acquire(fb_t *fb, _fb_page_t *page)
static void fb_release(fb_t *fb)
{
fb->ops->release(fb, fb->ops_context);
- fb->active_page->next = fb->inactive_pages;
- fb->inactive_pages = fb->active_page;
+
+ /* XXX: this is getting silly, either add a doubly linked list header or
+ * at least use some functions for this local to this file.
+ */
+ fb->active_page->next = fb->inactive_pages_head;
+ fb->inactive_pages_head = fb->active_page;
+ fb->inactive_pages_head->previous = NULL;
+ if (fb->inactive_pages_head->next)
+ fb->inactive_pages_head->next->previous = fb->inactive_pages_head;
+ else
+ fb->inactive_pages_tail = fb->inactive_pages_head;
+
fb->active_page = NULL;
}
@@ -161,8 +177,12 @@ static void fb_page_new(fb_t *fb)
page->ops_page = fb->ops->page_alloc(fb, fb->ops_context, &page->public_page);
pthread_mutex_lock(&fb->inactive_mutex);
- page->next = fb->inactive_pages;
- fb->inactive_pages = page;
+ page->next = fb->inactive_pages_head;
+ fb->inactive_pages_head = page;
+ if (fb->inactive_pages_head->next)
+ fb->inactive_pages_head->next->previous = fb->inactive_pages_head;
+ else
+ fb->inactive_pages_tail = fb->inactive_pages_head;
pthread_mutex_unlock(&fb->inactive_mutex);
}
@@ -185,12 +205,16 @@ static inline _fb_page_t * _fb_page_get(fb_t *fb)
* pages faster than vhz.
*/
pthread_mutex_lock(&fb->inactive_mutex);
- while (!(page = fb->inactive_pages))
+ while (!(page = fb->inactive_pages_tail))
pthread_cond_wait(&fb->inactive_cond, &fb->inactive_mutex);
- fb->inactive_pages = page->next;
+ fb->inactive_pages_tail = page->previous;
+ if (fb->inactive_pages_tail)
+ fb->inactive_pages_tail->next = NULL;
+ else
+ fb->inactive_pages_head = NULL;
pthread_mutex_unlock(&fb->inactive_mutex);
- page->next = NULL;
+ page->next = page->previous = NULL;
page->public_page.fragment.zeroed = 0;
return page;
© 2021 All Rights Reserved