1e41f4b71Sopenharmony_ci# Standard Library
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciThe OpenHarmony kernel uses the musl libc library that supports the Portable Operating System Interface (POSIX). You can develop components and applications working on the kernel based on the POSIX.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Standard Library API Framework
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci**Figure 1** POSIX framework
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci![](figures/posix-framework.png "posix-framework")
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciThe musl libc library supports POSIX standards. The OpenHarmony kernel adapts the related system call APIs to implement external functions.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciFor details about the APIs supported by the standard library, see the API document of the C library, which also covers the differences between the standard library and the POSIX standard library.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci### Development Example
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci####  Example Description
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ciIn this example, the main thread creates THREAD_NUM child threads. Once a child thread is started, it enters the standby state. After the main thread successfully wakes up all child threads, they continue to execute until the lifecycle ends. The main thread uses the **pthread_join** method to wait until all child threads are executed.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci####  Sample Code
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ciThe sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ExamplePosix** function is called in **TestTaskEntry**.
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ciThe sample code is as follows: 
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci```
32e41f4b71Sopenharmony_ci#include <stdio.h>
33e41f4b71Sopenharmony_ci#include <unistd.h>
34e41f4b71Sopenharmony_ci#include <pthread.h>
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci#define THREAD_NUM 3
37e41f4b71Sopenharmony_ciint g_startNum = 0; /* Number of threads to start */
38e41f4b71Sopenharmony_ciint g_wakenNum = 0; /* Number of threads to wake up */
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_cistruct testdata {
41e41f4b71Sopenharmony_ci    pthread_mutex_t mutex;
42e41f4b71Sopenharmony_ci    pthread_cond_t cond;
43e41f4b71Sopenharmony_ci} g_td;
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci/* Entry function of the child thread */
46e41f4b71Sopenharmony_cistatic VOID *ChildThreadFunc(VOID *arg)
47e41f4b71Sopenharmony_ci{
48e41f4b71Sopenharmony_ci    int rc;
49e41f4b71Sopenharmony_ci    pthread_t self = pthread_self();
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci    /* Acquire a mutex. */
52e41f4b71Sopenharmony_ci    rc = pthread_mutex_lock(&g_td.mutex);
53e41f4b71Sopenharmony_ci    if (rc != 0) {
54e41f4b71Sopenharmony_ci        dprintf("ERROR:take mutex lock failed, error code is %d!\n", rc);
55e41f4b71Sopenharmony_ci        goto EXIT;
56e41f4b71Sopenharmony_ci    }
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci    /* The value of g_startNum is increased by 1. The value indicates the number of child threads that have acquired a mutex. */
59e41f4b71Sopenharmony_ci    g_startNum++;
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci     /* Wait for the cond variable. */
62e41f4b71Sopenharmony_ci    rc = pthread_cond_wait(&g_td.cond, &g_td.mutex);
63e41f4b71Sopenharmony_ci    if (rc != 0) {
64e41f4b71Sopenharmony_ci        dprintf("ERROR: pthread condition wait failed, error code is %d!\n", rc);
65e41f4b71Sopenharmony_ci        (void)pthread_mutex_unlock(&g_td.mutex);
66e41f4b71Sopenharmony_ci        goto EXIT;
67e41f4b71Sopenharmony_ci    }
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci    /* Attempt to acquire a mutex, which is failed in normal cases. */
70e41f4b71Sopenharmony_ci    rc = pthread_mutex_trylock(&g_td.mutex);
71e41f4b71Sopenharmony_ci    if (rc == 0) {
72e41f4b71Sopenharmony_ci        dprintf("ERROR: mutex gets an abnormal lock!\n");
73e41f4b71Sopenharmony_ci        goto EXIT;
74e41f4b71Sopenharmony_ci    }
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci    /* The value of g_wakenNum is increased by 1. The value indicates the number of child threads that have been woken up by the cond variable. */
77e41f4b71Sopenharmony_ci    g_wakenNum++;
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci    /* Release a mutex. */
80e41f4b71Sopenharmony_ci    rc = pthread_mutex_unlock(&g_td.mutex);
81e41f4b71Sopenharmony_ci    if (rc != 0) {
82e41f4b71Sopenharmony_ci        dprintf("ERROR: mutex release failed, error code is %d!\n", rc);
83e41f4b71Sopenharmony_ci        goto EXIT;
84e41f4b71Sopenharmony_ci    }
85e41f4b71Sopenharmony_ciEXIT:
86e41f4b71Sopenharmony_ci    return NULL;
87e41f4b71Sopenharmony_ci}
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_cistatic int ExamplePosix(VOID)
90e41f4b71Sopenharmony_ci{
91e41f4b71Sopenharmony_ci    int i, rc;
92e41f4b71Sopenharmony_ci    pthread_t thread[THREAD_NUM];
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci    /* Initialize the mutex. */
95e41f4b71Sopenharmony_ci    rc = pthread_mutex_init(&g_td.mutex, NULL);
96e41f4b71Sopenharmony_ci    if (rc != 0) {
97e41f4b71Sopenharmony_ci        dprintf("ERROR: mutex init failed, error code is %d!\n", rc);
98e41f4b71Sopenharmony_ci        goto ERROROUT;
99e41f4b71Sopenharmony_ci    }
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci    /* Initialize the cond variable. */
102e41f4b71Sopenharmony_ci    rc = pthread_cond_init(&g_td.cond, NULL);
103e41f4b71Sopenharmony_ci    if (rc != 0) {
104e41f4b71Sopenharmony_ci        dprintf("ERROR: pthread condition init failed, error code is %d!\n", rc);
105e41f4b71Sopenharmony_ci        goto ERROROUT;
106e41f4b71Sopenharmony_ci    }
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ci    /* Create child threads in batches. */
109e41f4b71Sopenharmony_ci    for (i = 0; i < THREAD_NUM; i++) {
110e41f4b71Sopenharmony_ci        rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL);
111e41f4b71Sopenharmony_ci        if (rc != 0) {
112e41f4b71Sopenharmony_ci            dprintf("ERROR: pthread create failed, error code is %d!\n", rc);
113e41f4b71Sopenharmony_ci            goto ERROROUT;
114e41f4b71Sopenharmony_ci        }
115e41f4b71Sopenharmony_ci    }
116e41f4b71Sopenharmony_ci    dprintf("pthread_create ok\n");
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci    /* Wait until all child threads obtain a mutex. */
119e41f4b71Sopenharmony_ci    while (g_startNum < THREAD_NUM) {
120e41f4b71Sopenharmony_ci        usleep(100);
121e41f4b71Sopenharmony_ci    }
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci    /* Acquire a mutex and block all threads using pthread_cond_wait. */
124e41f4b71Sopenharmony_ci    rc = pthread_mutex_lock(&g_td.mutex);
125e41f4b71Sopenharmony_ci    if (rc != 0) {
126e41f4b71Sopenharmony_ci        dprintf("ERROR: mutex lock failed, error code is %d\n", rc);
127e41f4b71Sopenharmony_ci        goto ERROROUT;
128e41f4b71Sopenharmony_ci    }
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci    /* Release the mutex. */
131e41f4b71Sopenharmony_ci    rc = pthread_mutex_unlock(&g_td.mutex);
132e41f4b71Sopenharmony_ci    if (rc != 0) {
133e41f4b71Sopenharmony_ci        dprintf("ERROR: mutex unlock failed, error code is %d!\n", rc);
134e41f4b71Sopenharmony_ci        goto ERROROUT;
135e41f4b71Sopenharmony_ci    }
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci    for (int j = 0; j < THREAD_NUM; j++) {
138e41f4b71Sopenharmony_ci        /* Broadcast signals on the cond variable. */
139e41f4b71Sopenharmony_ci        rc = pthread_cond_signal(&g_td.cond);
140e41f4b71Sopenharmony_ci        if (rc != 0) {
141e41f4b71Sopenharmony_ci            dprintf("ERROR: pthread condition failed, error code is %d!\n", rc);
142e41f4b71Sopenharmony_ci            goto ERROROUT;
143e41f4b71Sopenharmony_ci        }
144e41f4b71Sopenharmony_ci    }
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci    sleep(1);
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci    /* Check whether all child threads are woken up. */
149e41f4b71Sopenharmony_ci    if (g_wakenNum != THREAD_NUM) {
150e41f4b71Sopenharmony_ci        dprintf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum);
151e41f4b71Sopenharmony_ci        goto ERROROUT;
152e41f4b71Sopenharmony_ci    }
153e41f4b71Sopenharmony_ci    dprintf("all threads awaked\n");
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci    /* Join all  child threads, that is, wait for the end of all  child threads. */
156e41f4b71Sopenharmony_ci    for (i = 0; i < THREAD_NUM; i++) {
157e41f4b71Sopenharmony_ci        rc = pthread_join(thread[i], NULL);
158e41f4b71Sopenharmony_ci        if (rc != 0) {
159e41f4b71Sopenharmony_ci            dprintf("ERROR: pthread join failed, error code is %d!\n", rc);
160e41f4b71Sopenharmony_ci            goto ERROROUT;
161e41f4b71Sopenharmony_ci        }
162e41f4b71Sopenharmony_ci    }
163e41f4b71Sopenharmony_ci    dprintf("all threads join ok\n");
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci    /* Destroy the cond variable. */
166e41f4b71Sopenharmony_ci    rc = pthread_cond_destroy(&g_td.cond);
167e41f4b71Sopenharmony_ci    if (rc != 0) {
168e41f4b71Sopenharmony_ci        dprintf("ERROR: pthread condition destroy failed, error code is %d!\n", rc);
169e41f4b71Sopenharmony_ci        goto ERROROUT;
170e41f4b71Sopenharmony_ci    }
171e41f4b71Sopenharmony_ci    return 0;
172e41f4b71Sopenharmony_ciERROROUT:
173e41f4b71Sopenharmony_ci    return -1;
174e41f4b71Sopenharmony_ci}
175e41f4b71Sopenharmony_ci```
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci#### Verification
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci  The output is as follows:
180e41f4b71Sopenharmony_ci
181e41f4b71Sopenharmony_ci```
182e41f4b71Sopenharmony_cipthread_create ok
183e41f4b71Sopenharmony_ciall threads awaked
184e41f4b71Sopenharmony_ciall threads join ok
185e41f4b71Sopenharmony_ci```
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci## Differences from the Linux Standard Library
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ciThe following describes the key differences between the standard library supported by the OpenHarmony kernel and the Linux standard library. For more differences, see the API document of the C library.
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci### Process
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci- The OpenHarmony user-mode processes support only static priorities, which range from 10 (highest) to 31 (lowest).
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci- The OpenHarmony user-mode threads support only static priorities, which range from 0 (highest) to 31 (lowest).
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci- The OpenHarmony process scheduling supports **SCHED_RR** only, and thread scheduling supports **SCHED_RR** or **SCHED_FIFO**.
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci### Memory
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci**Differences from Linux mmap**
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_cimmap prototype: **void \*mmap (void \*addr, size_t length, int prot, int flags, int fd, off_t offset)**
206e41f4b71Sopenharmony_ci
207e41f4b71Sopenharmony_ciThe lifecycle implementation of **fd** is different from that of Linux glibc. glibc releases the **fd** handle immediately after successfully invoking **mmap** for mapping. In the OpenHarmony kernel, you are not allowed to close the **fd** immediately after the mapping is successful. You can close the **fd** only after **munmap** is called. If you do not close **fd**, the OS reclaims the **fd** when the process exits.
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci**Example**
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ciLinux:
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci```
215e41f4b71Sopenharmony_ciint main(int argc, char *argv[])
216e41f4b71Sopenharmony_ci{
217e41f4b71Sopenharmony_ci    int fd;
218e41f4b71Sopenharmony_ci    void *addr = NULL;
219e41f4b71Sopenharmony_ci    ...
220e41f4b71Sopenharmony_ci    fd = open(argv[1], O_RDONLY);
221e41f4b71Sopenharmony_ci    if (fd == -1){
222e41f4b71Sopenharmony_ci        perror("open");
223e41f4b71Sopenharmony_ci        exit(EXIT_FAILURE);
224e41f4b71Sopenharmony_ci    }
225e41f4b71Sopenharmony_ci    addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, offset);
226e41f4b71Sopenharmony_ci    if (addr == MAP_FAILED) {
227e41f4b71Sopenharmony_ci        perror("mmap");
228e41f4b71Sopenharmony_ci        exit(EXIT_FAILURE);
229e41f4b71Sopenharmony_ci    }
230e41f4b71Sopenharmony_ci    close(fd);  /* OpenHarmony does not support closing fd immediately after the mapping is successful. */ 
231e41f4b71Sopenharmony_ci    ...
232e41f4b71Sopenharmony_ci    exit(EXIT_SUCCESS);
233e41f4b71Sopenharmony_ci}
234e41f4b71Sopenharmony_ci```
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci  OpenHarmony:
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci```
240e41f4b71Sopenharmony_ciint main(int argc, char *argv[])
241e41f4b71Sopenharmony_ci{
242e41f4b71Sopenharmony_ci    int fd;
243e41f4b71Sopenharmony_ci    void *addr = NULL;
244e41f4b71Sopenharmony_ci    ...
245e41f4b71Sopenharmony_ci    fd = open(argv[1], O_RDONLY);
246e41f4b71Sopenharmony_ci    if (fd == -1) {
247e41f4b71Sopenharmony_ci        perror("open");
248e41f4b71Sopenharmony_ci        exit(EXIT_FAILURE);
249e41f4b71Sopenharmony_ci    }
250e41f4b71Sopenharmony_ci    addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, offset);
251e41f4b71Sopenharmony_ci    if (addr == MAP_FAILED) {
252e41f4b71Sopenharmony_ci        perror("mmap");
253e41f4b71Sopenharmony_ci        exit(EXIT_FAILURE);
254e41f4b71Sopenharmony_ci    }
255e41f4b71Sopenharmony_ci    ...
256e41f4b71Sopenharmony_ci    munmap(addr, length);
257e41f4b71Sopenharmony_ci    close(fd);  /* Close fd after the munmap is canceled. */
258e41f4b71Sopenharmony_ci    exit(EXIT_SUCCESS);
259e41f4b71Sopenharmony_ci}
260e41f4b71Sopenharmony_ci```
261e41f4b71Sopenharmony_ci
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci### File System
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ciSystem directories: You cannot modify system directories and device mount directories, which include **/dev**, **/proc**, **/app**, **/bin**, **/data**, **/etc**, **/lib**, **/system**, and **/usr**.
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ciUser directory: The user directory refers to the **/storage** directory. You can create, read, and write files in this directory, but cannot mount it to a device.
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ciExcept in the system and user directories, you can create directories and mount them to devices. Note that nested mount is not allowed, that is, a mounted folder and its subfolders cannot be mounted repeatedly. A non-empty folder cannot be mounted.
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci### Signal
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci- The default behavior for signals does not include **STOP**, **CONTINUE**, or **COREDUMP**.
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ci- A sleeping process (for example, a process enters the sleeping status by calling the sleep function) cannot be woken up by a signal. The signal mechanism does not support the wakeup function. The behavior for a signal can be processed only when the process is scheduled by the CPU.
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ci- After a process exits, **SIGCHLD** is sent to the parent process. The sending action cannot be canceled.
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ci- Only signals 1 to 30 are supported. The callback is invoked only once even if the same signal is received multiple times.
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci### Time
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ciThe default time precision of OpenHarmony is 10 ms/tick. The time error of the **sleep** and **timeout** functions is less than or equal to 20 ms.
286