1 /*
2 * Copyright (C) 2020 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 /*
18 * Note: This is not a real pthreads implementation. This is file provides
19 * symbols to allow a single-threaded system to pretend to be pthreads
20 * supporting, but sans the ability to actually spawn new threads for
21 * compatibility with codebases which cannot be configured to not use
22 * e.g. mutexes.
23 *
24 * If we add actual threads, we should switch to musl's implementation,
25 * not fix this one.
26 */
27
28 #include <sys/types.h>
29 #include <time.h>
30
31 /*
32 * For musl, Trusty's libc, pthread_t is a unsigned long. There is only one
33 * thread, so we provide the constant thread ID of USER_ASPACE_BASE - 1
34 * Do not select 0 or -1, as both are used for "invalid thread" by some
35 * applications.
36 *
37 * This value was selected to allow attempts to dereference this to be
38 * guaranteed to fault.
39 */
pthread_self(void)40 pthread_t pthread_self(void) {
41 return (pthread_t)(USER_ASPACE_BASE - 1);
42 }
43
44 /* Perform a normal equality test to support invalid threads as input */
pthread_equal(pthread_t t1,pthread_t t2)45 int pthread_equal(pthread_t t1, pthread_t t2) {
46 return (int)(t1 == t2);
47 }
48
49 /*
50 * There is only one thread, so treat locks as no-ops.
51 * We could be slightly more correct by treating them as bools and spinning
52 * forever, but since we have no way of re-entering the program to unlock
53 * the lock, this could not be used for any useful purpose.
54 */
pthread_mutex_init(pthread_mutex_t * mutex,const pthread_mutexattr_t * attr)55 int pthread_mutex_init(pthread_mutex_t* mutex,
56 const pthread_mutexattr_t* attr) {
57 return 0;
58 }
59
pthread_mutex_destroy(pthread_mutex_t * mutex)60 int pthread_mutex_destroy(pthread_mutex_t* mutex) {
61 return 0;
62 }
63
pthread_mutex_lock(pthread_mutex_t * mutex)64 int pthread_mutex_lock(pthread_mutex_t* mutex) {
65 return 0;
66 }
67
pthread_mutex_trylock(pthread_mutex_t * mutex)68 int pthread_mutex_trylock(pthread_mutex_t* mutex) {
69 return 0;
70 }
71
pthread_mutex_unlock(pthread_mutex_t * mutex)72 int pthread_mutex_unlock(pthread_mutex_t* mutex) {
73 return 0;
74 }
75
pthread_cond_wait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex)76 int pthread_cond_wait(pthread_cond_t* restrict cond,
77 pthread_mutex_t* restrict mutex) {
78 return 0;
79 }
80
pthread_cond_timedwait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex,const struct timespec * restrict abstime)81 int pthread_cond_timedwait(pthread_cond_t* restrict cond,
82 pthread_mutex_t* restrict mutex,
83 const struct timespec* restrict abstime) {
84 return 0;
85 }
86
pthread_cond_broadcast(pthread_cond_t * cond)87 int pthread_cond_broadcast(pthread_cond_t* cond) {
88 return 0;
89 }
90
pthread_cond_signal(pthread_cond_t * cond)91 int pthread_cond_signal(pthread_cond_t* cond) {
92 return 0;
93 }
94
pthread_atfork(void (* prepare)(void),void (* parent)(void),void (* child)(void))95 int pthread_atfork(void (*prepare)(void),
96 void (*parent)(void),
97 void (*child)(void)) {
98 return 0;
99 }
100