return climit;
}
-unsigned int cpu_limit_get_usage_msecs(struct cpu_limit *climit)
+unsigned int
+cpu_limit_get_usage_msecs(struct cpu_limit *climit, enum cpu_limit_type type)
{
struct rusage rusage;
- struct timeval cpu_usage;
+ struct timeval cpu_usage = { 0, 0 };
int usage_diff;
/* Query cpu usage so far */
if (getrusage(RUSAGE_SELF, &rusage) < 0)
i_fatal("getrusage() failed: %m");
- cpu_usage = rusage.ru_utime;
- timeval_add(&cpu_usage, &rusage.ru_stime);
-
- struct timeval initial_total = climit->initial_usage.ru_utime;
- timeval_add(&initial_total, &climit->initial_usage.ru_stime);
+ if ((type & CPU_LIMIT_TYPE_USER) != 0)
+ timeval_add(&cpu_usage, &rusage.ru_utime);
+ if ((type & CPU_LIMIT_TYPE_SYSTEM) != 0)
+ timeval_add(&cpu_usage, &rusage.ru_stime);
+
+ struct timeval initial_total = { 0, 0 };
+ if ((type & CPU_LIMIT_TYPE_USER) != 0)
+ timeval_add(&initial_total, &climit->initial_usage.ru_utime);
+ if ((type & CPU_LIMIT_TYPE_SYSTEM) != 0)
+ timeval_add(&initial_total, &climit->initial_usage.ru_stime);
usage_diff = timeval_diff_msecs(&cpu_usage, &initial_total);
i_assert(usage_diff >= 0);
struct cpu_limit;
+enum cpu_limit_type {
+ CPU_LIMIT_TYPE_USER = BIT(0),
+ CPU_LIMIT_TYPE_SYSTEM = BIT(1),
+};
+#define CPU_LIMIT_TYPE_ALL (CPU_LIMIT_TYPE_USER | CPU_LIMIT_TYPE_SYSTEM)
+
typedef void cpu_limit_callback_t(void *context);
/* Call the callback when the CPU time limit is exceeded. The callback is called
(cpu_limit_callback_t *)callback, context)
void cpu_limit_deinit(struct cpu_limit **_climit);
-unsigned int cpu_limit_get_usage_msecs(struct cpu_limit *climit);
+unsigned int cpu_limit_get_usage_msecs(struct cpu_limit *climit,
+ enum cpu_limit_type type);
-static inline unsigned int cpu_limit_get_usage_secs(struct cpu_limit *climit)
+static inline unsigned int
+cpu_limit_get_usage_secs(struct cpu_limit *climit, enum cpu_limit_type type)
{
- return cpu_limit_get_usage_msecs(climit) / 1000;
+ return cpu_limit_get_usage_msecs(climit, type) / 1000;
}
#endif