Hey Gilles,

On Wed, 2008-10-22 at 13:51 +0200, Gilles Carry wrote:
> From: gilles.carry <[EMAIL PROTECTED]>
> 
> Syscall sched_setaffinity fails if choosen cpu is not online.
> In set_affinity, thread_id value is used as cpuid when calling
> sched_setaffinity. This fails when disabling cpus because threads ids
> and online cpu ids don't necessarly match.
> 
> This patch simply increments cpuid (max. 8192) until it finds an online cpu.
> This guaranties that no more than one thread is assigned to one cpu.
> If set_affinity is called more times than there are online cpus
> then matrix_mult.c fails.
> 
> Signed-off-by: Gilles Carry <[EMAIL PROTECTED]>

I just thought of something... 

main_thread:

    /* Create numcpus-1 concurrent threads */
    for (j = 0; j < (numcpus-1); j++) {
        tids[j] = create_fifo_thread(concurrent_thread, (void *)(intptr_t)j, 
PRIO);
                                                        ^^^^^^^^^^^^^^^^^^^
This was originally being used as the "cpuid", right?  But no longer...

        if (tids[j] == -1) {
            printf("Thread creation failed (max threads exceeded?)\n");
            break;
        }
    }



> ---
>  testcases/realtime/func/matrix_mult/matrix_mult.c |   58 ++++++++++++++------
>  1 files changed, 40 insertions(+), 18 deletions(-)
> 
> diff --git a/testcases/realtime/func/matrix_mult/matrix_mult.c 
> b/testcases/realtime/func/matrix_mult/matrix_mult.c
> index 21fded8..a551687 100644
> --- a/testcases/realtime/func/matrix_mult/matrix_mult.c
> +++ b/testcases/realtime/func/matrix_mult/matrix_mult.c
> @@ -44,6 +44,7 @@
>  #include <libjvmsim.h>
>  #include <libstats.h>
> 
> +#define MAX_CPUS     8192
>  #define PRIO         43
>  #define MATRIX_SIZE  100
>  #define DEF_OPS              8               /* the higher the number, the 
> more CPU intensive */
> @@ -66,15 +67,13 @@ static float criteria;
>  static int *mult_index;
>  static int *tids;
>  static int *flags;
> +static int online_cpu_id = -1;
> 
>  stats_container_t sdat, cdat, *curdat;
>  stats_container_t shist, chist;
>  static pthread_barrier_t mult_start;
> +static pthread_mutex_t mutex_cpu;
> 
> -int gettid(void)
> -{
> -     return syscall(__NR_gettid);
> -}

You shouldn't remove this... here's why...

> 
>  void usage(void)
>  {
> @@ -148,28 +147,42 @@ void matrix_mult_record(int m_size, int index)
>       curdat->records[index].y = delta;
>  }
> 
> -int set_affinity(int cpuid)
> +int set_affinity(void)
>  {
> -     int tid = gettid();
>       cpu_set_t mask;
> -
> -     CPU_ZERO(&mask);
> -     CPU_SET(cpuid, &mask);
> -
> -     if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
> -             printf("Thread %d: Can't set affinity: %s\n", tid, 
> strerror(errno));
> -             exit(1);
> -     }
> -
> -     return 0;
> +     int cpuid;
> +
> +     pthread_mutex_lock(&mutex_cpu);
> +     do {
> +             ++online_cpu_id;
> +             CPU_ZERO(&mask);
> +             CPU_SET(online_cpu_id, &mask);
> +
> +             if (!sched_setaffinity(0, sizeof(mask), &mask)) {
> +                     cpuid = online_cpu_id; /* Save this value before 
> unlocking mutex */
> +                     pthread_mutex_unlock(&mutex_cpu);
> +                     return cpuid;
> +             }
> +     } while (online_cpu_id < MAX_CPUS);
> +     pthread_mutex_unlock(&mutex_cpu);
> +     return -1;
>  }
> 
>  void *concurrent_thread(void *thread)
>  {
>       struct thread *t = (struct thread *)thread;
>       int thread_id = (intptr_t)t->arg;

This _was_ being passed to set_affinity and being used as the "cpuid",
but with your changes, this is no longer the case... the true thread id
and the thread id that was being reported by the old implementation of
set_affinity was actually be calculated with:

int tid = gettid();

Thus,

> +     int cpuid;
> +
> +     cpuid = set_affinity();
> +     if (cpuid == -1) {
> +             printf("Thread %d: Can't set affinity.\n", thread_id);

This...

> +             exit(1);
> +     } else {
> +             if (_dbg_lvl)
> +                     printf("Thread %d: Affinity set to cpu%d\n", thread_id, 
> cpuid);
> +     }

and this... are incorrectly reporting the thread id.  You need to be
using gettid()...

Also, to bring this full circle... what then, is the point of passing
'j' as an argument to:

create_fifo_thread() when creating the concurrent threads... it's no
longer useful, right?

> 
> -     set_affinity(thread_id);
>       pthread_barrier_wait(&mult_start);
>       while (flags[thread_id] != THREAD_DONE) {
>               pthread_mutex_lock(&t->mutex);
> @@ -219,6 +232,7 @@ void main_thread(void)
>       nsec_t start, end;
>       long smin = 0, smax = 0, cmin = 0, cmax = 0, delta = 0;
>       float savg, cavg;
> +     int cpuid;
> 
>       if (    stats_container_init(&sdat, ITERATIONS) ||
>               stats_container_init(&shist, HIST_BUCKETS) ||
> @@ -251,7 +265,15 @@ void main_thread(void)
>       }
>       memset(flags, 0, numcpus);
> 
> -     set_affinity(numcpus-1);
> +     cpuid = set_affinity();
> +     if (cpuid == -1) {
> +             printf("Main thread: Can't set affinity.\n");
> +             exit(1);
> +     } else {
> +             if (_dbg_lvl)
> +                     printf("Main thread: Affinity set to cpu%d\n", cpuid);
> +     }
> +
> 
>       /* run matrix mult operation sequentially */
>       curdat = &sdat;
-- 
-tim


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to