Add 2 new kind of event for running a memory or a io bounded load. 
"mem" name for a load is memory bounded, and "iorun" name for a load is io
bounded. The default file to be written to create the load is /dev/null and
the device/file could be specified with "io_device" key in "global" section.

E.g.
"tasks" : {
"thread0" :
{ "sleep" : 1000, "run" : 100, "mem" : 1000, "sleep" 10000, "iorun" : 1000 }
},
"global" : { "io_device" : "/dev/ttyS0" }

Signed-off-by: pi-cheng.chen <pi-cheng.c...@linaro.org>
---
 src/rt-app.c              | 74 +++++++++++++++++++++++++++++++++++++++++++++++
 src/rt-app.h              |  2 ++
 src/rt-app_parse_config.c | 23 +++++++++++++++
 src/rt-app_types.h        |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/src/rt-app.c b/src/rt-app.c
index 3cd601d..13f72e4 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -33,6 +33,8 @@ static volatile int continue_running;
 static pthread_t *threads;
 static int nthreads;
 static int p_load;
+static char *buffer[2];
+static int io_fd;
 rtapp_options_t opts;
 
 static ftrace_data_t ft_data = {
@@ -110,6 +112,45 @@ static inline loadwait(unsigned long exec)
        return load_count;
 }
 
+static void ioload(unsigned long count)
+{
+       ssize_t ret;
+       char *buf = buffer[0];
+
+       while (count != 0) {
+               ret = write(io_fd, buffer, count);
+               if (ret == -1) {
+                       perror("write");
+                       return;
+               }
+               count -= ret;
+               buf += ret;
+       }
+}
+
+static void memload(unsigned long count)
+{
+       static unsigned long current = 0;
+
+       while (count > 0) {
+               unsigned long size;
+
+               if (count > MEM_BUFFER_SIZE)
+                       size = MEM_BUFFER_SIZE;
+               else
+                       size = count;
+
+               if (size > (MEM_BUFFER_SIZE - current))
+                       size = MEM_BUFFER_SIZE - current;
+
+               memcpy(buffer[0], buffer[1], size);
+               count -= size;
+               current += size;
+               if (current >= MEM_BUFFER_SIZE)
+                       current -= MEM_BUFFER_SIZE;
+       }
+}
+
 static int run_event(event_data_t *event, int dry_run,
                unsigned long *perf, unsigned long *duration, rtapp_resource_t 
*resources)
 {
@@ -196,6 +237,18 @@ static int run_event(event_data_t *event, int dry_run,
                pthread_mutex_unlock(&(ddata->res.mtx.obj));
                break;
                }
+       case rtapp_mem:
+               {
+                       log_debug("mem %d", event->count);
+                       memload(event->count);
+               }
+               break;
+       case rtapp_iorun:
+               {
+                       log_debug("iorun %d", event->count);
+                       ioload(event->count);
+               }
+               break;
        }
 
        return lock;
@@ -488,6 +541,22 @@ int main(int argc, char* argv[])
 
        parse_command_line(argc, argv, &opts);
 
+       /* allocate memory buffers for memory-bound and IO-bound busy loops */
+       buffer[0] = malloc(MEM_BUFFER_SIZE);
+       buffer[1] = malloc(MEM_BUFFER_SIZE);
+       if (!buffer[0] || !buffer[1]) {
+               log_error("Cannot allocate memory buffers for memory-bound and"
+                               "IO-bound busy loops");
+               exit(EXIT_FAILURE);
+       }
+
+       /* open file for IO-bound busy loops */
+       io_fd = open(opts.io_device, O_CREAT | O_WRONLY, 0644);
+       if (io_fd < 0) {
+               log_error("Cannot open io_device file %s", opts.io_device);
+               exit(EXIT_FAILURE);
+       }
+
        /* allocated threads */
        nthreads = opts.nthreads;
        threads = malloc(nthreads * sizeof(pthread_t));
@@ -713,6 +782,11 @@ int main(int argc, char* argv[])
                close(ft_data.trace_fd);
                close(ft_data.marker_fd);
        }
+
+       close(io_fd);
+       free(buffer[0]);
+       free(buffer[1]);
+
        exit(EXIT_SUCCESS);
 
 
diff --git a/src/rt-app.h b/src/rt-app.h
index d55271f..477d493 100644
--- a/src/rt-app.h
+++ b/src/rt-app.h
@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 02110-1301, USA.
 
 #define BUDGET_OVERP 5
 
+#define MEM_BUFFER_SIZE        (4 * 1024 * 1024)
+
 void *thread_body(void *arg);
 
 #endif /* _RT_APP_H_ */
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c
index e062f79..f715424 100644
--- a/src/rt-app_parse_config.c
+++ b/src/rt-app_parse_config.c
@@ -320,6 +320,22 @@ parse_thread_event_data(char *name, struct json_object 
*obj,
                return;
        }
 
+       if (!strncmp(name, "mem", strlen("mem")) ||
+                       !strncmp(name, "iorun", strlen("iorun"))) {
+               if (!json_object_is_type(obj, json_type_int))
+                       goto unknown_event;
+
+               data->count = json_object_get_int(obj);
+
+               if (!strncmp(name, "mem", strlen("mem")))
+                       data->type = rtapp_mem;
+               else
+                       data->type = rtapp_iorun;
+
+               log_info(PIN2 "type %d count %d", data->type, data->count);
+               return;
+       }
+
        if (!strncmp(name, "lock", strlen("lock")) ||
                        !strncmp(name, "unlock", strlen("unlock"))) {
 
@@ -493,6 +509,10 @@ obj_is_event(char *name)
                        return rtapp_suspend;
        if (!strncmp(name, "resume", strlen("resume")))
                        return rtapp_resume;
+       if (!strncmp(name, "mem", strlen("mem")))
+                       return rtapp_mem;
+       if (!strncmp(name, "iorun", strlen("iorun")))
+                       return rtapp_iorun;
 
        return 0;
 }
@@ -677,6 +697,7 @@ parse_global(struct json_object *global, rtapp_options_t 
*opts)
                opts->logbasename = strdup("rt-app");
                opts->ftrace = 0;
                opts->pi_enabled = 0;
+               opts->io_device = strdup("/dev/null");
                return;
        }
 
@@ -719,6 +740,8 @@ parse_global(struct json_object *global, rtapp_options_t 
*opts)
                                                  TRUE, "rt-app");
        opts->ftrace = get_bool_value_from(global, "ftrace", TRUE, 0);
        opts->pi_enabled = get_bool_value_from(global, "pi_enabled", TRUE, 0);
+       opts->io_device = get_string_value_from(global, "io_device", TRUE,
+                                               "/dev/null");
 
 }
 
diff --git a/src/rt-app_types.h b/src/rt-app_types.h
index cefb3a6..3a7c231 100644
--- a/src/rt-app_types.h
+++ b/src/rt-app_types.h
@@ -65,6 +65,8 @@ typedef enum resource_t
        rtapp_timer,
        rtapp_suspend,
        rtapp_resume,
+       rtapp_mem,
+       rtapp_iorun,
 } resource_t;
 
 struct _rtapp_mutex {
@@ -103,6 +105,7 @@ typedef struct _event_data_t {
        int res;
        int dep;
        int duration;
+       int count;
 } event_data_t;
 
 typedef struct _phase_data_t {
@@ -165,6 +168,7 @@ typedef struct _rtapp_options_t {
 
        int ftrace;
        int die_on_dmiss;
+       char *io_device;
 } rtapp_options_t;
 
 typedef struct _timing_point_t {
-- 
1.9.1


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to