forked from len0rd/rockbox
Optimized the gui list code performance, including automatic frame dropping and cpu boosting when button events are getting queued. Improved scrollwheel acceleration code is needed to notice a real change.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12721 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
408dfd65ad
commit
2eefb5acb8
5 changed files with 222 additions and 82 deletions
201
apps/gui/list.c
201
apps/gui/list.c
|
|
@ -40,11 +40,17 @@
|
||||||
#define SCROLL_LIMIT 2
|
#define SCROLL_LIMIT 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The minimum number of pending button events in queue before starting
|
||||||
|
* to limit list drawing interval.
|
||||||
|
*/
|
||||||
|
#define FRAMEDROP_TRIGGER 6
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
static int offset_step = 16; /* pixels per screen scroll step */
|
static int offset_step = 16; /* pixels per screen scroll step */
|
||||||
/* should lines scroll out of the screen */
|
/* should lines scroll out of the screen */
|
||||||
static bool offset_out_of_view = false;
|
static bool offset_out_of_view = false;
|
||||||
#endif
|
#endif
|
||||||
|
static struct gui_list* last_list_displayed[NB_SCREENS];
|
||||||
|
|
||||||
#define SHOW_LIST_TITLE ((gui_list->title != NULL) && \
|
#define SHOW_LIST_TITLE ((gui_list->title != NULL) && \
|
||||||
(gui_list->display->nb_lines > 1))
|
(gui_list->display->nb_lines > 1))
|
||||||
|
|
@ -86,6 +92,9 @@ static void gui_list_init(struct gui_list * gui_list,
|
||||||
gui_list->title = NULL;
|
gui_list->title = NULL;
|
||||||
gui_list->title_width = 0;
|
gui_list->title_width = 0;
|
||||||
gui_list->title_icon = NOICON;
|
gui_list->title_icon = NOICON;
|
||||||
|
|
||||||
|
gui_list->last_displayed_selected_item = -1 ;
|
||||||
|
gui_list->last_displayed_start_item = -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -217,7 +226,7 @@ static int gui_list_get_item_offset(struct gui_list * gui_list, int item_width,
|
||||||
* Draws the list on the attached screen
|
* Draws the list on the attached screen
|
||||||
* - gui_list : the list structure
|
* - gui_list : the list structure
|
||||||
*/
|
*/
|
||||||
static void gui_list_draw(struct gui_list * gui_list)
|
static void gui_list_draw_smart(struct gui_list *gui_list)
|
||||||
{
|
{
|
||||||
struct screen * display=gui_list->display;
|
struct screen * display=gui_list->display;
|
||||||
int cursor_pos = 0;
|
int cursor_pos = 0;
|
||||||
|
|
@ -231,15 +240,51 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
int item_offset;
|
int item_offset;
|
||||||
int old_margin = display->getxmargin();
|
int old_margin = display->getxmargin();
|
||||||
#endif
|
#endif
|
||||||
|
int start, end;
|
||||||
|
bool partial_draw = false;
|
||||||
|
|
||||||
|
/* Speed up UI by drawing the changed contents only. */
|
||||||
|
if (gui_list == last_list_displayed[gui_list->display->screen_type]
|
||||||
|
&& gui_list->last_displayed_start_item == gui_list->start_item
|
||||||
|
&& gui_list->selected_size == 1)
|
||||||
|
{
|
||||||
|
partial_draw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHOW_LIST_TITLE)
|
||||||
|
lines = display->nb_lines - 1;
|
||||||
|
else
|
||||||
|
lines = display->nb_lines;
|
||||||
|
|
||||||
|
if (partial_draw)
|
||||||
|
{
|
||||||
|
end = gui_list->last_displayed_selected_item - gui_list->start_item;
|
||||||
|
i = gui_list->selected_item - gui_list->start_item;
|
||||||
|
if (i < end )
|
||||||
|
{
|
||||||
|
start = i;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = end;
|
||||||
|
end = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gui_textarea_clear(display);
|
gui_textarea_clear(display);
|
||||||
|
start = 0;
|
||||||
|
end = display->nb_lines;
|
||||||
|
gui_list->last_displayed_start_item = gui_list->start_item;
|
||||||
|
last_list_displayed[gui_list->display->screen_type] = gui_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_list->last_displayed_selected_item = gui_list->selected_item;
|
||||||
|
|
||||||
/* position and draw the list title & icon */
|
/* position and draw the list title & icon */
|
||||||
if (SHOW_LIST_TITLE)
|
if (SHOW_LIST_TITLE && !partial_draw)
|
||||||
{
|
{
|
||||||
i = 1;
|
|
||||||
lines = display->nb_lines - 1;
|
|
||||||
|
|
||||||
if (gui_list->title_icon != NOICON && draw_icons)
|
if (gui_list->title_icon != NOICON && draw_icons)
|
||||||
{
|
{
|
||||||
screen_put_iconxy(display, 0, 0, gui_list->title_icon);
|
screen_put_iconxy(display, 0, 0, gui_list->title_icon);
|
||||||
|
|
@ -266,11 +311,6 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
display->puts_scroll(text_pos, 0, gui_list->title);
|
display->puts_scroll(text_pos, 0, gui_list->title);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
lines = display->nb_lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust the position of icon, cursor, text for the list */
|
/* Adjust the position of icon, cursor, text for the list */
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
@ -309,7 +349,14 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
screen_set_xmargin(display, text_pos); /* margin for list */
|
screen_set_xmargin(display, text_pos); /* margin for list */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (i < display->nb_lines)
|
if (SHOW_LIST_TITLE)
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
if (end < display->nb_lines)
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = start; i < end; i++)
|
||||||
{
|
{
|
||||||
unsigned char *s;
|
unsigned char *s;
|
||||||
char entry_buffer[MAX_PATH];
|
char entry_buffer[MAX_PATH];
|
||||||
|
|
@ -338,21 +385,28 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
{/* The selected item must be displayed scrolling */
|
{/* The selected item must be displayed scrolling */
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if (global_settings.invert_cursor)/* Display inverted-line-style*/
|
if (global_settings.invert_cursor)/* Display inverted-line-style*/
|
||||||
|
{
|
||||||
/* if text got out of view */
|
/* if text got out of view */
|
||||||
if (item_offset > item_width - (display->width - text_pos))
|
if (item_offset > item_width - (display->width - text_pos))
|
||||||
|
{
|
||||||
/* don't scroll */
|
/* don't scroll */
|
||||||
display->puts_style_offset(0, i, entry_name,
|
display->puts_style_offset(0, i, entry_name,
|
||||||
STYLE_INVERT,item_offset);
|
STYLE_INVERT,item_offset);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
display->puts_scroll_style_offset(0, i, entry_name,
|
display->puts_scroll_style_offset(0, i, entry_name,
|
||||||
STYLE_INVERT,
|
STYLE_INVERT,
|
||||||
item_offset);
|
item_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
else /* if (!global_settings.invert_cursor) */
|
else /* if (!global_settings.invert_cursor) */
|
||||||
|
{
|
||||||
if (item_offset > item_width - (display->width - text_pos))
|
if (item_offset > item_width - (display->width - text_pos))
|
||||||
display->puts_offset(0, i, entry_name,item_offset);
|
display->puts_offset(0, i, entry_name,item_offset);
|
||||||
else
|
else
|
||||||
display->puts_scroll_offset(0, i, entry_name,item_offset);
|
display->puts_scroll_offset(0, i, entry_name,item_offset);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
display->puts_scroll(text_pos, i, entry_name);
|
display->puts_scroll(text_pos, i, entry_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -389,7 +443,6 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
if(icon)
|
if(icon)
|
||||||
screen_put_iconxy(display, icon_pos, i, icon);
|
screen_put_iconxy(display, icon_pos, i, icon);
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
@ -413,6 +466,15 @@ static void gui_list_draw(struct gui_list * gui_list)
|
||||||
gui_textarea_update(display);
|
gui_textarea_update(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force a full screen update.
|
||||||
|
*/
|
||||||
|
static void gui_list_draw(struct gui_list *gui_list)
|
||||||
|
{
|
||||||
|
last_list_displayed[gui_list->display->screen_type] = NULL;
|
||||||
|
return gui_list_draw_smart(gui_list);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Selects an item in the list
|
* Selects an item in the list
|
||||||
* - gui_list : the list structure
|
* - gui_list : the list structure
|
||||||
|
|
@ -426,6 +488,64 @@ static void gui_list_select_item(struct gui_list * gui_list, int item_number)
|
||||||
gui_list_put_selection_in_screen(gui_list, false);
|
gui_list_put_selection_in_screen(gui_list, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scroll_down(struct gui_list *gui_list, bool paginate)
|
||||||
|
{
|
||||||
|
int nb_lines = gui_list->display->nb_lines;
|
||||||
|
if (SHOW_LIST_TITLE)
|
||||||
|
nb_lines--;
|
||||||
|
int item_pos = gui_list->selected_item - gui_list->start_item;
|
||||||
|
int end_item = gui_list->start_item + nb_lines;
|
||||||
|
|
||||||
|
if (paginate)
|
||||||
|
{
|
||||||
|
/* When we reach the bottom of the list
|
||||||
|
* we jump to a new page if there are more items*/
|
||||||
|
if ((item_pos > nb_lines-gui_list->selected_size) &&
|
||||||
|
(end_item < gui_list->nb_items) )
|
||||||
|
{
|
||||||
|
gui_list->start_item = gui_list->selected_item;
|
||||||
|
if ( gui_list->start_item > gui_list->nb_items-nb_lines )
|
||||||
|
gui_list->start_item = gui_list->nb_items-nb_lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we start scrolling vertically when reaching the line
|
||||||
|
* (nb_lines-SCROLL_LIMIT)
|
||||||
|
* and when we are not in the last part of the list*/
|
||||||
|
if( (item_pos > nb_lines-SCROLL_LIMIT) &&
|
||||||
|
(end_item < gui_list->nb_items) )
|
||||||
|
{
|
||||||
|
gui_list->start_item+=gui_list->selected_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scroll_up(struct gui_list *gui_list, bool paginate)
|
||||||
|
{
|
||||||
|
int item_pos = gui_list->selected_item - gui_list->start_item;
|
||||||
|
int nb_lines = gui_list->display->nb_lines;
|
||||||
|
|
||||||
|
if (paginate)
|
||||||
|
{
|
||||||
|
/* When we reach the top of the list
|
||||||
|
* we jump to a new page if there are more items*/
|
||||||
|
if( item_pos < 0)
|
||||||
|
gui_list->start_item = gui_list->selected_item - nb_lines +
|
||||||
|
gui_list->selected_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we start scrolling vertically when reaching the line
|
||||||
|
* (nb_lines-SCROLL_LIMIT)
|
||||||
|
* and when we are not in the last part of the list*/
|
||||||
|
if( item_pos < SCROLL_LIMIT-1)
|
||||||
|
gui_list->start_item-=gui_list->selected_size;
|
||||||
|
}
|
||||||
|
if( gui_list->start_item < 0 )
|
||||||
|
gui_list->start_item = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Selects the next item in the list
|
* Selects the next item in the list
|
||||||
* (Item 0 gets selected if the end of the list is reached)
|
* (Item 0 gets selected if the end of the list is reached)
|
||||||
|
|
@ -444,33 +564,7 @@ static void gui_list_select_next(struct gui_list * gui_list)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gui_list->selected_item+=gui_list->selected_size;
|
gui_list->selected_item+=gui_list->selected_size;
|
||||||
int nb_lines = gui_list->display->nb_lines;
|
scroll_down(gui_list, global_settings.scroll_paginated);
|
||||||
if (SHOW_LIST_TITLE)
|
|
||||||
nb_lines--;
|
|
||||||
int item_pos = gui_list->selected_item - gui_list->start_item;
|
|
||||||
int end_item = gui_list->start_item + nb_lines;
|
|
||||||
|
|
||||||
if (global_settings.scroll_paginated)
|
|
||||||
{
|
|
||||||
/* When we reach the bottom of the list
|
|
||||||
* we jump to a new page if there are more items*/
|
|
||||||
if( (item_pos > nb_lines-gui_list->selected_size) &&
|
|
||||||
(end_item < gui_list->nb_items) )
|
|
||||||
{
|
|
||||||
gui_list->start_item = gui_list->selected_item;
|
|
||||||
if ( gui_list->start_item > gui_list->nb_items-nb_lines )
|
|
||||||
gui_list->start_item = gui_list->nb_items-nb_lines;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* we start scrolling vertically when reaching the line
|
|
||||||
* (nb_lines-SCROLL_LIMIT)
|
|
||||||
* and when we are not in the last part of the list*/
|
|
||||||
if( (item_pos > nb_lines-SCROLL_LIMIT) &&
|
|
||||||
(end_item < gui_list->nb_items) )
|
|
||||||
gui_list->start_item+=gui_list->selected_size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,27 +593,8 @@ static void gui_list_select_previous(struct gui_list * gui_list)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int item_pos;
|
|
||||||
gui_list->selected_item -= gui_list->selected_size;
|
gui_list->selected_item -= gui_list->selected_size;
|
||||||
item_pos = gui_list->selected_item - gui_list->start_item;
|
scroll_up(gui_list, global_settings.scroll_paginated);
|
||||||
if (global_settings.scroll_paginated)
|
|
||||||
{
|
|
||||||
/* When we reach the top of the list
|
|
||||||
* we jump to a new page if there are more items*/
|
|
||||||
if( item_pos < 0)
|
|
||||||
gui_list->start_item = gui_list->selected_item - nb_lines +
|
|
||||||
gui_list->selected_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* we start scrolling vertically when reaching the line
|
|
||||||
* (nb_lines-SCROLL_LIMIT)
|
|
||||||
* and when we are not in the last part of the list*/
|
|
||||||
if( item_pos < SCROLL_LIMIT-1)
|
|
||||||
gui_list->start_item-=gui_list->selected_size;
|
|
||||||
}
|
|
||||||
if( gui_list->start_item < 0 )
|
|
||||||
gui_list->start_item = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,6 +925,9 @@ unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
case ACTION_STD_PREV:
|
case ACTION_STD_PREV:
|
||||||
case ACTION_STD_PREVREPEAT:
|
case ACTION_STD_PREVREPEAT:
|
||||||
gui_synclist_select_previous(lists);
|
gui_synclist_select_previous(lists);
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
||||||
|
#endif
|
||||||
gui_synclist_draw(lists);
|
gui_synclist_draw(lists);
|
||||||
yield();
|
yield();
|
||||||
return ACTION_STD_PREV;
|
return ACTION_STD_PREV;
|
||||||
|
|
@ -857,6 +935,9 @@ unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
case ACTION_STD_NEXT:
|
case ACTION_STD_NEXT:
|
||||||
case ACTION_STD_NEXTREPEAT:
|
case ACTION_STD_NEXTREPEAT:
|
||||||
gui_synclist_select_next(lists);
|
gui_synclist_select_next(lists);
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
||||||
|
#endif
|
||||||
gui_synclist_draw(lists);
|
gui_synclist_draw(lists);
|
||||||
yield();
|
yield();
|
||||||
return ACTION_STD_NEXT;
|
return ACTION_STD_NEXT;
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ struct gui_list
|
||||||
int selected_size;
|
int selected_size;
|
||||||
/* The data that will be passed to the callback function YOU implement */
|
/* The data that will be passed to the callback function YOU implement */
|
||||||
void * data;
|
void * data;
|
||||||
|
/* These are used to calculate how much of the screen content we need
|
||||||
|
to redraw. */
|
||||||
|
int last_displayed_selected_item;
|
||||||
|
int last_displayed_start_item;
|
||||||
/* The optional title, set to NULL for none */
|
/* The optional title, set to NULL for none */
|
||||||
char *title;
|
char *title;
|
||||||
/* Cache the width of the title string in pixels/characters */
|
/* Cache the width of the title string in pixels/characters */
|
||||||
|
|
@ -162,6 +166,7 @@ extern void gui_list_screen_scroll_out_of_view(bool enable);
|
||||||
struct gui_synclist
|
struct gui_synclist
|
||||||
{
|
{
|
||||||
struct gui_list gui_list[NB_SCREENS];
|
struct gui_list gui_list[NB_SCREENS];
|
||||||
|
struct gui_list *last_displayed[NB_SCREENS];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void gui_synclist_init(
|
extern void gui_synclist_init(
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "thread.h"
|
||||||
#include "backlight.h"
|
#include "backlight.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
|
@ -255,21 +256,52 @@ static void button_tick(void)
|
||||||
lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
|
lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void button_boost(bool state)
|
||||||
|
{
|
||||||
|
static bool boosted = false;
|
||||||
|
|
||||||
|
if (state && !boosted)
|
||||||
|
{
|
||||||
|
cpu_boost(true);
|
||||||
|
boosted = true;
|
||||||
|
}
|
||||||
|
else if (!state && boosted)
|
||||||
|
{
|
||||||
|
cpu_boost(false);
|
||||||
|
boosted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long button_get(bool block)
|
long button_get(bool block)
|
||||||
{
|
{
|
||||||
struct event ev;
|
struct event ev;
|
||||||
|
int pending_count = queue_count(&button_queue);
|
||||||
|
|
||||||
if ( block || !queue_empty(&button_queue) )
|
/* Control the CPU boost trying to keep queue empty. */
|
||||||
|
if (pending_count == 0)
|
||||||
|
button_boost(false);
|
||||||
|
else if (pending_count > 2)
|
||||||
|
button_boost(true);
|
||||||
|
|
||||||
|
if ( block || pending_count )
|
||||||
{
|
{
|
||||||
queue_wait(&button_queue, &ev);
|
queue_wait(&button_queue, &ev);
|
||||||
return ev.id;
|
return ev.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BUTTON_NONE;
|
return BUTTON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long button_get_w_tmo(int ticks)
|
long button_get_w_tmo(int ticks)
|
||||||
{
|
{
|
||||||
struct event ev;
|
struct event ev;
|
||||||
|
|
||||||
|
/* Be sure to keep boosted state. */
|
||||||
|
if (!queue_empty(&button_queue))
|
||||||
|
return button_get(true);
|
||||||
|
|
||||||
|
button_boost(false);
|
||||||
|
|
||||||
queue_wait_w_tmo(&button_queue, &ev, ticks);
|
queue_wait_w_tmo(&button_queue, &ev, ticks);
|
||||||
return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
|
return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ extern bool queue_in_queue_send(struct event_queue *q);
|
||||||
extern bool queue_empty(const struct event_queue* q);
|
extern bool queue_empty(const struct event_queue* q);
|
||||||
extern void queue_clear(struct event_queue* q);
|
extern void queue_clear(struct event_queue* q);
|
||||||
extern void queue_remove_from_head(struct event_queue *q, long id);
|
extern void queue_remove_from_head(struct event_queue *q, long id);
|
||||||
|
extern int queue_count(const struct event_queue *q);
|
||||||
extern int queue_broadcast(long id, intptr_t data);
|
extern int queue_broadcast(long id, intptr_t data);
|
||||||
|
|
||||||
extern void mutex_init(struct mutex *m);
|
extern void mutex_init(struct mutex *m);
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,27 @@ void queue_remove_from_head(struct event_queue *q, long id)
|
||||||
set_irq_level(oldlevel);
|
set_irq_level(oldlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of events waiting in the queue.
|
||||||
|
*
|
||||||
|
* @param struct of event_queue
|
||||||
|
* @return number of events in the queue
|
||||||
|
*/
|
||||||
|
int queue_count(const struct event_queue *q)
|
||||||
|
{
|
||||||
|
int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (q->read <= q->write)
|
||||||
|
result = q->write - q->read;
|
||||||
|
else
|
||||||
|
result = QUEUE_LENGTH - (q->read - q->write);
|
||||||
|
|
||||||
|
set_irq_level(oldlevel);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int queue_broadcast(long id, intptr_t data)
|
int queue_broadcast(long id, intptr_t data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue