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