• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "util.h"
18 
19 #include <err.h>
20 #include <math.h>
21 #include <sched.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <wchar.h>
25 
26 #include <cstdlib>
27 
28 // This function returns a pointer less than 2 * alignment + or_mask bytes into the array.
GetAlignedMemory(char * orig_ptr,size_t alignment,size_t or_mask)29 char* GetAlignedMemory(char* orig_ptr, size_t alignment, size_t or_mask) {
30   if ((alignment & (alignment - 1)) != 0) {
31     errx(1, "warning: alignment passed into GetAlignedMemory is not a power of two.");
32   }
33   if (or_mask > alignment) {
34     errx(1, "warning: or_mask passed into GetAlignedMemory is too high.");
35   }
36   uintptr_t ptr = reinterpret_cast<uintptr_t>(orig_ptr);
37   if (alignment > 0) {
38     // When setting the alignment, set it to exactly the alignment chosen.
39     // The pointer returned will be guaranteed not to be aligned to anything
40     // more than that.
41     ptr += alignment - (ptr & (alignment - 1));
42     ptr |= alignment | or_mask;
43   }
44 
45   return reinterpret_cast<char*>(ptr);
46 }
47 
GetAlignedPtr(std::vector<char> * buf,size_t alignment,size_t nbytes)48 char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) {
49   buf->resize(nbytes + 3 * alignment);
50   return GetAlignedMemory(buf->data(), alignment, 0);
51 }
52 
GetAlignedPtr(std::vector<wchar_t> * buf,size_t alignment,size_t nchars)53 wchar_t* GetAlignedPtr(std::vector<wchar_t>* buf, size_t alignment, size_t nchars) {
54   buf->resize(nchars + ceil((3 * alignment) / sizeof(wchar_t)));
55   return reinterpret_cast<wchar_t*>(GetAlignedMemory(reinterpret_cast<char*>(buf->data()),
56                                                      alignment, 0));
57 }
58 
GetAlignedPtrFilled(std::vector<char> * buf,size_t alignment,size_t nbytes,char fill_byte)59 char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) {
60   char* buf_aligned = GetAlignedPtr(buf, alignment, nbytes);
61   memset(buf_aligned, fill_byte, nbytes);
62   return buf_aligned;
63 }
64 
65 #if defined(__APPLE__)
66 
67 // Darwin doesn't support this, so do nothing.
LockToCPU(int)68 bool LockToCPU(int) {
69   return false;
70 }
71 
72 #else
73 
LockToCPU(int cpu_to_lock)74 bool LockToCPU(int cpu_to_lock) {
75   cpu_set_t cpuset;
76 
77   CPU_ZERO(&cpuset);
78   CPU_SET(cpu_to_lock, &cpuset);
79   if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
80     if (errno == EINVAL) {
81       printf("Invalid cpu %d\n", cpu_to_lock);
82     } else {
83       perror("sched_setaffinity failed");
84     }
85     return false;
86   }
87 
88   return true;
89 }
90 
91 #endif
92