static bool get_free_sockets(const char* topology, const int topology_length,
               int** sockets, int* sockets_size)
{
   /* temporary counter */
   int i, j;
   /* this number of sockets we discovered already */
   int socket_number  = 0;

   (*sockets) = NULL;
   (*sockets_size) = 0;

   /* go through the whole topology and check if there are some sockets
      completely unbound */
   for (i = 0; i < topology_length && topology[i] != '\0'; i++) {

      if (topology[i] == 'S' || topology[i] == 's') {

         /* we're on a new socket: check all cores (and skip threads) after it */
         bool free = true;

         /* check the topology till the next socket (or end) */
         for (j = i + 1; j < topology_length && topology[j] != '\0'; j++) {
            if (topology[j] == 'c') {
               /* this socket has at least one core in use */
               free = false;
            } else if (topology[j] == 'S' || topology[j] == 's') {
               break;
            }
         }

         /* fast forward */
         i = j;

         /* check if this socket had a core in use */
         if (free == true) {
            /* this socket can be used completely */
            (*sockets) = sge_realloc(*sockets, ((*sockets_size)+1)*sizeof(int), 1);
            (*sockets)[(*sockets_size)] = socket_number;
            (*sockets_size)++;
         }

         /* increment the number of sockets we discovered so far */
         socket_number++;

      } /* end if this is a socket */

   }

   /* it was successful when we found at least one socket not used by any job */
   if ((*sockets_size) > 0) {
      /* we also have to free the list outside afterwards */
      return true;
   } else {
      return false;
   }
}
Beispiel #2
0
static void
sge_dstring_allocate(dstring *sb, size_t request)
{  
   /* always request multiples of REALLOC_CHUNK */
   size_t chunks = request / REALLOC_CHUNK + 1;
   request = chunks * REALLOC_CHUNK;

   /* set new size */
   sb->size += request;

   /* allocate memory */
   if (sb->s != NULL) {
      sb->s = sge_realloc(sb->s, sb->size * sizeof(char), 1);
   } else {
      sb->s = malloc(sb->size * sizeof(char));
      sb->s[0] = '\0';
   }
}
Beispiel #3
0
/****** uti/io/sge_stream2string() ********************************************
*  NAME
*     sge_stream2string() -- Read string from stream
*
*  SYNOPSIS
*     char* sge_stream2string(FILE *fp, int *len)
*
*  FUNCTION
*     Read string from stream
*
*  INPUTS
*     FILE *fp - file descriptor
*     int *len - number of bytes read
*
*  RESULT
*     char* - pointer to malloced string buffer
*
*  SEE ALSO
*     uti/io/sge_file2string()
*     uti/io/sge_string2file()
*
*  NOTES
*     MT-NOTE: sge_stream2string() is MT safe
******************************************************************************/ 
char *sge_stream2string(FILE *fp, int *len)
{
   char *str;
   int filled = 0;
   int malloced_len, i;
 
   DENTER(TOP_LAYER, "sge_stream2string");
 
   if (!(str = malloc(FILE_CHUNK))) {
      DEXIT;
      return NULL;
   }
   malloced_len = FILE_CHUNK;
 
   /* malloced_len-filled-1 cause we reserve space for \0 termination */
   while ((i = fread(&str[filled], 1, malloced_len-filled-1, fp)) > 0) {
      filled += i;
      if (malloced_len == filled+1) {
         str = sge_realloc(str, malloced_len + FILE_CHUNK, 0);
         if (str == NULL) {
            DEXIT;
            return NULL;
         }
         malloced_len += FILE_CHUNK;
      }
 
      if (feof(fp)) {
         DPRINTF(("got EOF\n"));
         break;
      }
   }
   str[filled] = '\0';  /* NULL termination */
   *len = filled;
 
   DEXIT;
   return str;
}
int kupdate(int avenrun[3])
{
   kstat_t *ks;
   kid_t nkcid;
   int i;
   int changed = 0;
   static int ncpu = 0;
   static kid_t kcid = 0;
   kstat_named_t *kn;

   /*
   * 0. kstat_open
   */
   if (!kc) {
      kc = kstat_open();
      if (!kc) {
         perror("kstat_open ");
         return -1;
      }
      changed = 1;
      kcid = kc->kc_chain_id;
   }


   /* keep doing it until no more changes */
   kcid_changed:

   /*
   * 1.  kstat_chain_update
   */
   nkcid = kstat_chain_update(kc);
   if (nkcid) {
      /* UPDKCID will abort if nkcid is -1, so no need to check */
      changed = 1;
      kcid = nkcid;
   }
   UPDKCID(nkcid,0);

   ks = kstat_lookup(kc, "unix", 0, "system_misc");
   if (kstat_read(kc, ks, 0) == -1) {
      perror("kstat_read");
      return -1;
   }

#if 0
   /* load average */
   kn = kstat_data_lookup(ks, "avenrun_1min");
   if (kn)
      avenrun[0] = kn->value.ui32;
   kn = kstat_data_lookup(ks, "avenrun_5min");
   if (kn)
      avenrun[1] = kn->value.ui32;
   kn = kstat_data_lookup(ks, "avenrun_15min");
   if (kn)
      avenrun[2] = kn->value.ui32;

   /* nproc */
   kn = kstat_data_lookup(ks, "nproc");
   if (kn) {
      nproc = kn->value.ui32;
#ifdef NO_NPROC
      if (nproc > maxprocs)
      reallocproc(2 * nproc);
#endif
   }
#endif

   if (changed) {
      int ncpus = 0;

      /*
      * 2. get data addresses
      */

      ncpu = 0;

      kn = kstat_data_lookup(ks, "ncpus");
      if (kn && kn->value.ui32 > ncpus) {
         ncpus = kn->value.ui32;
         cpu_ks = (kstat_t **)sge_realloc(cpu_ks, ncpus * sizeof(kstat_t *), 1);
         cpu_stat = (cpu_stat_t *)sge_realloc(cpu_stat, ncpus * sizeof(cpu_stat_t), 1);
      }

      for (ks = kc->kc_chain; ks; ks = ks->ks_next) {
         if (strncmp(ks->ks_name, "cpu_stat", 8) == 0) {
            nkcid = kstat_read(kc, ks, NULL);
            /* if kcid changed, pointer might be invalid */
            UPDKCID(nkcid, kcid);

            cpu_ks[ncpu] = ks;
            ncpu++;
            if (ncpu >= ncpus) {
               break;
            }
         }
      }
      /* note that ncpu could be less than ncpus, but that's okay */
      changed = 0;
   }


   /*
   * 3. get data
   */

   for (i = 0; i < ncpu; i++) {
      nkcid = kstat_read(kc, cpu_ks[i], &cpu_stat[i]);
      /* if kcid changed, pointer might be invalid */
      UPDKCID(nkcid, kcid);
   }

   /* return the number of cpus found */
   return(ncpu);
}
Beispiel #5
0
static const char*
sge_dstring_vsprintf_copy_append(dstring *sb,
                                 sge_dstring_copy_append_f function,
                                 const char *format,
                                 va_list ap)
{
   const char *ret = NULL;

   if (sb != NULL && format != NULL && function != NULL) {
      char static_buffer[BUFSIZ];
      int vsnprintf_ret;
      va_list ap_copy;

      va_copy(ap_copy, ap);
      vsnprintf_ret = vsnprintf(static_buffer, BUFSIZ, format, ap_copy);
      va_end(ap_copy);

      /*
       * We have to handle three cases here:
       *    1) If the function returns -1 then vsprintf does not follow 
       *       the C99 standard. We have to increase the buffer until
       *       all parameters fit into the buffer.
       *    2) The function returns a value >BUFSIZE. This indicates
       *       that the function follows the C99 standard. 
       *       vsnprintf_ret is the number of characters which would
       *       have been written to the buffer if it where large enough.
       *       We have to create a buffer of this size.
       *    3) If the return value is >0 and <BUFSIZ than vsprintf
       *       was successfull. We do not need a dyn_buffer.
       */
      if (vsnprintf_ret == -1) {
         size_t dyn_size = 2 * BUFSIZ;
         char *dyn_buffer = sge_malloc(dyn_size);

         while (vsnprintf_ret == -1 && dyn_buffer != NULL) {
            va_copy(ap_copy, ap);
            vsnprintf_ret = vsnprintf(dyn_buffer, dyn_size, format, ap_copy);
            va_end(ap_copy);

            if (vsnprintf_ret == -1) {
               dyn_size *= 2;
               dyn_buffer = sge_realloc(dyn_buffer, dyn_size, 0);
            }
         }
         if (dyn_buffer != NULL) {
            ret = function(sb, dyn_buffer);
            sge_free(&dyn_buffer);
         } else {
            /* error: no memory */
            ret = NULL;
         }
      } else if (vsnprintf_ret > BUFSIZ) {
         char *dyn_buffer = NULL;

         dyn_buffer = (char *)malloc((vsnprintf_ret + 1) * sizeof(char));
         if (dyn_buffer != NULL) {
            va_copy(ap_copy, ap);
            vsnprintf(dyn_buffer, vsnprintf_ret + 1, format, ap_copy);
            va_end(ap_copy);

            ret = function(sb, dyn_buffer);
            sge_free(&dyn_buffer);
         } else {
            /* error: no memory */
            ret = NULL;
         }
      } else {
         ret = function(sb, static_buffer);
      }
   }
   return ret;
}
Beispiel #6
0
/****** uti/io/sge_bin2string() ***********************************************
*  NAME
*     sge_bin2string() -- Put binary stream into a string 
*
*  SYNOPSIS
*     char* sge_bin2string(FILE *fp, int size) 
*
*  FUNCTION
*     Read a binary steam from given file descriptor 'fp' and
*     write it into (dynamically) malloced buffer as "ASCII" format.
*  
*     "ASCII" format means:
*           '\0' is written as '\\' '\0' 
*           '\\' is written as '\\' '\\'
*           End of buffer is written as '\0'
*
*  INPUTS
*     FILE *fp - file descriptor 
*     int size - size of the buffer used within this function 
*
*  RESULT
*     char* - malloced buffer
*
*  SEE ALSO
*     uti/io/sge_string2bin()
*
*  NOTES
*     MT-NOTE: sge_bin2string() is MT safe
******************************************************************************/
char *sge_bin2string(FILE *fp, int size) 
{
   int i, fd;
   char inbuf[BUFFER], outbuf[2*BUFFER];
   char *inp, *outp;
   char *dstbuf;
   int len,             /* length of current tmp buffer */
       dstbuflen,       /* total length of destination buffer */
       chunksize,       /* chunks for realloc */
       lastpos,         /* last position in destination buffer */
       error;
   
   if ((fd = fileno(fp)) == -1)
      return NULL;

   chunksize = 20480;
   
   if (size <= 0)       /* no idea about buffer, malloc in chunks */
      size = chunksize;

   dstbuf = (char *) malloc(size+1);
   dstbuflen = size;
   lastpos = 0;

   error = false;

   while (!error) {
      i = read(fd, inbuf, BUFFER);
      if (i > 0) {
         inp = inbuf;
         outp = outbuf;
         while (inp < &inbuf[i]) {
            if (*inp == '\\') {
               *outp++ = '\\';
               *outp++ = '\\';
            }
            else if (*inp == '\0') {
               *outp++ = '\\';
               *outp++ = '0';
            }
            else
               *outp++ = *inp;
            inp++;
         }


         len = outp - outbuf;

         if (lastpos + len > dstbuflen) {
            if ((dstbuf = sge_realloc(dstbuf, lastpos + len + chunksize, 0)) == NULL) {
               error = true;
               break;
            }   
            dstbuflen = lastpos + len + chunksize;

         }
         
         memcpy(&dstbuf[lastpos], outbuf, len);
         lastpos += len;

      }
      else if (i == 0) {
         break;
      }
      else {
         if (errno != EINTR) {
            error=true;
            break;
         }
      }
   }

   if (error) {
      sge_free(&dstbuf);
      return NULL;
   }
   else {
      if ((dstbuf = sge_realloc(dstbuf, lastpos + 1, 0)) == NULL) {
         return NULL;
      }
      dstbuf[lastpos] = '\0';
      return dstbuf;
   }
}
static int account_cores_on_socket(char** topology, const int topology_length,
               const int socket_number, const int cores_needed, int** list_of_sockets,
               int* list_of_sockets_size, int** list_of_cores, int* list_of_cores_size)
{
   int i;
   /* socket number we are at the moment */
   int current_socket_number = -1;
   /* return value */
   int retval;

   /* try to use as many cores as possible on a specific socket
      but not more */

   /* jump to the specific socket given by the "socket_number" */
   for (i = 0; i < topology_length && (*topology)[i] != '\0'; i++) {
      if ((*topology)[i] == 'S' || (*topology)[i] == 's') {
         current_socket_number++;
         if (current_socket_number >= socket_number) {
            /* we are at the beginning of socket #"socket_number" */
            break;
         }
      }
   }

   /* check if we reached that socket or if it was out of range */
   if (socket_number != current_socket_number) {

      /* early abort because we couldn't find the socket we were
         searching for */
      retval = 0;

   } else {

      /* we are at a 'S' or 's' and going to the next 'S' or 's'
         and collecting all cores in between */

      int core_counter = 0;   /* current core number on the socket */
      i++;                    /* just forward to the first core on the socket */
      retval  = 0;            /* need to initialize the number of cores we found */

      for (; i < topology_length && (*topology)[i] != '\0'; i++) {
         if ((*topology)[i] == 'C') {
            /* take this core */
            (*list_of_sockets_size)++;    /* the socket list is growing */
            (*list_of_cores_size)++;      /* the core list is growing */
            *list_of_sockets = sge_realloc(*list_of_sockets, (*list_of_sockets_size)
                                           * sizeof(int), 1);
            *list_of_cores   = sge_realloc(*list_of_cores, (*list_of_cores_size)
                                           * sizeof(int), 1);
            /* store the logical <socket,core> tuple inside the lists */
            (*list_of_sockets)[(*list_of_sockets_size) - 1]   = socket_number;
            (*list_of_cores)[(*list_of_cores_size) - 1]       = core_counter;
            /* increase the number of cores we've collected so far */
            retval++;
            /* move forward to the next core */
            core_counter++;
            /* do accounting */
            (*topology)[i] = 'c';
            /* thread binding: accounting is done here */
            account_all_threads_after_core(topology, i);

         } else if ((*topology)[i] == 'c') {
            /* this core is already in use */
            /* move forward to the next core */
            core_counter++;
         } else if ((*topology)[i] == 'S' || (*topology)[i] == 's') {
            /* we are already on another socket which we can not use */
            break;
         }

         if (retval >= cores_needed) {
            /* we have already collected as many cores we need to collect */
            break;
         }
      }

   }

   return retval;
}