src/Platform-Posix.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jul 29 02:17:11 2012 -0700 (2012-07-29)
changeset 124 0d7ac9ba25c2
parent 92 e3974e7360e9
child 251 ca99a81745fe
permissions -rw-r--r--
Allow void to compare to void.
dvander@28
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@28
     2
 *
dvander@28
     3
 * Copyright (C) 2012 David Anderson
dvander@28
     4
 *
dvander@28
     5
 * This file is part of JITCraft.
dvander@28
     6
 *
dvander@28
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@28
     8
 * the terms of the GNU General Public License as published by the Free
dvander@28
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@28
    10
 * any later version.
dvander@28
    11
 * 
dvander@28
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@28
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@28
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@28
    15
 *
dvander@28
    16
 * You should have received a copy of the GNU General Public License along with
dvander@28
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@28
    18
 */
dvander@28
    19
#include <sys/mman.h>
dvander@28
    20
#include "Platform.h"
dvander@28
    21
danderson@91
    22
using namespace ke;
dvander@28
    23
dvander@28
    24
static inline int
dvander@28
    25
ToProtBits(OS::Protection prot)
dvander@28
    26
{
dvander@28
    27
    switch (prot) {
dvander@28
    28
      case OS::Prot_ReadWrite:
dvander@28
    29
        return PROT_READ | PROT_WRITE;
dvander@28
    30
      case OS::Prot_ReadWriteExecute:
dvander@28
    31
        return PROT_READ | PROT_WRITE | PROT_EXEC;
dvander@28
    32
      default:
dvander@28
    33
        assert(prot == OS::Prot_ReadExecute);
dvander@28
    34
        return PROT_READ | PROT_EXEC;
dvander@28
    35
    }
dvander@28
    36
}
dvander@28
    37
dvander@28
    38
Address
dvander@28
    39
OS::MapMemory(size_t amount, MapMode mode, Protection prot_)
dvander@28
    40
{
dvander@28
    41
    int prot = ToProtBits(prot_);
dvander@28
    42
    void *addr = mmap(NULL, amount, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
dvander@28
    43
    if (addr == MAP_FAILED)
dvander@28
    44
        return NULL;
dvander@28
    45
dvander@28
    46
    return Address(addr);
dvander@28
    47
}
dvander@28
    48
dvander@28
    49
bool
dvander@28
    50
OS::CommitMemory(Address address, size_t amount, Protection prot_)
dvander@28
    51
{
dvander@28
    52
    return true;
dvander@28
    53
}
dvander@28
    54
dvander@28
    55
void
dvander@28
    56
OS::UnmapMemory(Address address, size_t size)
dvander@28
    57
{
dvander@28
    58
    munmap(address, size);
dvander@28
    59
}
dvander@28
    60
dvander@28
    61
OS::AlignableMapping
dvander@28
    62
OS::MapAlignedMemory(size_t amount, size_t alignment, MapMode mode)
dvander@28
    63
{
dvander@28
    64
    assert(amount >= alignment);
dvander@28
    65
    assert(IsPowerOfTwo(alignment));
dvander@28
    66
dvander@28
    67
    if (alignment == kPageAlignment) {
dvander@28
    68
        Address address = MapMemory(amount, mode, Prot_ReadWrite);
dvander@28
    69
        if (!address)
dvander@28
    70
            return AlignableMapping();
dvander@28
    71
        return AlignableMapping(address, alignment, amount);
dvander@28
    72
    }
dvander@28
    73
dvander@28
    74
    size_t requested = Min(amount * 2, amount + 2 * alignment);
danderson@92
    75
    Address address = MapMemory(requested, mode, Prot_ReadWrite);
dvander@28
    76
    if (!address)
dvander@28
    77
        return AlignableMapping();
dvander@28
    78
dvander@28
    79
    size_t begin = 0;
dvander@28
    80
    Address aligned = AlignedBase(address, alignment);
dvander@28
    81
    if (!IsAligned(address, alignment)) {
dvander@28
    82
        // Shave off the first part of the unaligned region.
dvander@28
    83
        aligned += alignment;
dvander@28
    84
        begin = size_t(aligned - address);
dvander@28
    85
        UnmapAlignedMemory(address, begin);
dvander@28
    86
    }
dvander@28
    87
dvander@28
    88
    if (requested - begin > amount) {
dvander@28
    89
        // Shave off the last part of the unaligned region.
danderson@92
    90
        UnmapAlignedMemory(aligned + amount, requested - amount - begin);
dvander@28
    91
    }
dvander@28
    92
dvander@28
    93
    return AlignableMapping(aligned, alignment, amount);
dvander@28
    94
}
dvander@28
    95
dvander@28
    96
void
dvander@28
    97
OS::UnmapAlignedMemory(Address address, size_t size)
dvander@28
    98
{
dvander@28
    99
    OS::UnmapMemory(address, size);
dvander@28
   100
}
dvander@28
   101