Home | History | Annotate | Download | only in bionic
      1 /*
      2  * Copyright (C) 2014 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 <malloc.h>
     18 #include <sys/param.h>
     19 #include <unistd.h>
     20 
     21 #include "jemalloc.h"
     22 #include "private/bionic_macros.h"
     23 
     24 void* je_pvalloc(size_t bytes) {
     25   size_t pagesize = getpagesize();
     26   size_t size = __BIONIC_ALIGN(bytes, pagesize);
     27   if (size < bytes) {
     28     return NULL;
     29   }
     30   return je_memalign(pagesize, size);
     31 }
     32 
     33 #ifdef je_memalign
     34 #undef je_memalign
     35 #endif
     36 
     37 // The man page for memalign says it fails if boundary is not a power of 2,
     38 // but this is not true. Both glibc and dlmalloc round up to the next power
     39 // of 2, so we'll do the same.
     40 void* je_memalign_round_up_boundary(size_t boundary, size_t size) {
     41   if (boundary != 0) {
     42     if (!powerof2(boundary)) {
     43       boundary = BIONIC_ROUND_UP_POWER_OF_2(boundary);
     44     }
     45   } else {
     46     boundary = 1;
     47   }
     48   return je_memalign(boundary, size);
     49 }
     50 
     51 int je_mallopt(int param, int value) {
     52   // The only parameter we currently understand is M_DECAY_TIME.
     53   if (param == M_DECAY_TIME) {
     54     // Only support setting the value to 1 or 0.
     55     ssize_t decay_time;
     56     if (value) {
     57       decay_time = 1;
     58     } else {
     59       decay_time = 0;
     60     }
     61     // First get the total number of arenas.
     62     unsigned narenas;
     63     size_t sz = sizeof(unsigned);
     64     if (je_mallctl("arenas.narenas", &narenas, &sz, nullptr, 0) != 0) {
     65       return 0;
     66     }
     67 
     68     // Set the decay time for any arenas that will be created in the future.
     69     if (je_mallctl("arenas.decay_time", nullptr, nullptr, &decay_time, sizeof(decay_time)) != 0) {
     70       return 0;
     71     }
     72 
     73     // Change the decay on the already existing arenas.
     74     char buffer[100];
     75     for (unsigned i = 0; i < narenas; i++) {
     76       snprintf(buffer, sizeof(buffer), "arena.%d.decay_time", i);
     77       if (je_mallctl(buffer, nullptr, nullptr, &decay_time, sizeof(decay_time)) != 0) {
     78         break;
     79       }
     80     }
     81     return 1;
     82   }
     83   return 0;
     84 }
     85