Back to index

glibc  2.9
pthread_attr_setaffinity.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <assert.h>
00021 #include <errno.h>
00022 #include <limits.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <pthreadP.h>
00026 #include <shlib-compat.h>
00027 
00028 
00029 /* Defined in pthread_setaffinity.c.  */
00030 extern size_t __kernel_cpumask_size attribute_hidden;
00031 extern int __determine_cpumask_size (pid_t tid);
00032 
00033 
00034 int
00035 __pthread_attr_setaffinity_new (pthread_attr_t *attr, size_t cpusetsize,
00036                             const cpu_set_t *cpuset)
00037 {
00038   struct pthread_attr *iattr;
00039 
00040   assert (sizeof (*attr) >= sizeof (struct pthread_attr));
00041   iattr = (struct pthread_attr *) attr;
00042 
00043   if (cpuset == NULL || cpusetsize == 0)
00044     {
00045       free (iattr->cpuset);
00046       iattr->cpuset = NULL;
00047       iattr->cpusetsize = 0;
00048     }
00049   else
00050     {
00051       if (__kernel_cpumask_size == 0)
00052        {
00053          int res = __determine_cpumask_size (THREAD_SELF->tid);
00054          if (res != 0)
00055            /* Some serious problem.  */
00056            return res;
00057        }
00058 
00059       /* Check whether the new bitmask has any bit set beyond the
00060         last one the kernel accepts.  */
00061       for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
00062        if (((char *) cpuset)[cnt] != '\0')
00063          /* Found a nonzero byte.  This means the user request cannot be
00064             fulfilled.  */
00065          return EINVAL;
00066 
00067       if (iattr->cpusetsize != cpusetsize)
00068        {
00069          void *newp = (cpu_set_t *) realloc (iattr->cpuset, cpusetsize);
00070          if (newp == NULL)
00071            return ENOMEM;
00072 
00073          iattr->cpuset = newp;
00074          iattr->cpusetsize = cpusetsize;
00075        }
00076 
00077       memcpy (iattr->cpuset, cpuset, cpusetsize);
00078     }
00079 
00080   return 0;
00081 }
00082 versioned_symbol (libpthread, __pthread_attr_setaffinity_new,
00083                 pthread_attr_setaffinity_np, GLIBC_2_3_4);
00084 
00085 
00086 #if SHLIB_COMPAT (libpthread, GLIBC_2_3_3, GLIBC_2_3_4)
00087 int
00088 __pthread_attr_setaffinity_old (pthread_attr_t *attr, cpu_set_t *cpuset)
00089 {
00090   /* The old interface by default assumed a 1024 processor bitmap.  */
00091   return __pthread_attr_setaffinity_new (attr, 128, cpuset);
00092 }
00093 compat_symbol (libpthread, __pthread_attr_setaffinity_old,
00094               pthread_attr_setaffinity_np, GLIBC_2_3_3);
00095 #endif