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