-- define application classes
-application_class { name="interrupt", priority=99, modal=true , share=false }
-application_class { name="navigator", priority=4 , modal=false, share=true }
-application_class { name="phone" , priority=3 , modal=false, share=true }
-application_class { name="game" , priority=2 , modal=false, share=true }
-application_class { name="player" , priority=1 , modal=false, share=true }
-application_class { name="implicit" , priority=0 , modal=false, share=true }
+application_class { name="interrupt", priority=99, modal=true , share=false, order="fifo" }
+application_class { name="navigator", priority=4 , modal=false, share=true , order="fifo" }
+application_class { name="phone" , priority=3 , modal=false, share=true , order="lifo" }
+application_class { name="game" , priority=2 , modal=false, share=true , order="lifo" }
+application_class { name="player" , priority=1 , modal=false, share=true , order="lifo" }
+application_class { name="implicit" , priority=0 , modal=false, share=true , order="lifo" }
-- define zone attributes
zone.attributes {
#define USAGE_KEY(p) (((uint32_t)(p) & USAGE_MASK) << USAGE_SHIFT)
#define PRIORITY_KEY(p) (((uint32_t)(p) & PRIORITY_MASK) << PRIORITY_SHIFT)
+#define STAMP_MAX STAMP_MASK
+
typedef struct {
const char *class_name;
uint32_t priority;
mrp_application_class_t *mrp_application_class_create(const char *name,
- uint32_t pri,
- bool modal,
- bool share)
+ uint32_t pri,
+ bool modal,
+ bool share,
+ mrp_resource_order_t order)
{
mrp_application_class_t *class;
mrp_list_hook_t *insert_before, *clhook, *n;
class->priority = pri;
class->modal = modal;
class->share = share;
+ class->order = order;
for (zone = 0; zone < MRP_ZONE_MAX; zone++)
mrp_list_init(&class->resource_sets[zone]);
uint32_t mrp_application_class_get_sorting_key(mrp_resource_set_t *rset)
{
+ mrp_application_class_t *class;
+ bool lifo;
+ uint32_t rqstamp;
uint32_t priority;
uint32_t usage;
uint32_t state;
MRP_ASSERT(rset, "invalid argument");
+ class = rset->class.ptr;
+ lifo = (class->order == MRP_RESOURCE_ORDER_LIFO);
+
+ rqstamp = rset->request.stamp;
+
priority = PRIORITY_KEY(rset->class.priority);
usage = USAGE_KEY(rset->resource.share ? 1 : 0);
state = STATE_KEY(rset->state == mrp_resource_acquire ? 1 : 0);
- stamp = STAMP_KEY(rset->request.stamp);
+ stamp = STAMP_KEY(lifo ? rqstamp : STAMP_MAX - rqstamp);
key = priority | usage | state | stamp;
struct mrp_application_class_s {
- mrp_list_hook_t list;
- const char *name;
- uint32_t priority;
- bool share;
- bool modal;
- mrp_list_hook_t resource_sets[MRP_ZONE_MAX];
+ mrp_list_hook_t list;
+ const char *name;
+ uint32_t priority;
+ bool share;
+ bool modal;
+ mrp_resource_order_t order;
+ mrp_list_hook_t resource_sets[MRP_ZONE_MAX];
};
mrp_application_class_t *mrp_application_class_find(const char *);
uint32_t mrp_zone_create(const char *name, mrp_attr_t *attrs);
mrp_application_class_t *mrp_application_class_create(const char *name,
- uint32_t priority,
- bool modal,
- bool share);
+ uint32_t priority,
+ bool modal,
+ bool share,
+ mrp_resource_order_t order);
int mrp_application_class_print(char *buf, int len, bool with_resource_sets);
MODAL,
SHARE,
GRANT,
+ ORDER,
SHARED,
METHOD,
OWNERS,
static void free_attrs(mrp_attr_t *);
static int check_attrindex(lua_State *, int, attr_def_t *);
static int check_boolean(lua_State *, int);
+static mrp_resource_order_t check_order(lua_State *, int);
+static int push_order(lua_State *, mrp_resource_order_t);
static field_t field_check(lua_State *, int, const char **);
static field_t field_name_to_type(const char *, size_t);
int priority = 0;
int modal = -1;
int share = -1;
+ mrp_resource_order_t order = 0;
const char *name = NULL;
MRP_LUA_ENTER;
share = check_boolean(L, -1);
break;
+ case ORDER:
+ order = check_order(L, -1);
+ break;
+
default:
luaL_error(L, "unexpected field '%s'", fldnam);
break;
luaL_error(L, "modal class can't share");
if (share < 0)
luaL_error(L, "missing or wrong share field");
+ if (!order)
+ luaL_error(L, "missing or wrong order field");
if (priority < 0)
luaL_error(L, "negative priority");
- if (!mrp_application_class_create(name, priority, modal, share))
+ if (!mrp_application_class_create(name, priority, modal, share, order))
luaL_error(L, "failed to create application class '%s'", name);
appclass = (appclass_t *)mrp_lua_create_object(L, APPCLASS_CLASS, name,0);
switch (fld) {
case NAME: lua_pushstring(L, ac->name); break;
case PRIORITY: lua_pushinteger(L, ac->priority); break;
+ case MODAL: lua_pushboolean(L, ac->modal); break;
+ case SHARE: lua_pushboolean(L, ac->share); break;
+ case ORDER: push_order(L, ac->order); break;
default: lua_pushnil(L); break;
}
}
return lua_toboolean(L, idx) ? 1 : 0;
}
+static mrp_resource_order_t check_order(lua_State *L, int idx)
+{
+ const char *str = luaL_checkstring(L, idx);
+
+ if (!strcasecmp(str, "fifo"))
+ return MRP_RESOURCE_ORDER_FIFO;
+
+ if (!strcasecmp(str, "lifo"))
+ return MRP_RESOURCE_ORDER_LIFO;
+
+ luaL_error(L, "invalid value for order ('fifo' or 'lifo' accepted only)");
+
+ return MRP_RESOURCE_ORDER_UNKNOWN;
+}
+
+static int push_order(lua_State *L, mrp_resource_order_t order)
+{
+ const char *str;
+
+ switch (order) {
+ case MRP_RESOURCE_ORDER_FIFO: str = "fifo"; break;
+ case MRP_RESOURCE_ORDER_LIFO: str = "lifo"; break;
+ default: str = "<unknown>"; break;
+ }
+
+ lua_pushstring(L, str);
+
+ return 1;
+}
+
static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
{
return SHARE;
if (!strcmp(name, "grant"))
return GRANT;
+ if (!strcmp(name, "order"))
+ return ORDER;
break;
case 6:
#define MRP_ATTRIBUTE_MAX (sizeof(mrp_attribute_mask_t) * 8)
typedef enum mrp_resource_state_e mrp_resource_state_t;
+typedef enum mrp_resource_order_e mrp_resource_order_t;
typedef enum mrp_resource_access_e mrp_resource_access_t;
typedef struct mrp_resource_client_s mrp_resource_client_t;
MRP_RESOURCE_RW = (MRP_RESOURCE_READ | MRP_RESOURCE_WRITE)
};
+enum mrp_resource_order_e {
+ MRP_RESOURCE_ORDER_UNKNOWN = 0,
+ MRP_RESOURCE_ORDER_FIFO,
+ MRP_RESOURCE_ORDER_LIFO
+};
+
union mrp_attr_value_u {
const char *string;
int32_t integer;