};
static long jiffy;
+static int taskstat_support = -1;
static int process_get_cpu_util(struct resource *res,
const struct resource_attribute *attr,
switch (attr->id) {
case PROCESS_ATTR_NAME:
+ if (!taskstat_support && (strlen(ctx->comm) == 0)) {
+ char *stat_fields[PROCESS_STAT_FIELD_MAX];
+ char buffer[BUFF_MAX];
+ int ret, len;
+
+ ret = kernel_get_process_stat_fields(ctx->tgid, buffer,
+ BUFF_MAX, stat_fields);
+ if (ret < 0)
+ break;
+
+ len = strlen(stat_fields[PROCESS_STAT_FIELD_COMM]) - 2/* '(', ')' */;
+ len = (len < TS_COMM_LEN - 1) ? len : TS_COMM_LEN - 1;
+ strncpy(ctx->comm, stat_fields[PROCESS_STAT_FIELD_COMM] + 1, len);
+ }
+
strncpy((char *)data, ctx->comm, TS_COMM_LEN);
break;
case PROCESS_ATTR_PGID:
*((int *)data) = ctx->pgid;
break;
case PROCESS_ATTR_PPID:
+ if (ctx->ppid < 0) {
+ char *stat_fields[PROCESS_STAT_FIELD_MAX];
+ char buffer[BUFF_MAX];
+ int ret;
+
+ ret = kernel_get_process_stat_fields(ctx->tgid, buffer,
+ BUFF_MAX, stat_fields);
+ if (ret < 0)
+ break;
+
+ ctx->ppid = atoi(stat_fields[PROCESS_STAT_FIELD_PPID]);
+ }
+
*((int *)data) = ctx->ppid;
break;
}
return 0;
}
+static bool process_check_taskstat_support(struct resource *resource,
+ const struct resource_attribute *attr)
+{
+ return !!taskstat_support;
+}
+
static bool process_check_gpu_support(struct resource *resource,
const struct resource_attribute *attr)
{
.type = DATA_TYPE_DOUBLE,
.ops = {
.get = process_get_cpu_util,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_MEM_VIRT",
.type = DATA_TYPE_UINT64,
.ops = {
.get = process_get_mem_attrs,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_MEM_RSS",
.type = DATA_TYPE_UINT64,
.ops = {
.get = process_get_mem_attrs,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_MEM_RSS_PERCENT",
.type = DATA_TYPE_DOUBLE,
.ops = {
.get = process_get_mem_attrs,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_DISK_READ_PER_SEC",
.type = DATA_TYPE_DOUBLE,
.ops = {
.get = process_get_disk_attrs,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_DISK_WRITE_PER_SEC",
.type = DATA_TYPE_DOUBLE,
.ops = {
.get = process_get_disk_attrs,
- .is_supported = resource_attr_supported_always,
+ .is_supported = process_check_taskstat_support,
},
}, {
.name = "PROCESS_ATTR_NAME",
ctx->prev_total_time = get_total_cpu_time();
/* update initial status */
- ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true);
- if (ret < 0)
- return ret;
+ if (taskstat_support) {
+ ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true);
+ if (ret < 0)
+ return ret;
+
+ memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1);
+ ctx->ppid = ctx->curr.ac_ppid;
+ } else {
+ /*
+ * if taskstat is not supported, comm, pgid and ppid is retrieved
+ * from procfs status lazily.
+ *
+ * ctx->comm is now "\0" so it is treated as not initialized.
+ */
+ ctx->ppid = -1;
+ }
+
+ ctx->pgid = -1;
ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem);
if (ret < 0)
return ret;
- memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1);
-
- ctx->pgid = -1;
- ctx->ppid = ctx->curr.ac_ppid;
-
return 0;
}
include_gpu_mem = is_resource_attr_interested(res, PROCESS_GROUP_ATTR_MEM_GPU);
- memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats));
-
- ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false);
- if (ret < 0)
- return ret;
+ if (taskstat_support) {
+ memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats));
+ ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false);
+ if (ret < 0)
+ return ret;
+ }
ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem);
if (ret < 0)
return -EINVAL;
}
+ if (taskstat_support < 0)
+ taskstat_support = (int)kernel_check_taskstat_support();
+
ctx = calloc(1, sizeof(struct process_context));
if (!ctx)
return -ENOMEM;