resource: add configurable 'fifo' and 'lifo' ordering to application classes
authorJanos Kovacs <jankovac503@gmail.com>
Thu, 14 Feb 2013 01:44:11 +0000 (03:44 +0200)
committerJanos Kovacs <jankovac503@gmail.com>
Thu, 14 Feb 2013 01:59:32 +0000 (03:59 +0200)
src/daemon/murphy.lua
src/resource/application-class.c
src/resource/application-class.h
src/resource/config-api.h
src/resource/config-lua.c
src/resource/data-types.h

index 262bcd2..b18e734 100644 (file)
@@ -54,12 +54,12 @@ end
 
 
 -- 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 {
index 27bdee5..fb7b2b5 100644 (file)
@@ -83,6 +83,8 @@
 #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;
@@ -103,9 +105,10 @@ static void insert_into_application_class_table(const char *, uint32_t);
 
 
 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;
@@ -150,6 +153,7 @@ mrp_application_class_t *mrp_application_class_create(const char *name,
     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]);
@@ -318,6 +322,9 @@ void mrp_application_class_move_resource_set(mrp_resource_set_t *rset)
 
 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;
@@ -326,10 +333,15 @@ uint32_t mrp_application_class_get_sorting_key(mrp_resource_set_t *rset)
 
     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;
 
index 534dbe0..02b692b 100644 (file)
 
 
 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 *);
index fb53513..6d7f60a 100644 (file)
@@ -38,9 +38,10 @@ int mrp_zone_definition_create(mrp_attr_def_t *attrdefs);
 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);
 
index 0de7e61..f9e7334 100644 (file)
@@ -80,6 +80,7 @@ enum field_e {
     MODAL,
     SHARE,
     GRANT,
+    ORDER,
     SHARED,
     METHOD,
     OWNERS,
@@ -197,6 +198,8 @@ static mrp_attr_t *check_attrs(lua_State *, int, attr_def_t *);
 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);
 
@@ -573,6 +576,7 @@ static int appclass_create(lua_State *L)
     int priority = 0;
     int modal = -1;
     int share = -1;
+    mrp_resource_order_t order = 0;
     const char *name = NULL;
 
     MRP_LUA_ENTER;
@@ -597,6 +601,10 @@ static int appclass_create(lua_State *L)
             share = check_boolean(L, -1);
             break;
 
+        case ORDER:
+            order = check_order(L, -1);
+            break;
+
         default:
             luaL_error(L, "unexpected field '%s'", fldnam);
             break;
@@ -611,9 +619,11 @@ static int appclass_create(lua_State *L)
         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);
@@ -643,6 +653,9 @@ static int appclass_getfield(lua_State *L)
         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;
         }
     }
@@ -1514,6 +1527,36 @@ static int check_boolean(lua_State *L, int idx)
     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)
 {
@@ -1558,6 +1601,8 @@ static field_t field_name_to_type(const char *name, size_t len)
             return SHARE;
         if (!strcmp(name, "grant"))
             return GRANT;
+        if (!strcmp(name, "order"))
+            return ORDER;
         break;
 
     case 6:
index c86f20f..9040755 100644 (file)
@@ -50,6 +50,7 @@
 #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;
@@ -87,6 +88,12 @@ enum mrp_resource_access_e {
     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;