On Saturday 20 August 2005 10:40, canon wrote: > I don't understand your strategy. > In fact, the current algo looks like this : > pid = get_pid_of_the_process_to_control () > while (1) { > if (cpu_usage_of_process (pid) * 100 > total_time_since_the_start > (pid) * percent) { > kill (SIGSTOP, pid); > usleep (1); usleep (1); //depend on HZ const > kill (SIGCONT, pid); > } > } > I don't know if it is the best solution for controlling the process but > it works (I have just to use the utime and starttime field of the > /proc/<pid>/stat file). > Do you think that it is possible to influence the scheduling of a > process with the counter and priority fields in the same way with a > module ? Or is there better way to make a process sleep in the kernel > space (because I should force the process to suspend its process each ms > to have a fine granularity) ? I don't know if this is the better strategies but I suggest you to implement it with a kernel module. I don't know if you can well control processes by mean of a user processes, but I'm sure that informations you can take by stat file can be taken from a kernel module. I've now better understood your project and thinks seems to be really simpler than as I've previously understood. I give you further suggest on implementation of timer (and related sleep functions). Perhaps, you can implement your program without ioctl. The code below is an example. With user_proc I indicate the task_struct of the process given by find_task_by_pid(pid) --------------------------------------------------------------------------------------------------------------------------------- /* prog_module.c */ #define __NO_VERSION__ #if defined __KERNEL__ # include <linux/kernel.h> #endif #include <linux/autoconf.h> /* <linux/config.h> should be good too */ #if defined( CONFIG_MODVERSIONS ) && ! defined( MODVERSIONS ) # define MODVERSIONS #endif #if defined( MODVERSIONS ) # include <linux/modversions.h> #endif #include <linux/module.h> #include <linux/timer.h> extern int create_device_file(void); extern remove_device_file(void); struct timer_list mtpmc_timer; pid_t user_pid; struc task_struct *user_proc; int cpu_usage_exceed(void) /*IMPORTANT! you have to implement this function { if (cpu_usage_of_process (user_proc) * 100 > total_time_since_the_start (user_proc) * percent) return 1; else return 0; } static void timer_function(unsigned long par) { send_sig(SIGCONT, user_proc, 1); if (cpu_usage_exceed()) send_sig(SIGSTOP, user_proc, 1); mod_timer(&timer, jiffies + par*HZ); /* jiffies is the current time. Timer expires after par*HZ clock ticks, that is, after par seconds */ return; } int prog_init(void) { create_device_file(); init_timer(&timer); return 0; } void prog_exit(void) { remove_device_file(); del_timer(&timer); return; } module_init(prog_init); module_exit(prog_exit); ---------------------------------------------------------------------------------------------------------------------------- I'll explain you something: prog_init and prog_exit are the initialization and exit function that create and delete the timer you've to use. Put all in a program called prog_module.c. Then adds the following operations before the initialization function: static struct file_operations ops = { .write = write, .open = open, .release = release, .owner = THIS_MODULE, }; static ssize_t write(struct file *filp, const char __user *src, size_t count, loff_t *off) { user_pid = ATOI(src); /* IMPORTANT! You have to substitute this function with the corresponding in the kernel space. I don't remember what it is. user_proc = find_task_by_pid(user_pid); timer.function = timer_function; mod_timer(&timer, jiffies + num_sec*HZ); return 0; } static int mtpmc_open(struct inode *ino, struct file *filp) { printk(KERN_DEBUG "open\n"); MOD_INC_USE_COUNT; if (Device_Open){ printk(KERN_DEBUG "Device already open by another user process.\n\n"); return -EBUSY; } Device_Open++; return 0; } static int mtpmc_release(struct inode *ino, struct file *filp) { printk(KERN_DEBUG "release\n"); MOD_DEC_USE_COUNT; Device_Open--; return 0; } int create_device_file(void) { major = register_chrdev(0, "prog", &ops); if (major<0){ printk(KERN_DEBUG "can't get dynamic major number\n"); return major; } return 0; } int remove_device_file(void) { int ret = unregister_chrdev(major, "prog"); if (ret<0){ printk(KERN_DEBUG "error in unregister_chrdev: %d\n", ret); return -1; } return 0; } ---------------------------------------------------------------------------------------------------------------------------- You have to implement the cpu_usage_exceed() function by studying the Scheduling procedure. You can call this modules, after you have insmoded it, by means of a user program. This have to perform only a read operation in order to pass the pid of monitoring process. ---------------------------------------------------------------------------------------------------------------------------- /* prog_user.c */ int main(void) { char pid_par[255]; int fd; printf("Opening...\n"); fd = open("/dev/prog", O_RDWR); if (fd==-1){ printf("Open failure\n"); exit(1); } printf("Insert pid (0 to exit): "); scanf("%s",pid_par); r = read(fd, pid_par, strlen(pid_par), NULL); } ---------------------------------------------------------------------------------------------------------------------------- I give you also a Makefile that you can use to compile the module: ---------------------------------------------------------------------------------------------------------------------------- /* Makefile */ TARGET := prog_module TARGET2 := prog_user INCLUDE := -I /usr/src/linux/include CFLAGS := -O2 -DMODULE -D__KERNEL__ ${INCLUDE} CC := gcc ${TARGET}.o: ${TARGET}.c ${CC} ${CFLAGS} -c ${TARGET}.c user: ${TARGET2}.c ${CC} ${TARGET2}.c -o ${TARGET2} ./${TARGET2} .PHONY: clean install: ${TARGET}.o insmod ./${TARGET}.o uninstall: rmmod ${TARGET} clean: rm -rf ${TARGET}.o rm -rf ${TARGET2} --------------------------------------------------------------------------------------------------------------------- After you have completed the module you have to run: make /*to compile the module*/ make install /*to install the module */ make user /*to execute the user program */ To remove all: make uninstall /* to remove the module */ make clean /* to remove objects file **/ IMPORTANT OBSERVATION!!!!!!!!!!!!!!!!!! 1. You've not to use the ioctl mechanism. I don't use it in the program I've described 2. I hope I'm well wrote the program as I've not tested it. Help yourself y studying the documentation from ULK e LDD. 3. You can also develop a module without implement a user space program but in this case you have to know the pid you want to monitor before inserting module. If so, reply me and I tell you how you can do it, reducing the size of the above program. 4. If you find function that modify the amount of cpu usage of a process, it's better for you as you can call this instruction in the init function without the need to implement timers. 5. Insert the code in file and then print it. Continue studying the Chapter I've indicate to you (except the one treating IOCTL mechanism) and step by step you'll understand better what I'm wrote (and you'll find lso errors that I've make). Vincenzo Mallozzi. ___________________________________ Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB http://mail.yahoo.it -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/