コード例 #1
0
ファイル: cpusets.c プロジェクト: agurban/pbspro
/** 
 * @brief
 * 	reclaim_cpusets()
 * 	Given a list of cpusets, attempt to destroy each cpuset named by the list.
 * 	If it can be destroyed, unset the bits corresponding to the cpuset's nodes
 * 	in the mask (if supplied).  This is used to reclaim cpusets that were
 * 	supposed to be deleted, but were in fact "stuck", and placed on stucklist.
 *
 * @param[in] listp - pointer to cpuset list
 * @param[in] maskp - pointer to mask bitfield
 *
 * @return	int
 * @retval	num of cpuset reclaimed		success
 * @retval	0				error
 *
 */
int
reclaim_cpusets(cpusetlist **listp, Bitfield *maskp)
{
	cpusetlist		*set, *next;
	int			count = 0;

	/*
	 * Walk the list of stuck cpusets, attempting to free each one.  Keep
	 * track of the previous and next pointers so the element can be
	 * unlinked and freed.
	 */
	for (set = *listp; set != NULL; set = next) {
		next = set->next;	/* Keep track of next pointer. */

		/* See if this cpuset can be deleted now.  If not, go on. */
		if (destroy_cpuset(set->name)) {
			log_err(0, __func__, "could not destroy cpuset");
			continue;
		}

		/*
		 * Remove the corresponding bits from the given bitmask, if supplied,
		 * and return the nodes to the nodepool.
		 */
		if (maskp != NULL)
			BITFIELD_CLRM(maskp, &(set->nodes));
		BITFIELD_SETM(&nodepool, &(set->nodes));

		/* Log that the cpuset was reclaimed. */
		(void)sprintf(log_buffer, "stuck cpuset %s reclaimed", set->name);
		log_event(PBSEVENT_ERROR, PBS_EVENTCLASS_JOB, LOG_INFO, __func__, log_buffer);

#ifdef	DEBUG
		(void)sprintf(log_buffer, "nodepool now %s", bitfield2hex(&nodepool));
		log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_JOB, LOG_INFO, __func__, log_buffer);
#endif	/* DEBUG */

		/* Now free the storage for the cpusetlist element. */
		if (remove_from_cpusetlist(listp, NULL, set->name, NULL))
			break;

		count ++;		/* Another cpuset reclaimed. */
	}

	/*
	 * Perform a quick sanity check.  If there are no cpusets on the supplied
	 * list, then there should be no bits set in the supplied bitfield.  Log
	 * an error message if this is not the case.
	 */
	if (maskp != NULL && *listp == NULL && !BITFIELD_IS_ZERO(maskp))
		log_err(-1, __func__, "NULL cpusetlist but mask not empty!");

	return (count);
}
コード例 #2
0
ファイル: getqueues.c プロジェクト: Johnlihj/torque
static int
find_nodemasks(Queue *queue, Resources *rsrcs)
  {
  Job *job;
  Bitfield jobs_using;

  BITFIELD_CLRALL(&jobs_using);

  /*
   * Compute the set of nodes that are both physically available and also
   * assigned to this queue.
   */
  BITFIELD_CPY(&queue->availmask, &(queue->queuemask));
  BITFIELD_ANDM(&queue->availmask, &(queue->rsrcs->availmask));

  /*
   * Compute the set of nodes in use by jobs running on the queue (if
   * there are any) and remove those nodes from the available node mask.
   */

  if (queue->running)
    {
    for (job = queue->jobs; job != NULL; job = job->next)
      {
      if (job->state == 'R')
        BITFIELD_SETM(&jobs_using, &(job->nodemask));
      }
    }

  /*
   * Remove the used node bits from the queue's availmask, and add them to
   * the resources' nodes used bits.
   */
  BITFIELD_CLRM(&queue->availmask, &jobs_using);

  BITFIELD_SETM(&rsrcs->nodes_used, &jobs_using);

  return (0);
  }
コード例 #3
0
ファイル: dyn_nodemask.c プロジェクト: AlbertDeFusco/torque
int schd_alloc_nodes(int request, Queue *queue, Bitfield *maskp)
  {
  char   *id = "schd_alloc_nodes";
  Bitfield avail;
  Bitfield mask;
  Bitfield contig;
  int remain;
  int qmsb;
  int qlsb;
  int i, n;
  int count;
  int found;

  /* Make certain the nodecount request can be fulfilled. */

  if (request <= 0 || request > BITFIELD_NUM_ONES(&(queue->availmask)))
    return 0;

  /*
   * Make a copy of the queue's available bit mask to play with, and clear
   * the allocated nodes mask.
   */
  BITFIELD_CPY(&avail, &(queue->availmask));

  BITFIELD_CLRALL(&mask);

  /* How many have been found, and how many remain. */
  found  = 0;

  remain = request;

  while (remain > 0)
    {
    /*
     * Find first and last available bit positions in the
     * queue's available node mask.
     */
    qmsb = BITFIELD_MS_ONE(&avail);
    qlsb = BITFIELD_LS_ONE(&avail);

    /*
     * Starting with the size of the remaining nodes needed to satisfy
     * this request, look for a set of 'n' contiguous bits in the
     * available node mask.  If that is not found, try the next smallest
     * contiguous vector, etc.
     */

    for (n = remain; n > 0; n--)
      {
      /*
       * Create a contiguous bitmask of 'n' bits, starting at the
       * position of the highest bit in the avail mask.
       */
      BITFIELD_CLRALL(&contig);

      for (i = 0; i < n; i++)
        BITFIELD_SETB(&contig, qmsb - i);

      /*
       * Calculate how many times this contiguous bitmask needs to be
       * shifted to the right to cover every set of 'n' bits between
       * the qmsb and qlsb, inclusive.  Count the initial configuration
       * as well (the trailing '+ 1').
       */
      count = (qmsb + 1 - qlsb) - n + 1;

      /*
       * Shift the contiguous mask right one bit at a time, checking
       * if all the bits in the mask are set in the available mask.
       */
      for (i = 0; i < count; i++)
        {

        /* Are all bits in contig also set in the avail mask? */
        if (BITFIELD_TSTALLM(&avail, &contig))
          {
          break;
          }

        BITFIELD_SHIFTR(&contig);
        }

      /*
       * If the contiguous bits are available, add them to the new job
       * nodemask, and remove them from the avail mask.  Adjust the
       * remaining node count, and start the next hunt for the remaining
       * nodes.
       */
      if (i < count)
        {
        BITFIELD_SETM(&mask,  &contig);
        BITFIELD_CLRM(&avail, &contig);

        found  += n;
        remain -= n;

        break; /* for(n) loop */
        }
      }

    /* Check for something going wrong. */
    if (n == 0)
      {
      DBPRT(("%s: couldn't find any contiguous bits (even one!)\n", id));
      break; /* while(remain) loop */
      }
    }

  /*
   * If no bits remain to be allocated, copy the new mask into the provided
   * space, and return the number of bits requested.
   */
  if (!remain && (found == request))
    {
    BITFIELD_CPY(maskp, &mask);
    DBPRT(("%s: mask %s\n", id,
           schd_format_nodemask(&queue->queuemask, maskp)));
    return found;
    }

  return 0;
  }