summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2015-08-24 14:18:28 +0200
committerVincent Guittot <vincent.guittot@linaro.org>2015-08-24 14:18:28 +0200
commitdc08dc380cb32c7a9341176709334a363df3dcd5 (patch)
tree9328c10f12b83f6e5a77c8fd08c4d83d843343bc
parent3d5b0ebcd48b818b987802fd216121b66113a305 (diff)
workgen: Add IO-bounded and memory-bounded eventslinaro-v1.0
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. The size of per-thread memory buffer to create IO/memory load could also be specified with "mem_buffer_size" in the same section. Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> [ replace Text by String in tutorial.txt] Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
-rw-r--r--doc/examples/tutorial/example6.json29
-rw-r--r--doc/tutorial.txt18
-rw-r--r--src/rt-app.c48
-rw-r--r--src/rt-app_parse_config.c58
-rw-r--r--src/rt-app_types.h16
5 files changed, 169 insertions, 0 deletions
diff --git a/doc/examples/tutorial/example6.json b/doc/examples/tutorial/example6.json
new file mode 100644
index 0000000..06899eb
--- /dev/null
+++ b/doc/examples/tutorial/example6.json
@@ -0,0 +1,29 @@
+{
+ /*
+ * Simple use case which creates CPU-, memory-,
+ * and IO-bouned load for 2 seconds duration.
+ */
+ "tasks" : {
+ "thread0" : {
+ "instance" : 1,
+ "loop" : -1,
+ "run" : 1000,
+ "mem" : 1000,
+ "sleep" : 5000,
+ "iorun" : 100000
+ }
+ },
+ "global" : {
+ "duration" : 2,
+ "calibration" : "CPU0",
+ "default_policy" : "SCHED_OTHER",
+ "pi_enabled" : false,
+ "lock_pages" : false,
+ "logdir" : "./",
+ "log_basename" : "rt-app2",
+ "ftrace" : true,
+ "gnuplot" : true,
+ "io_device" : "/dev/null",
+ "mem_buffer_size" : 1048576
+ }
+}
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index b2b0971..9c47178 100644
--- a/doc/tutorial.txt
+++ b/doc/tutorial.txt
@@ -81,6 +81,14 @@ case. Default value is False.
* gnuplot : Boolean. if True, it will create a gnu plot compatible file for
each threads (see gnuplot section for more details). Default value is False.
+"io_device" : Text. Path to the file which will be written to create IO-bounded
+busy loop. Specify it carefully since it might damage the specified file.
+Default value is "/dev/null".
+
+"mem_buffer_size" : Integer. The size of per-thread memory buffer in byte being
+used to create IO-bounded and memory-bounded busy loop. Default value is
+4194304(4MB).
+
*** default global object:
"global" : {
"duration" : -1,
@@ -93,6 +101,8 @@ each threads (see gnuplot section for more details). Default value is False.
"log_basename" : "rt-app",
"ftrace" : false,
"gnuplot" : false,
+ "io_device" : "/dev/null"
+ "mem_buffer_size" : 4194304
}
**** tasks object ****
@@ -187,6 +197,14 @@ frequency or the compute capacity of the CPU.
* sleep : Integer. Emulate the sleep of a task. The duration is defined in
usec.
+* mem : Integer. Emulate the memory write operation. The value defines the size
+in byte to be written into the memory buffer. The size of the memory buffer is
+defined by "mem_buffer_size" in "global" object.
+
+* iorun : Integer. Emulate the IO write operation. The value defined the size
+in byte to be write into the IO device specified by "io_device" in "global"
+object.
+
* timer : Object. Emulate the wake up of the thread by a timer. Timer differs
from sleep event by the start time of the timer duration. Sleep duration starts
at the beginning of the sleep event whereas timer duration starts at the end of
diff --git a/src/rt-app.c b/src/rt-app.c
index 1dbc366..f14f228 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -179,6 +179,42 @@ static inline loadwait(unsigned long exec)
return load_count;
}
+static void ioload(unsigned long count, struct _rtapp_iomem_buf *iomem, int io_fd)
+{
+ ssize_t ret;
+
+ while (count != 0) {
+ unsigned long size;
+
+ if (count > iomem->size)
+ size = iomem->size;
+ else
+ size = count;
+
+ ret = write(io_fd, iomem->ptr, size);
+ if (ret == -1) {
+ perror("write");
+ return;
+ }
+ count -= ret;
+ }
+}
+
+static void memload(unsigned long count, struct _rtapp_iomem_buf *iomem)
+{
+ while (count > 0) {
+ unsigned long size;
+
+ if (count > iomem->size)
+ size = iomem->size;
+ else
+ size = count;
+
+ memset(iomem->ptr, 0, size);
+ count -= size;
+ }
+}
+
static int run_event(event_data_t *event, int dry_run,
unsigned long *perf, unsigned long *duration, rtapp_resource_t *resources)
{
@@ -273,6 +309,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, &rdata->res.buf);
+ }
+ break;
+ case rtapp_iorun:
+ {
+ log_debug("iorun %d", event->count);
+ ioload(event->count, &rdata->res.buf, ddata->res.dev.fd);
+ }
+ break;
}
return lock;
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c
index 144c151..f4ac5cf 100644
--- a/src/rt-app_parse_config.c
+++ b/src/rt-app_parse_config.c
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define PIN2 PIN" "
#define PIN3 PIN2" "
#define JSON_FILE_BUF_SIZE 4096
+#define DEFAULT_MEM_BUF_SIZE (4 * 1024 * 1024)
/* redefine foreach as in <json/json_object.h> but to be ANSI
* compatible */
@@ -191,6 +192,21 @@ static int init_cond_resource(rtapp_resource_t *data, const rtapp_options_t *opt
&data->res.cond.attr);
}
+static int init_membuf_resource(rtapp_resource_t *data, const rtapp_options_t *opts)
+{
+ log_info(PIN3 "Init: %s membuf", data->name);
+
+ data->res.buf.ptr = malloc(opts->mem_buffer_size);
+ data->res.buf.size = opts->mem_buffer_size;
+}
+
+static int init_iodev_resource(rtapp_resource_t *data, const rtapp_options_t *opts)
+{
+ log_info(PIN3 "Init: %s io device", data->name);
+
+ data->res.dev.fd = open(opts->io_device, O_CREAT | O_WRONLY, 0644);
+}
+
static void
init_resource_data(const char *name, int type, int idx, const rtapp_options_t *opts)
{
@@ -211,6 +227,12 @@ init_resource_data(const char *name, int type, int idx, const rtapp_options_t *o
case rtapp_wait:
init_cond_resource(data, opts);
break;
+ case rtapp_mem:
+ init_membuf_resource(data, opts);
+ break;
+ case rtapp_iorun:
+ init_iodev_resource(data, opts);
+ break;
}
}
@@ -333,6 +355,32 @@ 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;
+
+ /* create an unique name for per-thread buffer */
+ ref = create_unique_name(unique_name, sizeof(unique_name), "mem", tag);
+ i = get_resource_index(ref, rtapp_mem, opts);
+ data->res = i;
+ data->count = json_object_get_int(obj);
+
+ /* A single IO devices for all threads */
+ if (strncmp(name, "iorun", strlen("iorun")) == 0) {
+ i = get_resource_index("io_device", rtapp_iorun, opts);
+ data->dep = i;
+ };
+
+ 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"))) {
@@ -527,6 +575,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;
}
@@ -712,6 +764,8 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
opts->ftrace = 0;
opts->lock_pages = 1;
opts->pi_enabled = 0;
+ opts->io_device = strdup("/dev/null");
+ opts->mem_buffer_size = DEFAULT_MEM_BUF_SIZE;
return;
}
@@ -796,6 +850,10 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
opts->ftrace = get_bool_value_from(global, "ftrace", TRUE, 0);
opts->lock_pages = get_bool_value_from(global, "lock_pages", TRUE, 1);
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");
+ opts->mem_buffer_size = get_int_value_from(global, "mem_buffer_size",
+ TRUE, DEFAULT_MEM_BUF_SIZE);
}
diff --git a/src/rt-app_types.h b/src/rt-app_types.h
index eca8ff1..2ce9c9d 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 {
@@ -86,6 +88,15 @@ struct _rtapp_timer {
int init;
};
+struct _rtapp_iomem_buf {
+ char *ptr;
+ int size;
+};
+
+struct _rtapp_iodev {
+ int fd;
+};
+
/* Shared resources */
typedef struct _rtapp_resource_t {
union {
@@ -93,6 +104,8 @@ typedef struct _rtapp_resource_t {
struct _rtapp_cond cond;
struct _rtapp_signal signal;
struct _rtapp_timer timer;
+ struct _rtapp_iomem_buf buf;
+ struct _rtapp_iodev dev;
} res;
int index;
resource_t type;
@@ -104,6 +117,7 @@ typedef struct _event_data_t {
int res;
int dep;
int duration;
+ int count;
} event_data_t;
typedef struct _phase_data_t {
@@ -167,6 +181,8 @@ typedef struct _rtapp_options_t {
int ftrace;
int die_on_dmiss;
+ int mem_buffer_size;
+ char *io_device;
} rtapp_options_t;
typedef struct _timing_point_t {