Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: sandbox/linux/seccomp/allocator.cc

Issue 3225010: Pull seccomp-sandbox in via DEPS rather than using an in-tree copy... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp/allocator.h ('k') | sandbox/linux/seccomp/clone.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // The allocator is very simplistic. It requests memory pages directly from
6 // the system. Each page starts with a header describing the allocation. This
7 // makes sure that we can return the memory to the system when it is
8 // deallocated.
9 // For allocations that are smaller than a single page, we try to squeeze
10 // multiple of them into the same page.
11 // We expect to use this allocator for a moderate number of small allocations.
12 // In most cases, it will only need to ever make a single request to the
13 // operating system for the lifetime of the STL container object.
14 // We don't worry about memory fragmentation as the allocator is expected to
15 // be short-lived.
16
17 #include <stdint.h>
18 #include <sys/mman.h>
19
20 #include "allocator.h"
21 #include "linux_syscall_support.h"
22
23 namespace playground {
24
25 class SysCalls {
26 public:
27 #define SYS_CPLUSPLUS
28 #define SYS_ERRNO my_errno
29 #define SYS_INLINE inline
30 #define SYS_PREFIX -1
31 #undef SYS_LINUX_SYSCALL_SUPPORT_H
32 #include "linux_syscall_support.h"
33 SysCalls() : my_errno(0) { }
34 int my_errno;
35 };
36 #ifdef __NR_mmap2
37 #define MMAP mmap2
38 #define __NR_MMAP __NR_mmap2
39 #else
40 #define MMAP mmap
41 #define __NR_MMAP __NR_mmap
42 #endif
43
44 // We only ever keep track of the very last partial page that was used for
45 // allocations. This approach simplifies the code a lot. It can theoretically
46 // lead to more memory fragmentation, but for our use case that is unlikely
47 // to happen.
48 struct Header {
49 // The total amount of memory allocated for this chunk of memory. Typically,
50 // this would be a single page.
51 size_t total_len;
52
53 // "used" keeps track of the number of bytes currently allocated in this
54 // page. Note that as elements are freed from this page, "used" is updated
55 // allowing us to track when the page is free. However, these holes in the
56 // page are never re-used, so "tail" is the only way to find out how much
57 // free space remains and when we need to request another chunk of memory
58 // from the system.
59 size_t used;
60 void *tail;
61 };
62 static Header* last_alloc;
63
64 void* SystemAllocatorHelper::sys_allocate(size_t size) {
65 // Number of bytes that need to be allocated
66 if (size + 3 < size) {
67 return NULL;
68 }
69 size_t len = (size + 3) & ~3;
70
71 if (last_alloc) {
72 // Remaining space in the last chunk of memory allocated from system
73 size_t remainder = last_alloc->total_len -
74 (reinterpret_cast<char *>(last_alloc->tail) -
75 reinterpret_cast<char *>(last_alloc));
76
77 if (remainder >= len) {
78 void* ret = last_alloc->tail;
79 last_alloc->tail = reinterpret_cast<char *>(last_alloc->tail) + len;
80 last_alloc->used += len;
81 return ret;
82 }
83 }
84
85 SysCalls sys;
86 if (sizeof(Header) + len + 4095 < len) {
87 return NULL;
88 }
89 size_t total_len = (sizeof(Header) + len + 4095) & ~4095;
90 Header* mem = reinterpret_cast<Header *>(
91 sys.MMAP(NULL, total_len, PROT_READ|PROT_WRITE,
92 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0));
93 if (mem == MAP_FAILED) {
94 return NULL;
95 }
96
97 // If we were only asked to allocate a single page, then we will use any
98 // remaining space for other small allocations.
99 if (total_len - sizeof(Header) - len >= 4) {
100 last_alloc = mem;
101 }
102 mem->total_len = total_len;
103 mem->used = len;
104 char* ret = reinterpret_cast<char *>(mem) + sizeof(Header);
105 mem->tail = ret + len;
106
107 return ret;
108 }
109
110 void SystemAllocatorHelper::sys_deallocate(void* p, size_t size) {
111 // Number of bytes in this allocation
112 if (size + 3 < size) {
113 return;
114 }
115 size_t len = (size + 3) & ~3;
116
117 // All allocations (small and large) have starting addresses in the
118 // first page that was allocated from the system. This page starts with
119 // a header that keeps track of how many bytes are currently used. The
120 // header can be found by truncating the last few bits of the address.
121 Header* header = reinterpret_cast<Header *>(
122 reinterpret_cast<uintptr_t>(p) & ~4095);
123 header->used -= len;
124
125 // After the last allocation has been freed, return the page(s) to the
126 // system
127 if (!header->used) {
128 SysCalls sys;
129 sys.munmap(header, header->total_len);
130 if (last_alloc == header) {
131 last_alloc = NULL;
132 }
133 }
134 }
135
136 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/allocator.h ('k') | sandbox/linux/seccomp/clone.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698