On 07/19/2012 03:41 AM, Rob Landley wrote:
Meaning to works as renice, rather than nice. I'm open to suggestions, I
can as well the 'work-as-nice' functionality,

Is there more to it than:

   if (opt.argc>2) xexec(toys.optargs+2);

Well, taskset getpid() and then exec. And detect -p... ok there's a bit
of work.

I'd prefer if you could add the new work-as-nice stuff since you know
what the UI should be like, and I'll hold off converting to the raw
syscall until then. Sound good?


In attach a patch which makes taskset work as both nice (and renice, the existing behavior).

The following example which spawns four loops:

#include <pthread.h>

void * loop(void * ptr)
{
    while(1){}
}

int main()
{
    int i = 0;
    for (i=0; i< 4; i++)
    {
        pthread_t tid;
        pthread_create(&tid, NULL, loop, NULL);
    }
    sleep(100);
    return 0;
}

executed as follows:

edb@lapedb:~/edb-stuff/toybox/toybox$ sudo ./toybox taskset 55 ./a.out

on my poor little quad-core with hyperthreading gives the following top output:

top - 09:50:37 up  1:23, 14 users,  load average: 3.52, 1.49, 0.79
Tasks: 195 total,   1 running, 193 sleeping,   0 stopped,   1 zombie
%Cpu0  : 99.7 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.3
%Cpu1  :  7.3 us,  2.7 sy,  0.0 ni, 90.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu2  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu3  :  6.0 us,  4.0 sy,  0.0 ni, 90.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu4  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu5  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu6  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0
%Cpu7  :  0.7 us,  0.0 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0

my 2 cents
E.

--
Elie De Brauwer

# HG changeset patch
# User Elie De Brauwer <[email protected]>
# Date 1342770207 -7200
# Node ID 8f22dbddf1e6d9f131e96612f71702bb9f8486e2
# Parent  98bde84a888c8b4136921b2ee21b0227d818f2f1
taskset.c now also support executing new commands with a given cpu affinity mask

diff -r 98bde84a888c -r 8f22dbddf1e6 toys/taskset.c
--- a/toys/taskset.c	Fri Jul 20 08:42:44 2012 +0200
+++ b/toys/taskset.c	Fri Jul 20 09:43:27 2012 +0200
@@ -6,24 +6,28 @@
  *
  * Not in SUSv4.
 
-USE_TASKSET(NEWTOY(taskset, "<1>2a", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_TASKSET(NEWTOY(taskset, "<1pa", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 
 config TASKSET
 	bool "taskset"
 	default y
 	help
-	  usage: taskset [-a] [mask] PID
+	  usage: taskset [-ap] [mask] [PID|cmd [args...]]
 
 	  When mask is present the CPU affinity mask of a given PID will
 	  be set to this mask. When a mask is not given, the mask will
 	  be printed. A mask is a hexadecimal string where the bit position
 	  matches the cpu number.
 	  -a	Set/get the affinity of all tasks of a PID.
+	  -p	Set/get the affinity of given PID instead of a new command.
 */
 
 #define _GNU_SOURCE
 #include "toys.h"
 
+#define A_FLAG 0x1
+#define P_FLAG 0x2
+
 static int str_to_cpu_set(char * mask, cpu_set_t *set)
 {
 	int size = strlen(mask);
@@ -73,7 +77,7 @@
 	return toybuf;
 }
 
-static void do_taskset(pid_t pid)
+static void do_taskset(pid_t pid, int quiet)
 {
 	cpu_set_t mask;
 
@@ -81,9 +85,9 @@
 	if (sched_getaffinity(pid, sizeof(mask), &mask))
 		perror_exit("failed to get %d's affinity", pid);
 
-	printf("pid %d's current affinity mask: %s\n", pid, cpu_set_to_str(&mask));
+	if (!quiet) printf("pid %d's current affinity mask: %s\n", pid, cpu_set_to_str(&mask));
 
-	if (toys.optc == 2)
+	if (toys.optc >= 2)
 	{
 		if (str_to_cpu_set(toys.optargs[0], &mask))
 			perror_exit("bad mask: %s", toys.optargs[0]);
@@ -94,7 +98,7 @@
 		if (sched_getaffinity(pid, sizeof(mask), &mask))
 			perror_exit("failed to get %d's affinity", pid);
 
-		printf("pid %d's new affinity mask: %s\n", pid, cpu_set_to_str(&mask));
+		if (!quiet) printf("pid %d's new affinity mask: %s\n", pid, cpu_set_to_str(&mask));
 	}
 }
 
@@ -102,7 +106,7 @@
 {
 	if (!new->parent) return DIRTREE_RECURSE;
 	if (S_ISDIR(new->st.st_mode) && *new->name != '.')
-		do_taskset(atoi(new->name));
+			do_taskset(atoi(new->name), 0);
 
 	return 0;
 }
@@ -111,9 +115,20 @@
 {
 	char * pidstr = (toys.optc==1)?toys.optargs[0]:toys.optargs[1];
 
-	if (toys.optflags & 0x1)
+	if (!(toys.optflags & P_FLAG))
+	{
+		if (toys.optc >= 2)
+		{
+			do_taskset(getpid(),1);
+			xexec(&toys.optargs[1]);
+		}
+		else error_exit("Needs at least a mask and a command");
+	}
+
+	if (toys.optflags & A_FLAG)
 	{
 		sprintf(toybuf, "/proc/%s/task/", pidstr);
 		dirtree_read(toybuf, task_cb);
-	} else do_taskset(atoi(pidstr));
+	} else 
+		do_taskset(atoi(pidstr), 0);
 }
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to