"Fossies" - the Fresh Open Source Software Archive

Member "openlitespeed-1.6.5/src/shm/addrmap.cpp" (3 Jan 2020, 5635 Bytes) of package /linux/www/openlitespeed-1.6.5.src.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "addrmap.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * 
    3  */
    4 
    5 #include "addrmap.h"
    6 #include <shm/lsshmtypes.h>
    7 #include <shm/lsshmhash.h>
    8 #include <sys/mman.h>
    9 
   10 
   11 int Addr2OffMap::alloc(size_t size)
   12 {
   13     assert(m_table == NULL);
   14     m_table = (AddrOffPair *)malloc(size * sizeof(*m_table));
   15     if (m_table)
   16     {
   17         memset(m_table, 0, size * sizeof(*m_table));
   18         m_tableEnd  = m_table + size;
   19         m_tableSize = size;
   20         return LS_OK;
   21     }
   22     return LS_FAIL;
   23 }    
   24 
   25 
   26 void Addr2OffMap::release()
   27 {
   28     if (m_table)
   29     {
   30         free(m_table);
   31         LS_ZERO_FILL(m_table, m_tableSize);
   32     }
   33 }
   34 
   35 
   36 void Addr2OffMap::swap(Addr2OffMap &rhs)
   37 {
   38     char buf[sizeof(Addr2OffMap)];
   39     memmove(buf, &rhs, sizeof(buf));
   40     memmove(&rhs, this, sizeof(buf));
   41     memmove(this, buf, sizeof(buf));
   42 }
   43 
   44 
   45 int Addr2OffMap::rehash(int new_size)
   46 {
   47     new_size = LsShmHash::roundUp(new_size);
   48 
   49     Addr2OffMap newTable(new_size);
   50     if (newTable.m_table == NULL)
   51         return LS_FAIL;
   52     AddrOffPair *p = m_table;
   53     AddrOffPair *pEnd = m_table + m_tableSize;
   54     while(p < pEnd)
   55     {
   56         if (p->m_ptr)
   57         {
   58             if (newTable.addEx(p) == LS_FAIL)
   59             {
   60                 newTable.release();
   61                 return rehash(new_size * 2);
   62             }
   63         }
   64         p++;
   65     }
   66     swap(newTable);
   67     return LS_OK;
   68 }
   69     
   70     
   71 int Addr2OffMap::add_collide(const AddrOffPair *p, AddrOffPair *pInfo)
   72 {
   73     AddrOffPair *pEnd = pInfo + 3;
   74     if (pEnd >= m_tableEnd)
   75         pEnd = m_table + (pEnd - m_tableEnd);
   76     while(pInfo != pEnd)
   77     {
   78         assert(((size_t)pInfo->m_ptr) >> LARGE_PAGE_BITS
   79                 != ((size_t)p->m_ptr) >> LARGE_PAGE_BITS);
   80         if (pInfo == m_tableEnd - 1)
   81         {
   82             pInfo = m_table;
   83         }
   84         else
   85         {
   86             ++pInfo;
   87         }
   88         if (pInfo->m_ptr == NULL)
   89         {
   90             memmove(pInfo, p, sizeof(*p));
   91             return LS_OK;
   92         }
   93     }
   94     return LS_FAIL;
   95 }
   96 
   97 
   98 const AddrOffPair *Addr2OffMap::lookup_collid(const char *p, AddrOffPair *pInfo) const
   99 {
  100     AddrOffPair *pEnd = pInfo + 3;
  101     if (pEnd >= m_tableEnd)
  102         pEnd = m_table + (pEnd - m_tableEnd);
  103     while(pInfo != pEnd)
  104     {
  105         if (pInfo == m_tableEnd - 1)
  106         {
  107             pInfo = m_table;
  108         }
  109         else
  110         {
  111             ++pInfo;
  112         }
  113         if (((size_t)pInfo->m_ptr >> LARGE_PAGE_BITS) == 
  114             ((size_t)p) >> LARGE_PAGE_BITS)
  115         {
  116             return pInfo;
  117         }
  118     }
  119     return NULL;
  120 }
  121     
  122 
  123 
  124 AddrMap::~AddrMap()
  125 {
  126 
  127 }
  128 
  129 
  130 int AddrMap::addLargePage(AddrOffPair info, size_t size)
  131 {
  132     assert((info.m_offset & LARGE_PAGE_MASK) == 0);
  133     assert((size   & LARGE_PAGE_MASK) == 0);
  134     int page = info.m_offset >> LARGE_PAGE_BITS;
  135     assert(page == m_off2ptrTable.size());
  136     char * end = info.m_ptr + size;
  137     while(info.m_ptr < end)
  138     {
  139         if (m_off2ptrTable.push_back(info.m_ptr) == -1)
  140             return LS_FAIL;
  141         m_ptr2offTable.add(&info);
  142         info.m_ptr += LARGE_PAGE_SIZE;
  143         info.m_offset += LARGE_PAGE_SIZE;
  144     }
  145     return LS_OK;
  146 }
  147 
  148 
  149 int AddrMap::mapAddrSpace(size_t total)
  150 {
  151     int needed = total - getMaxOffset();
  152     if (needed <= 0)
  153         return LS_OK;
  154     AddrOffPair pair;
  155     size_t bytes = (needed + LARGE_PAGE_MASK ) & ~LARGE_PAGE_MASK;
  156     pair.m_ptr = (char *) mmap(NULL, bytes + LARGE_PAGE_SIZE, PROT_NONE,
  157                                MAP_ANON|MAP_SHARED, -1, 0);
  158     if (!pair.m_ptr)
  159         return LS_FAIL;
  160     if (((unsigned long)pair.m_ptr & LARGE_PAGE_MASK) == 0)
  161         bytes += LARGE_PAGE_SIZE;
  162     else
  163     {
  164         char *pRelease = pair.m_ptr;
  165         size_t size; 
  166         pair.m_ptr = (char *)(((unsigned long)pair.m_ptr & ~LARGE_PAGE_MASK) 
  167                             + LARGE_PAGE_SIZE);
  168         size = pair.m_ptr - pRelease;
  169         munmap(pRelease, size);
  170         pRelease = pair.m_ptr + bytes;
  171         munmap(pRelease, LARGE_PAGE_SIZE - size);
  172     }
  173     pair.m_offset = getMaxOffset();
  174     if (addLargePage(pair, bytes) == LS_FAIL)
  175     {
  176         munmap(pair.m_ptr, bytes);
  177         return LS_FAIL;
  178     }
  179     return LS_OK;
  180     
  181 }
  182 
  183 
  184 int AddrMap::remap(int fd, size_t start_offset, size_t new_size)
  185 {
  186     if (mapAddrSpace(new_size) == LS_FAIL)
  187         return LS_FAIL;
  188     start_offset = start_offset & ~(LSSHM_PAGESIZE -1);
  189     while(start_offset < new_size)
  190     {
  191         size_t block_end = (start_offset + LARGE_PAGE_SIZE) & ~LARGE_PAGE_MASK;
  192         if (block_end > new_size)
  193             block_end = new_size;
  194         char * ptr = offset2ptr(start_offset);
  195         ptr = (char *)mmap(ptr, block_end - start_offset, PROT_READ | PROT_WRITE,
  196                             MAP_FIXED | MAP_SHARED, fd, start_offset);
  197         if (ptr == MAP_FAILED)
  198             return LS_FAIL;
  199         start_offset = block_end;
  200     }
  201     return LS_OK;
  202     
  203 }
  204 
  205 static int unmap_large_page(void *pPage)
  206 {
  207     munmap(pPage, LARGE_PAGE_SIZE);
  208     return 0;
  209 }
  210 
  211 
  212 void AddrMap::unmap()
  213 {
  214     m_off2ptrTable.for_each(m_off2ptrTable.begin(), m_off2ptrTable.end(), 
  215                             unmap_large_page);
  216     m_off2ptrTable.clear();
  217     m_ptr2offTable.clear();
  218 }
  219 
  220 
  221 size_t AddrMap::getAvailAddrSpace( size_t offset, size_t required_size)
  222 {
  223     size_t avail = 0;
  224     int page = offset >> LARGE_PAGE_BITS;
  225     avail = LARGE_PAGE_SIZE - (offset & LARGE_PAGE_MASK);
  226     while(avail < required_size && page < m_off2ptrTable.size() - 1)
  227     {
  228         if (required_size > LARGE_PAGE_SIZE 
  229             && m_off2ptrTable[page + 1] - m_off2ptrTable[page] == LARGE_PAGE_SIZE)
  230         {
  231             avail += LARGE_PAGE_SIZE;
  232             ++page;
  233         }
  234         else
  235             break;
  236     }
  237     return avail;    
  238 }
  239