blob: 5b92c8003060d03483b8178bdc68dcda1442f31b [file] [log] [blame]
[email protected]5ace0a82012-07-25 21:26:121// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]fbd31eb2011-03-01 00:19:022// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "courgette/memory_allocator.h"
6
7#include <map>
8
thestigc9e38a22014-09-13 01:02:119#include "base/files/file_util.h"
[email protected]68c986e2013-06-11 13:26:2510#include "base/strings/stringprintf.h"
[email protected]fbd31eb2011-03-01 00:19:0211
[email protected]31662202013-03-23 19:10:5412#if defined(OS_WIN)
[email protected]fbd31eb2011-03-01 00:19:0213
[email protected]578d5dae2014-02-21 16:07:5214namespace {
[email protected]fbd31eb2011-03-01 00:19:0215
[email protected]578d5dae2014-02-21 16:07:5216// The file is created in the %TEMP% folder.
17// NOTE: Since the file will be used as backing for a memory allocation,
18// it will never be so big that size_t cannot represent its size.
19base::File CreateTempFile() {
[email protected]9e275712013-02-10 19:20:1420 base::FilePath path;
[email protected]03d9afc02013-12-03 17:55:5221 if (!base::CreateTemporaryFile(&path))
[email protected]578d5dae2014-02-21 16:07:5222 return base::File();
[email protected]43a9e242011-04-06 17:42:4523
[email protected]578d5dae2014-02-21 16:07:5224 int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
25 base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE |
26 base::File::FLAG_TEMPORARY;
27 return base::File(path, flags);
[email protected]fbd31eb2011-03-01 00:19:0228}
29
[email protected]578d5dae2014-02-21 16:07:5230} // namespace
[email protected]fbd31eb2011-03-01 00:19:0231
[email protected]578d5dae2014-02-21 16:07:5232namespace courgette {
[email protected]fbd31eb2011-03-01 00:19:0233
34// FileMapping
35
36FileMapping::FileMapping() : mapping_(NULL), view_(NULL) {
37}
38
39FileMapping::~FileMapping() {
40 Close();
41}
42
[email protected]43a9e242011-04-06 17:42:4543bool FileMapping::InitializeView(size_t size) {
[email protected]6c131952011-03-03 23:39:3244 DCHECK(view_ == NULL);
45 DCHECK(mapping_ != NULL);
46 view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
[email protected]43a9e242011-04-06 17:42:4547 if (!view_) {
48 Close();
49 return false;
50 }
51 return true;
[email protected]6c131952011-03-03 23:39:3252}
53
[email protected]43a9e242011-04-06 17:42:4554bool FileMapping::Create(HANDLE file, size_t size) {
[email protected]fbd31eb2011-03-01 00:19:0255 DCHECK(file != INVALID_HANDLE_VALUE);
56 DCHECK(!valid());
57 mapping_ = ::CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 0, NULL);
[email protected]6c131952011-03-03 23:39:3258 if (!mapping_)
[email protected]43a9e242011-04-06 17:42:4559 return false;
[email protected]fbd31eb2011-03-01 00:19:0260
[email protected]43a9e242011-04-06 17:42:4561 return InitializeView(size);
[email protected]fbd31eb2011-03-01 00:19:0262}
63
64void FileMapping::Close() {
65 if (view_)
66 ::UnmapViewOfFile(view_);
67 if (mapping_)
68 ::CloseHandle(mapping_);
69 mapping_ = NULL;
70 view_ = NULL;
71}
72
73bool FileMapping::valid() const {
74 return view_ != NULL;
75}
76
77void* FileMapping::view() const {
78 return view_;
79}
80
81// TempMapping
82
83TempMapping::TempMapping() {
84}
85
86TempMapping::~TempMapping() {
87}
88
[email protected]43a9e242011-04-06 17:42:4589bool TempMapping::Initialize(size_t size) {
[email protected]578d5dae2014-02-21 16:07:5290 file_ = CreateTempFile();
91 if (!file_.IsValid())
92 return false;
93
[email protected]fbd31eb2011-03-01 00:19:0294 // TODO(tommi): The assumption here is that the alignment of pointers (this)
95 // is as strict or stricter than the alignment of the element type. This is
96 // not always true, e.g. __m128 has 16-byte alignment.
97 size += sizeof(this);
[email protected]578d5dae2014-02-21 16:07:5298 if (!file_.SetLength(size) ||
99 !mapping_.Create(file_.GetPlatformFile(), size)) {
[email protected]43a9e242011-04-06 17:42:45100 file_.Close();
101 return false;
102 }
[email protected]fbd31eb2011-03-01 00:19:02103
[email protected]6c131952011-03-03 23:39:32104 TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
105 write[0] = this;
[email protected]43a9e242011-04-06 17:42:45106
107 return true;
[email protected]fbd31eb2011-03-01 00:19:02108}
109
110void* TempMapping::memory() const {
111 uint8* mem = reinterpret_cast<uint8*>(mapping_.view());
[email protected]5ace0a82012-07-25 21:26:12112 // The 'this' pointer is written at the start of mapping_.view(), so
113 // go past it. (See Initialize()).
[email protected]fbd31eb2011-03-01 00:19:02114 if (mem)
115 mem += sizeof(this);
116 DCHECK(mem);
117 return mem;
118}
119
[email protected]43a9e242011-04-06 17:42:45120bool TempMapping::valid() const {
121 return mapping_.valid();
122}
123
[email protected]fbd31eb2011-03-01 00:19:02124// static
125TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
126 TempMapping* ret = NULL;
127 if (mem) {
128 ret = reinterpret_cast<TempMapping**>(mem)[-1];
129 }
130 DCHECK(ret);
131 return ret;
132}
133
134} // namespace courgette
135
136#endif // OS_WIN