Hi,
This patch adds a library for cpu controller testing. The library contains
the common functions used by all test cases. These functions will be further
used in testcases for memory controller also.
In addition to the library code this patch also contains the changes required
to call and use library functions in testcase 1(2).
<addlibrary.patch>
Signed-off-by: Sudhir Kumar <[EMAIL PROTECTED]>
Index:
ltp-full-20080131/testcases/kernel/controllers/libcontrollers/libcontrollers.c
===================================================================
--- /dev/null
+++
ltp-full-20080131/testcases/kernel/controllers/libcontrollers/libcontrollers.c
@@ -0,0 +1,164 @@
+#include "libcontrollers.h"
+
+/*
+ * Function: scan_shares_file()
+ * This function scans all the shares files under the mountpoint
+ * of the controller and returns the total added shares of all
+ * the groups (currently excludes default group) ??
+ */
+int scan_shares_files ()
+{
+ struct stat statbuffer;
+ DIR *dp;
+ char *path_pointer;
+
+ /*
+ * Check if we can get stat of the file
+ */
+ if (lstat (fullpath, &statbuffer) < 0)
+ error_function("Can not read stat for file ", fullpath);
+
+ if (S_ISDIR (statbuffer.st_mode) == 0) /* not a directory */
+ {
+ /*
+ * We run all user tasks in the created groups and not default groups.
So
+ * exclude the shares of default group. FLAG to ensure dir_pointer is
non NULL
+ */
+ if ((FLAG == 1) && (strcmp(fullpath, "/dev/cpuctl/cpu.shares")
!= 0) &&\
+ (strcmp (dir_pointer->d_name, "cpu.shares") == 0))
+ {
+ *shares_pointer += read_shares_file (fullpath);
+ }
+ return 0;
+ }
+
+ /*
+ * Now it's a directory. let the path_pointer point to the end
+ * of fullpath to append new files names
+ */
+
+ path_pointer = fullpath + strlen(fullpath);
+ *path_pointer++ = '/';
+ *path_pointer = 0;
+
+ if ((dp = opendir(fullpath)) == NULL) /* Error in opening directory */
+ error_function("Can't open ", fullpath);
+ /*
+ * search all groups recursively and get total shares
+ */
+
+ while ((dir_pointer = readdir(dp)) != NULL) /* Error in reading
directory */
+ {
+ if ((strcmp(dir_pointer->d_name, ".") == 0) ||
(strcmp(dir_pointer->d_name, "..") == 0))
+ continue; /* ignore current and parent directory
*/
+
+ FLAG = 1;
+ strcpy (path_pointer, dir_pointer->d_name ); /* append name to
fullpath */
+
+ if ((retval = scan_shares_files()) != 0)
+ break;
+ }
+
+ /*
+ * This directory is searched fully. let us go back to parent directory
again
+ */
+
+ path_pointer[-1] = 0;
+
+ if (closedir (dp) < 0)
+ error_function("Could not close dir ", fullpath);
+ return 0;
+}
+
+/*
+ * Function: read_file ()
+ * This function is written keeping in mind the support
+ * to read other files also if required in future.
+ * Each file under a group contains some diff parameter/s
+ */
+
+int read_file(char *filepath, int action, unsigned int *value)
+{
+ int num_line = 0;
+ FILE *fp;
+ switch (action)
+ {
+ case GET_SHARES:
+ *value = read_shares_file(filepath);
+ if (*value == -1)
+ return -1;
+ break;
+
+ case GET_TASKS:
+ fp = fopen (filepath, "r");
+ if (fp == NULL)
+ error_function("Could not open file", filepath);
+ while(fgets(target, LINE_MAX, fp) != NULL)
+ num_line++;
+ *value = (unsigned int)num_line;
+ if (fclose (fp))
+ error_function ("Could not close file",
filepath);
+ break;
+
+ default:
+ error_function("Wrong action type passed to fun
read_file for ", filepath);
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Function: errir_function()
+ * Prints error message and returns -1
+ */
+
+inline int error_function(char *msg1, char *msg2)
+{
+ fprintf (stdout,"ERROR: %s ", msg1);
+ fprintf (stdout,"%s\n", msg2);
+ return -1;
+
+}
+
+/* Function: read_shares_file()
+ * Reads shares value from a given shares file and writes them to
+ * the given pointer location. Returns 0 if success
+ */
+
+unsigned
+int read_shares_file (char *filepath)
+{
+ FILE *fp;
+ unsigned int shares;
+ fp = fopen (filepath, "r");
+ if (fp == NULL)
+ error_function("Could not open file", filepath);
+ fscanf (fp, "%u", &shares);
+ if (fclose (fp))
+ error_function ("Could not close file", filepath);
+ return shares;
+}
+
+/* Function: write_to_file()
+ * writes value to shares file or pid to tasks file
+ */
+
+int write_to_file (char *file, const char *mode, unsigned int value)
+{
+ FILE *fp;
+ fp = fopen (file, mode);
+ if (fp == NULL)
+ error_function ("in opening file for writing:", file);
+ fprintf (fp, "%u\n", value);
+ fclose (fp);
+ return 0;
+}
+/* Function: signal_handler_alarm()
+ * signal handler for the new action
+ */
+
+void signal_handler_alarm (int signal)
+{
+ timer_expired = 1;
+}
+
Index: ltp-full-20080131/testcases/kernel/controllers/libcontrollers/Makefile
===================================================================
--- /dev/null
+++ ltp-full-20080131/testcases/kernel/controllers/libcontrollers/Makefile
@@ -0,0 +1,15 @@
+TARGET=libcontrollers.a
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,%.o,$(SRCS))
+
+all : $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(AR) -cr $@ $^
+
+clean:
+ rm -f $(TARGET) $(OBJS)
+
+install:
+
+
Index:
ltp-full-20080131/testcases/kernel/controllers/libcontrollers/libcontrollers.h
===================================================================
--- /dev/null
+++
ltp-full-20080131/testcases/kernel/controllers/libcontrollers/libcontrollers.h
@@ -0,0 +1,47 @@
+#include <dirent.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef PATH_MAX
+char fullpath[PATH_MAX];
+#else
+char fullpath[1024]; /* Guess */
+#endif
+
+int FLAG, timer_expired;
+
+int retval;
+
+unsigned int num_line;//??
+
+unsigned int current_shares;
+
+unsigned int total_shares;
+
+unsigned int *shares_pointer;//??
+
+char target[LINE_MAX];
+
+struct dirent *dir_pointer;
+
+enum{
+ GET_SHARES =1,
+ GET_TASKS
+};
+
+inline int error_function(char *msg1, char *msg2);
+
+unsigned int read_shares_file (char *filepath);
+
+int read_file(char *filepath, int action, unsigned int *value);
+
+int scan_shares_files ();
+
+int write_to_file (char * file, const char* mode, unsigned int value);
+
+void signal_handler_alarm (int signal );
Index: ltp-full-20080131/testcases/kernel/controllers/Makefile
===================================================================
--- ltp-full-20080131.orig/testcases/kernel/controllers/Makefile
+++ ltp-full-20080131/testcases/kernel/controllers/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS = cpuctl
+SUBDIRS = libcontrollers cpuctl
CHECK_CPUCTL = $(shell grep -w cpu /proc/cgroups|cut -f1)
all:
@set -e;
Index: ltp-full-20080131/testcases/kernel/controllers/cpuctl/Makefile
===================================================================
--- ltp-full-20080131.orig/testcases/kernel/controllers/cpuctl/Makefile
+++ ltp-full-20080131/testcases/kernel/controllers/cpuctl/Makefile
@@ -1,6 +1,6 @@
CFLAGS += -Wall
-CPPFLAGS += -I../../../../include
-LDLIBS += -lm -L../../../../lib/ -lltp
+CPPFLAGS += -I../../../../include -I../libcontrollers
+LDLIBS += -lm -L../../../../lib/ -L../libcontrollers -lcontrollers -lltp
SRCS = $(wildcard *.c)
Index: ltp-full-20080131/testcases/kernel/controllers/cpuctl/cpuctl_test01.c
===================================================================
--- ltp-full-20080131.orig/testcases/kernel/controllers/cpuctl/cpuctl_test01.c
+++ ltp-full-20080131/testcases/kernel/controllers/cpuctl/cpuctl_test01.c
@@ -55,6 +55,7 @@
#include <time.h>
#include <unistd.h>
+#include "../libcontrollers/libcontrollers.h"
#include "test.h" /* LTP harness APIs*/
#define TIME_INTERVAL 60 /* Time interval in seconds*/
@@ -66,21 +67,19 @@ extern int Tst_count;
char *TCID = "cpu_controller_test01";
int TST_TOTAL = 1;
pid_t scriptpid;
+char path[] = "/dev/cpuctl";
extern void
cleanup()
{
kill (scriptpid, SIGUSR1);/* Inform the shell to do cleanup*/
tst_exit (); /* Report exit status*/
}
-
-int write_to_file (char * file, const char* mode, unsigned int value);
-void signal_handler_alarm (int signal );
int timer_expired = 0;
int main(int argc, char* argv[])
{
- int num_cpus, test_num; /* To calculate cpu time in %*/
+ int num_cpus, test_num, len; /* num_cpus to
calculate cpu time in %*/
char mygroup[32], mytaskfile[32], mysharesfile[32], ch;
pid_t pid;
int my_group_num, /* A number attached with a group*/
@@ -90,10 +89,13 @@ int main(int argc, char* argv[])
double total_cpu_time, /* Accumulated cpu time*/
delta_cpu_time, /* Time the task could run on cpu(s)
(in an interval)*/
prev_cpu_time=0;
+ double exp_cpu_time; /* Expected time in % as obtained by
shares calculation */
struct rusage cpu_usage;
time_t current_time, prev_time, delta_time;
unsigned long int myshares = 1, baseshares = 1000; /* Simply the
base value to start with*/
+ unsigned int fmyshares, num_tasks;/* f-> from file. num_tasks is tasks
in this group*/
struct sigaction newaction, oldaction;
+
/* Signal handling for alarm*/
sigemptyset (&newaction.sa_mask);
newaction.sa_handler = signal_handler_alarm;
@@ -132,6 +134,33 @@ int main(int argc, char* argv[])
fprintf(stdout,"\ntask-%d SHARES=%lu\n",my_group_num, myshares);
read (fd, &ch, 1); /* To block all tasks here and fire
them up at the same time*/
+
+ /*
+ * We now calculate the expected % cpu time of this task by getting
+ * it's group's shares, the total shares of all the groups and the
+ * number of tasks in this group.
+ */
+ FLAG = 0;
+ total_shares = 0;
+ shares_pointer = &total_shares;
+ len = strlen (path);
+ if (!strncpy (fullpath, path, len))
+ tst_brkm (TBROK, cleanup, "Could not copy directory path %s ",
path);
+
+ if (scan_shares_files() != 0)
+ tst_brkm (TBROK, cleanup, "From function scan_shares_files in
%s ", fullpath);
+
+// fprintf(stdout, "The total shares are: %u\n", total_shares);
+
+ /* return val: -1 in case of function error, else 2 is min share value
*/
+ if ((fmyshares = read_shares_file(mysharesfile)) < 2)
+ tst_brkm (TBROK, cleanup, "in reading shares files %s ",
mysharesfile);
+
+ if ((read_file (mytaskfile, GET_TASKS, &num_tasks)) < 0)
+ tst_brkm (TBROK, cleanup, "in reading tasks files %s ",
mytaskfile);
+
+ exp_cpu_time = (double)(fmyshares * 100) /(total_shares * num_tasks);
+
prev_time = time (NULL); /* Note down the time*/
while (1)
@@ -159,7 +188,9 @@ int main(int argc, char* argv[])
else
mytime = (delta_cpu_time * 100) /
(TIME_INTERVAL * num_cpus);
- fprintf (stdout,"PID: %u\ttask-%d:cpu time --->
%6.3f\%(%fs) --->%lu(shares)\tinterval:%lu\n",getpid(),my_group_num, mytime,
delta_cpu_time, myshares, delta_time);
+ fprintf (stdout,"task-%d:CPU TIME{calc:-%6.2f(s)i.e.
%6.2f(\%) exp:-%6.2f(\%)}\
+with %lu(shares) in %lu (s) INTERVAL\n",my_group_num, delta_cpu_time, mytime,\
+exp_cpu_time, myshares, delta_time);
first_counter++;
if (first_counter >= NUM_INTERVALS) /* Take n sets
of readings for each shares value*/
@@ -189,21 +220,3 @@ int main(int argc, char* argv[])
}/* end while*/
}/* end main*/
-
-int write_to_file (char *file, const char *mode, unsigned int value)
-{
- FILE *fp;
- fp = fopen (file, mode);
- if (fp == NULL)
- {
- tst_brkm (TBROK, cleanup, "Could not open file %s for writing",
file);
- }
- fprintf (fp, "%u\n", value);
- fclose (fp);
- return 0;
-}
-
-void signal_handler_alarm (int signal)
-{
- timer_expired = 1;
-}
Thanks,
Sudhir Kumar
LTC, ISTL
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list