示例#1
0
int CentralFreeList::RemoveRange(void **start, void **end, int N) {
  ASSERT(N > 0);
  lock_.Lock();
  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&
      used_slots_ > 0) {
    int slot = --used_slots_;
    ASSERT(slot >= 0);
    TCEntry *entry = &tc_slots_[slot];
    *start = entry->head;
    *end = entry->tail;
    lock_.Unlock();
    return N;
  }

  int result = 0;
  void* head = NULL;
  void* tail = NULL;
  // TODO: Prefetch multiple TCEntries?
  tail = FetchFromSpansSafe();
  if (tail != NULL) {
    SLL_SetNext(tail, NULL);
    head = tail;
    result = 1;
    while (result < N) {
      void *t = FetchFromSpans();
      if (!t) break;
      SLL_Push(&head, t);
      result++;
    }
  }
  lock_.Unlock();
  *start = head;
  *end = tail;
  return result;
}
示例#2
0
    int CCentralCacheMgr::AllocSpan(int clz)
    {
        struct SSpanInfo & spanInfo = m_sSpanList[clz];
        PRINT("clz:%d, %s", clz, spanInfo.c_string());

        size_t nodeSize     = CSizeMap::GetInstance().class_to_size(clz);
        size_t wantPages    = CSizeMap::GetInstance().class_to_pages(clz);
        size_t allocSize    = wantPages << FT_PAGE_BIT;
        size_t allocNodes   = allocSize / nodeSize;

        void * allocAddr = (void *)CPageMgr::GetInstance().AllocPages(wantPages);
        PRINT("alloc new spaninfo, %p", allocAddr);

        struct SSpanNode * spanNode = s_spannode_allocator.AllocNode();
        {
            spanNode->span_addr = allocAddr;
            spanNode->span_size = allocNodes;
            spanNode->free_size = allocNodes;
            RB_NODE_INIT(spanNode->span_node);
            RB_NODE_INIT(spanNode->alloc_node);

            size_t start = (size_t)spanNode->span_addr;
            size_t end = start + allocSize;

            size_t curr = start;
            size_t next = curr + nodeSize;

            while (next < end) {
                SLL_SetNext((void *)curr, (void *)next);
                next += nodeSize;
                curr += nodeSize;
            }
            SLL_SetNext((void *)curr, NULL);
            SLL_SetNext(&spanNode->object_list, spanNode->span_addr);
            PRINT("%s", spanNode->c_string());
        }
        
        InsertSpan(clz, spanNode);
        PRINT("End of allocspan, %s", spanInfo.c_string());
        
        AddAllocPages(wantPages);
        PRINT("Now, allocate out pages:%zd, bytes:%zd", AllocOutPages(), AllocOutBytes());
    }
示例#3
0
    int CCentralCacheMgr::FetchFromSpan(int clz, int N, void ** start, void ** end)
    {
        struct SSpanInfo & spanInfo = m_sSpanList[clz];

        PRINT("clazz:%d, wantsize:%d, %s", clz, N, spanInfo.c_string());

        if (spanInfo.free_object < N) {
            AllocSpan(clz);
        }

        void *s = NULL, *e = NULL;
        int needCount = N;
        bool firstTimeAlloc = true;

        int allocsize = 0;
        SSpanNode * spanNode = NULL;
        
        rb_node * node = rb_first(&spanInfo.alloc_tree);
        while (node != NULL) {
            
            spanNode = AllocTreeGetObject(node);
            allocsize = needCount;
            PRINT("%s", spanNode->c_string());
            PRINT("N:%d, needsize:%d", N, needCount);

            if (spanNode->free_size < allocsize) {
                allocsize = spanNode->free_size;
            }

            SLL_PopRange(&spanNode->object_list, allocsize, &s, &e);
            spanNode->free_size -= allocsize;
            needCount -= allocsize;
            
            PRINT("%s", spanNode->c_string());
            PRINT("N:%d, needsize:%d", N, needCount);

            if (spanNode->free_size == 0) {
                RbRemove(&spanInfo.alloc_tree, spanNode, &CCentralCacheMgr::AllocTreeNode);
            }

            if (firstTimeAlloc) {
                firstTimeAlloc = false;

                *start = s;
                *end = e;
            } else {
                SLL_SetNext(*end, s);
                *end = e;
            }

            if (needCount == 0) {
                break;
            }

            node = rb_first(&spanInfo.alloc_tree);
        }

        int allocNum = N - needCount;
        spanInfo.free_object -= allocNum;
        PRINT("allocnum:%d, wantsize:%d, start:%p, end:%p", allocNum, N, *start, *end);

        return allocNum;
    }