Exemplo n.º 1
0
HgfsReq *
HgfsGetNewReq(HgfsSuperInfo *sip)       // IN: Superinfo containing free list
{
   HgfsReq *newReq;

   DEBUG(VM_DEBUG_REQUEST, "HgfsGetNewReq().\n");

   ASSERT(sip);

   /*
    * Here we atomically get the next free request from the free list and set
    * that request's state to ALLOCATED.
    */
   mutex_enter(&sip->reqFreeMutex);

   /* Wait for a request structure if there aren't any free */
   while (HgfsListIsEmpty(&sip->reqFreeList)) {
      /*
       * If the list is empty, we wait on the condition variable which is
       * unconditionally signaled whenever a request is destroyed.
       */
      if (cv_wait_sig(&sip->reqFreeCondVar, &sip->reqFreeMutex) == 0) {
         /*
          * We were interrupted while waiting for a request, so we must return
          * NULL and release the mutex.
          */
         newReq = NULL;
         goto out;
      }
   }

   newReq = HGFS_FREE_REQ_LIST_HEAD(sip);

   HgfsDebugPrintReq("HgfsGetNewReq", newReq);

   /* Failure of these indicates error in program's logic */
   ASSERT(newReq && newReq->state == HGFS_REQ_UNUSED);

   /* Take request off the free list and indicate it has been ALLOCATED */
   DblLnkLst_Unlink1(&newReq->listNode);
   newReq->state = HGFS_REQ_ALLOCATED;

   /* Clear packet of request before allocating to clients. */
   bzero(newReq->packet, sizeof newReq->packet);

   DEBUG(VM_DEBUG_LIST, "Dequeued from free list: %s", newReq->packet);
   HgfsDebugPrintReqList(&sip->reqFreeList);

out:
   mutex_exit(&sip->reqFreeMutex);

   DEBUG(VM_DEBUG_REQUEST, "HgfsGetNewReq() done.\n");
   return newReq;
}
static void
HgfsServerPolicyDestroyShares(DblLnkLst_Links *head) // IN
{
   ASSERT(head);

   while (head->next != head) {
      HgfsSharedFolder *share;

      share = DblLnkLst_Container(head->next, HgfsSharedFolder, links);
      ASSERT(share);
      DblLnkLst_Unlink1(&share->links);
      HgfsServerPolicyDestroyShare(share);
   }
}
Exemplo n.º 3
0
static void
BalloonChunkDestroyEmpty(Balloon *b,            // IN/OUT
                         BalloonChunk *chunk,   // IN/OUT
                         int isLargePage)       // IN
{
   if (chunk->nEntries == 0) {
      /* destroy empty chunk */
      DblLnkLst_Unlink1(&chunk->node);
      BalloonChunk_Destroy(chunk);

      /* update stats */
      b->pages[isLargePage].nChunks--;
   }
}
Exemplo n.º 4
0
/* Test code entry point */
int
main(int argc,    // IN
     char **argv) // IN
{
   member *c1;
   member *c2;
   member *c3;
   member *c4;

   DblLnkLst_Links h;
   member *a1;
   member *a2;
   member *a3;

   printf("Circular list: there is no origin\n");

   /* Create the 1st member */
   c1 = make_member(1);
   /* Special case: there is no list to merge with, initially */

   /* Add the 2nd member _after_ the 1st one */
   c2 = make_member(2);
   DblLnkLst_Link(&c1->l, &c2->l);

   /* Add the 3rd member _after_ the 2nd one */
   c3 = make_member(3);
   DblLnkLst_Link(&c1->l, &c3->l);

   /* Add the 4th member _before_ the 3rd one */
   c4 = make_member(4);
   DblLnkLst_Link(&c3->l, &c4->l);

   printf("See it from this member...\n");
   dump_circular(c1);
   printf("...Or from this one\n");
   dump_circular(c4);

   printf("\n");
   printf("Anchored (linear) list: it has a beginning and an end\n");

   /* Create the 'head' of the list */
   DblLnkLst_Init(&h);

   /* Add the 1st member at the _end_ */
   a1 = make_member(5);
   DblLnkLst_LinkLast(&h, &a1->l);

   /* Add the 2nd member at the _beginning_ */
   a2 = make_member(6);
   DblLnkLst_LinkFirst(&h, &a2->l);

   /* Add the 3rd member _before_ the 1st one */
   a3 = make_member(7);
   DblLnkLst_Link(&a1->l, &a3->l);

   dump_anchored(&h);

   printf("\n");
   printf("Merge both lists: the result is an anchored list\n");

   DblLnkLst_Link(&h, &c4->l);

   dump_anchored(&h);

   printf("\n");
   printf("Remove a member\n");

   DblLnkLst_Unlink1(&c3->l);

   dump_anchored(&h);

   printf("\n");
   printf("Split the result in two lists: an anchored one and a circular "
          "one\n");
   DblLnkLst_Unlink(&h, &a1->l);

   dump_anchored(&h);
   dump_circular(a1);

   return 0;
}
Exemplo n.º 5
0
static void
BalloonDeflateInt(Balloon *b,       // IN/OUT
                  uint32 target,    // IN
                  int isLargePages) // IN
{
   int                  status = BALLOON_SUCCESS;
   uint32               nPages, deallocations = 0;
   BalloonChunk         *chunk = NULL;
   BalloonChunkList     *chunkList = &b->pages[isLargePages];

   if (chunkList->nChunks == 0) {
      return;
   }

   nPages = 0;
   while (chunkList->nChunks > 0 && b->nPages > target
          && nPages < b->nPages - target) {
      PageHandle lockedHandle;

      if (chunk == NULL) {
         /*
          * The chunk should never be empty. If it is, then there is a
          * deviation between the guest balloon size, and tracked
          * pages...
          */
         ASSERT(DblLnkLst_IsLinked(&chunkList->chunks));
         chunk = DblLnkLst_Container(chunkList->chunks.next, BalloonChunk,
                                     node);
      }

      lockedHandle = chunk->entries[--chunk->nEntries];
      if (!chunk->nEntries) {
         DblLnkLst_Unlink1(&chunk->node);
         /*
          * Do not free the chunk, we may need it if the UNLOCK cmd fails
          */
         b->fallbackChunk = chunk;

         chunkList->nChunks--;
         chunk = NULL;
      }

      deallocations++;
      b->balloonOps->addPage(b, nPages++, lockedHandle);
      if (nPages == b->batchMaxEntries) {
         status = b->balloonOps->unlock(b, nPages, isLargePages, &target);
         nPages = 0;

         if (status != BALLOON_SUCCESS) {
            break;
         }
      }

      if (deallocations >= b->rateFree) {
         /* We released enough pages, let's take a break. */
         break;
      }
   }

   if (nPages) {
      b->balloonOps->unlock(b, nPages, isLargePages, NULL);
   }

   if (BALLOON_RATE_ADAPT) {
      if (status == BALLOON_SUCCESS) {
         /* slowly increase rate if no errors */
         b->rateFree = MIN(b->rateFree + BALLOON_RATE_FREE_INC,
                           BALLOON_RATE_FREE_MAX);
      } else {
         /* quickly decrease rate if error */
         b->rateFree = MAX(b->rateFree / 2, BALLOON_RATE_FREE_MIN);
      }
   }
}