Home | History | Annotate | Download | only in libhwbinder
      1 /*
      2  * Copyright (C) 2005 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 #define LOG_TAG "hw-ProcessState"
     18 
     19 #include <hwbinder/ProcessState.h>
     20 
     21 #include <cutils/atomic.h>
     22 #include <hwbinder/BpHwBinder.h>
     23 #include <hwbinder/IPCThreadState.h>
     24 #include <hwbinder/binder_kernel.h>
     25 #include <utils/Log.h>
     26 #include <utils/String8.h>
     27 #include <utils/threads.h>
     28 
     29 #include <private/binder/binder_module.h>
     30 #include <hwbinder/Static.h>
     31 
     32 #include <errno.h>
     33 #include <fcntl.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <unistd.h>
     37 #include <sys/ioctl.h>
     38 #include <sys/mman.h>
     39 #include <sys/stat.h>
     40 #include <sys/types.h>
     41 
     42 #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
     43 #define DEFAULT_MAX_BINDER_THREADS 0
     44 
     45 // -------------------------------------------------------------------------
     46 
     47 namespace android {
     48 namespace hardware {
     49 
     50 class PoolThread : public Thread
     51 {
     52 public:
     53     explicit PoolThread(bool isMain)
     54         : mIsMain(isMain)
     55     {
     56     }
     57 
     58 protected:
     59     virtual bool threadLoop()
     60     {
     61         IPCThreadState::self()->joinThreadPool(mIsMain);
     62         return false;
     63     }
     64 
     65     const bool mIsMain;
     66 };
     67 
     68 sp<ProcessState> ProcessState::self()
     69 {
     70     Mutex::Autolock _l(gProcessMutex);
     71     if (gProcess != NULL) {
     72         return gProcess;
     73     }
     74     gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE);
     75     return gProcess;
     76 }
     77 
     78 sp<ProcessState> ProcessState::selfOrNull() {
     79     Mutex::Autolock _l(gProcessMutex);
     80     return gProcess;
     81 }
     82 
     83 sp<ProcessState> ProcessState::initWithMmapSize(size_t mmap_size) {
     84     Mutex::Autolock _l(gProcessMutex);
     85     if (gProcess != NULL) {
     86         LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(),
     87                 "ProcessState already initialized with a different mmap size.");
     88         return gProcess;
     89     }
     90 
     91     gProcess = new ProcessState(mmap_size);
     92     return gProcess;
     93 }
     94 
     95 void ProcessState::setContextObject(const sp<IBinder>& object)
     96 {
     97     setContextObject(object, String16("default"));
     98 }
     99 
    100 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    101 {
    102     return getStrongProxyForHandle(0);
    103 }
    104 
    105 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
    106 {
    107     AutoMutex _l(mLock);
    108     mContexts.add(name, object);
    109 }
    110 
    111 sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
    112 {
    113     mLock.lock();
    114     sp<IBinder> object(
    115         mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
    116     mLock.unlock();
    117 
    118     //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
    119 
    120     if (object != NULL) return object;
    121 
    122     // Don't attempt to retrieve contexts if we manage them
    123     if (mManagesContexts) {
    124         ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
    125             String8(name).string());
    126         return NULL;
    127     }
    128 
    129     IPCThreadState* ipc = IPCThreadState::self();
    130     {
    131         Parcel data, reply;
    132         // no interface token on this magic transaction
    133         data.writeString16(name);
    134         data.writeStrongBinder(caller);
    135         status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
    136         if (result == NO_ERROR) {
    137             object = reply.readStrongBinder();
    138         }
    139     }
    140 
    141     ipc->flushCommands();
    142 
    143     if (object != NULL) setContextObject(object, name);
    144     return object;
    145 }
    146 
    147 void ProcessState::startThreadPool()
    148 {
    149     AutoMutex _l(mLock);
    150     if (!mThreadPoolStarted) {
    151         mThreadPoolStarted = true;
    152         if (mSpawnThreadOnStart) {
    153             spawnPooledThread(true);
    154         }
    155     }
    156 }
    157 
    158 bool ProcessState::isContextManager(void) const
    159 {
    160     return mManagesContexts;
    161 }
    162 
    163 bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
    164 {
    165     if (!mManagesContexts) {
    166         AutoMutex _l(mLock);
    167         mBinderContextCheckFunc = checkFunc;
    168         mBinderContextUserData = userData;
    169 
    170         int dummy = 0;
    171         status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
    172         if (result == 0) {
    173             mManagesContexts = true;
    174         } else if (result == -1) {
    175             mBinderContextCheckFunc = NULL;
    176             mBinderContextUserData = NULL;
    177             ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
    178         }
    179     }
    180     return mManagesContexts;
    181 }
    182 
    183 // Get references to userspace objects held by the kernel binder driver
    184 // Writes up to count elements into buf, and returns the total number
    185 // of references the kernel has, which may be larger than count.
    186 // buf may be NULL if count is 0.  The pointers returned by this method
    187 // should only be used for debugging and not dereferenced, they may
    188 // already be invalid.
    189 ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) {
    190     binder_node_debug_info info = {};
    191 
    192     uintptr_t* end = buf ? buf + buf_count : NULL;
    193     size_t count = 0;
    194 
    195     do {
    196         status_t result = ioctl(mDriverFD, BINDER_GET_NODE_DEBUG_INFO, &info);
    197         if (result < 0) {
    198             return -1;
    199         }
    200         if (info.ptr != 0) {
    201             if (buf && buf < end) *buf++ = info.ptr;
    202             count++;
    203             if (buf && buf < end) *buf++ = info.cookie;
    204             count++;
    205         }
    206     } while (info.ptr != 0);
    207 
    208     return count;
    209 }
    210 
    211 size_t ProcessState::getMmapSize() {
    212     return mMmapSize;
    213 }
    214 
    215 ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
    216 {
    217     const size_t N=mHandleToObject.size();
    218     if (N <= (size_t)handle) {
    219         handle_entry e;
    220         e.binder = NULL;
    221         e.refs = NULL;
    222         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
    223         if (err < NO_ERROR) return NULL;
    224     }
    225     return &mHandleToObject.editItemAt(handle);
    226 }
    227 
    228 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    229 {
    230     sp<IBinder> result;
    231 
    232     AutoMutex _l(mLock);
    233 
    234     handle_entry* e = lookupHandleLocked(handle);
    235 
    236     if (e != NULL) {
    237         // We need to create a new BpHwBinder if there isn't currently one, OR we
    238         // are unable to acquire a weak reference on this current one.  See comment
    239         // in getWeakProxyForHandle() for more info about this.
    240         IBinder* b = e->binder;
    241         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    242             b = new BpHwBinder(handle);
    243             e->binder = b;
    244             if (b) e->refs = b->getWeakRefs();
    245             result = b;
    246         } else {
    247             // This little bit of nastyness is to allow us to add a primary
    248             // reference to the remote proxy when this team doesn't have one
    249             // but another team is sending the handle to us.
    250             result.force_set(b);
    251             e->refs->decWeak(this);
    252         }
    253     }
    254 
    255     return result;
    256 }
    257 
    258 wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
    259 {
    260     wp<IBinder> result;
    261 
    262     AutoMutex _l(mLock);
    263 
    264     handle_entry* e = lookupHandleLocked(handle);
    265 
    266     if (e != NULL) {
    267         // We need to create a new BpHwBinder if there isn't currently one, OR we
    268         // are unable to acquire a weak reference on this current one.  The
    269         // attemptIncWeak() is safe because we know the BpHwBinder destructor will always
    270         // call expungeHandle(), which acquires the same lock we are holding now.
    271         // We need to do this because there is a race condition between someone
    272         // releasing a reference on this BpHwBinder, and a new reference on its handle
    273         // arriving from the driver.
    274         IBinder* b = e->binder;
    275         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    276             b = new BpHwBinder(handle);
    277             result = b;
    278             e->binder = b;
    279             if (b) e->refs = b->getWeakRefs();
    280         } else {
    281             result = b;
    282             e->refs->decWeak(this);
    283         }
    284     }
    285 
    286     return result;
    287 }
    288 
    289 void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
    290 {
    291     AutoMutex _l(mLock);
    292 
    293     handle_entry* e = lookupHandleLocked(handle);
    294 
    295     // This handle may have already been replaced with a new BpHwBinder
    296     // (if someone failed the AttemptIncWeak() above); we don't want
    297     // to overwrite it.
    298     if (e && e->binder == binder) e->binder = NULL;
    299 }
    300 
    301 String8 ProcessState::makeBinderThreadName() {
    302     int32_t s = android_atomic_add(1, &mThreadPoolSeq);
    303     pid_t pid = getpid();
    304     String8 name;
    305     name.appendFormat("HwBinder:%d_%X", pid, s);
    306     return name;
    307 }
    308 
    309 void ProcessState::spawnPooledThread(bool isMain)
    310 {
    311     if (mThreadPoolStarted) {
    312         String8 name = makeBinderThreadName();
    313         ALOGV("Spawning new pooled thread, name=%s\n", name.string());
    314         sp<Thread> t = new PoolThread(isMain);
    315         t->run(name.string());
    316     }
    317 }
    318 
    319 status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
    320     LOG_ALWAYS_FATAL_IF(maxThreads < 1, "Binder threadpool must have a minimum of one thread.");
    321     status_t result = NO_ERROR;
    322     // the BINDER_SET_MAX_THREADS ioctl really tells the kernel how many threads
    323     // it's allowed to spawn, *in addition* to any threads we may have already
    324     // spawned locally. If 'callerJoinsPool' is true, it means that the caller
    325     // will join the threadpool, and so the kernel needs to create one less thread.
    326     // If 'callerJoinsPool' is false, we will still spawn a thread locally, and we should
    327     // also tell the kernel to create one less thread than what was requested here.
    328     size_t kernelMaxThreads = maxThreads - 1;
    329     if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) != -1) {
    330         AutoMutex _l(mLock);
    331         mMaxThreads = maxThreads;
    332         mSpawnThreadOnStart = !callerJoinsPool;
    333     } else {
    334         result = -errno;
    335         ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
    336     }
    337     return result;
    338 }
    339 
    340 size_t ProcessState::getMaxThreads() {
    341     return mMaxThreads;
    342 }
    343 
    344 void ProcessState::giveThreadPoolName() {
    345     androidSetThreadName( makeBinderThreadName().string() );
    346 }
    347 
    348 static int open_driver()
    349 {
    350     int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
    351     if (fd >= 0) {
    352         int vers = 0;
    353         status_t result = ioctl(fd, BINDER_VERSION, &vers);
    354         if (result == -1) {
    355             ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
    356             close(fd);
    357             fd = -1;
    358         }
    359         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
    360           ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
    361             close(fd);
    362             fd = -1;
    363         }
    364         size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    365         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
    366         if (result == -1) {
    367             ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
    368         }
    369     } else {
    370         ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno));
    371     }
    372     return fd;
    373 }
    374 
    375 ProcessState::ProcessState(size_t mmap_size)
    376     : mDriverFD(open_driver())
    377     , mVMStart(MAP_FAILED)
    378     , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    379     , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    380     , mExecutingThreadsCount(0)
    381     , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    382     , mStarvationStartTimeMs(0)
    383     , mManagesContexts(false)
    384     , mBinderContextCheckFunc(NULL)
    385     , mBinderContextUserData(NULL)
    386     , mThreadPoolStarted(false)
    387     , mSpawnThreadOnStart(true)
    388     , mThreadPoolSeq(1)
    389     , mMmapSize(mmap_size)
    390 {
    391     if (mDriverFD >= 0) {
    392         // mmap the binder, providing a chunk of virtual address space to receive transactions.
    393         mVMStart = mmap(0, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    394         if (mVMStart == MAP_FAILED) {
    395             // *sigh*
    396             ALOGE("Using /dev/hwbinder failed: unable to mmap transaction memory.\n");
    397             close(mDriverFD);
    398             mDriverFD = -1;
    399         }
    400     }
    401     else {
    402         ALOGE("Binder driver could not be opened.  Terminating.");
    403     }
    404 }
    405 
    406 ProcessState::~ProcessState()
    407 {
    408     if (mDriverFD >= 0) {
    409         if (mVMStart != MAP_FAILED) {
    410             munmap(mVMStart, mMmapSize);
    411         }
    412         close(mDriverFD);
    413     }
    414     mDriverFD = -1;
    415 }
    416 
    417 }; // namespace hardware
    418 }; // namespace android
    419