13d8536b4Sopenharmony_ci/*
23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
33d8536b4Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
43d8536b4Sopenharmony_ci *
53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met:
73d8536b4Sopenharmony_ci *
83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
93d8536b4Sopenharmony_ci *    conditions and the following disclaimer.
103d8536b4Sopenharmony_ci *
113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
123d8536b4Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
133d8536b4Sopenharmony_ci *    provided with the distribution.
143d8536b4Sopenharmony_ci *
153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
163d8536b4Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
173d8536b4Sopenharmony_ci *    permission.
183d8536b4Sopenharmony_ci *
193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
303d8536b4Sopenharmony_ci */
313d8536b4Sopenharmony_ci
323d8536b4Sopenharmony_ci#include <errno.h>
333d8536b4Sopenharmony_ci#include <securec.h>
343d8536b4Sopenharmony_ci#include <limits.h>
353d8536b4Sopenharmony_ci#include "pthread.h"
363d8536b4Sopenharmony_ci#include "los_config.h"
373d8536b4Sopenharmony_ci#include "los_debug.h"
383d8536b4Sopenharmony_ci
393d8536b4Sopenharmony_ciint pthread_attr_init(pthread_attr_t *attr)
403d8536b4Sopenharmony_ci{
413d8536b4Sopenharmony_ci    if (attr == NULL) {
423d8536b4Sopenharmony_ci        return EINVAL;
433d8536b4Sopenharmony_ci    }
443d8536b4Sopenharmony_ci
453d8536b4Sopenharmony_ci    attr->detachstate                 = PTHREAD_CREATE_JOINABLE;
463d8536b4Sopenharmony_ci    attr->schedpolicy                 = SCHED_RR;
473d8536b4Sopenharmony_ci    attr->schedparam.sched_priority   = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
483d8536b4Sopenharmony_ci    attr->inheritsched                = PTHREAD_INHERIT_SCHED;
493d8536b4Sopenharmony_ci    attr->scope                       = PTHREAD_SCOPE_SYSTEM;
503d8536b4Sopenharmony_ci    attr->stackaddr_set               = 0;
513d8536b4Sopenharmony_ci    attr->stackaddr                   = NULL;
523d8536b4Sopenharmony_ci    attr->stacksize_set               = 1;
533d8536b4Sopenharmony_ci    attr->stacksize                   = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
543d8536b4Sopenharmony_ci
553d8536b4Sopenharmony_ci    return 0;
563d8536b4Sopenharmony_ci}
573d8536b4Sopenharmony_ci
583d8536b4Sopenharmony_ciint pthread_attr_destroy(pthread_attr_t *attr)
593d8536b4Sopenharmony_ci{
603d8536b4Sopenharmony_ci    if (attr == NULL) {
613d8536b4Sopenharmony_ci        return EINVAL;
623d8536b4Sopenharmony_ci    }
633d8536b4Sopenharmony_ci
643d8536b4Sopenharmony_ci    (void)memset_s(attr, sizeof(pthread_attr_t), 0, sizeof(pthread_attr_t));
653d8536b4Sopenharmony_ci
663d8536b4Sopenharmony_ci    return 0;
673d8536b4Sopenharmony_ci}
683d8536b4Sopenharmony_ci
693d8536b4Sopenharmony_ciint pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState)
703d8536b4Sopenharmony_ci{
713d8536b4Sopenharmony_ci    if ((attr != NULL) && ((detachState == PTHREAD_CREATE_JOINABLE) || (detachState == PTHREAD_CREATE_DETACHED))) {
723d8536b4Sopenharmony_ci        attr->detachstate = (UINT32)detachState;
733d8536b4Sopenharmony_ci        return 0;
743d8536b4Sopenharmony_ci    }
753d8536b4Sopenharmony_ci
763d8536b4Sopenharmony_ci    return EINVAL;
773d8536b4Sopenharmony_ci}
783d8536b4Sopenharmony_ci
793d8536b4Sopenharmony_ciint pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState)
803d8536b4Sopenharmony_ci{
813d8536b4Sopenharmony_ci    if ((attr == NULL) || (detachState == NULL)) {
823d8536b4Sopenharmony_ci        return EINVAL;
833d8536b4Sopenharmony_ci    }
843d8536b4Sopenharmony_ci
853d8536b4Sopenharmony_ci    *detachState = (int)attr->detachstate;
863d8536b4Sopenharmony_ci
873d8536b4Sopenharmony_ci    return 0;
883d8536b4Sopenharmony_ci}
893d8536b4Sopenharmony_ci
903d8536b4Sopenharmony_ciint pthread_attr_setscope(pthread_attr_t *attr, int scope)
913d8536b4Sopenharmony_ci{
923d8536b4Sopenharmony_ci    if (attr == NULL) {
933d8536b4Sopenharmony_ci        return EINVAL;
943d8536b4Sopenharmony_ci    }
953d8536b4Sopenharmony_ci
963d8536b4Sopenharmony_ci    if (scope == PTHREAD_SCOPE_SYSTEM) {
973d8536b4Sopenharmony_ci        attr->scope = (unsigned int)scope;
983d8536b4Sopenharmony_ci        return 0;
993d8536b4Sopenharmony_ci    }
1003d8536b4Sopenharmony_ci
1013d8536b4Sopenharmony_ci    if (scope == PTHREAD_SCOPE_PROCESS) {
1023d8536b4Sopenharmony_ci        return ENOTSUP;
1033d8536b4Sopenharmony_ci    }
1043d8536b4Sopenharmony_ci
1053d8536b4Sopenharmony_ci    return EINVAL;
1063d8536b4Sopenharmony_ci}
1073d8536b4Sopenharmony_ci
1083d8536b4Sopenharmony_ciint pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
1093d8536b4Sopenharmony_ci{
1103d8536b4Sopenharmony_ci    if ((attr == NULL) || (scope == NULL)) {
1113d8536b4Sopenharmony_ci        return EINVAL;
1123d8536b4Sopenharmony_ci    }
1133d8536b4Sopenharmony_ci
1143d8536b4Sopenharmony_ci    *scope = (int)attr->scope;
1153d8536b4Sopenharmony_ci
1163d8536b4Sopenharmony_ci    return 0;
1173d8536b4Sopenharmony_ci}
1183d8536b4Sopenharmony_ci
1193d8536b4Sopenharmony_ciint pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
1203d8536b4Sopenharmony_ci{
1213d8536b4Sopenharmony_ci    if ((attr != NULL) && ((inherit == PTHREAD_INHERIT_SCHED) || (inherit == PTHREAD_EXPLICIT_SCHED))) {
1223d8536b4Sopenharmony_ci        attr->inheritsched = (UINT32)inherit;
1233d8536b4Sopenharmony_ci        return 0;
1243d8536b4Sopenharmony_ci    }
1253d8536b4Sopenharmony_ci
1263d8536b4Sopenharmony_ci    return EINVAL;
1273d8536b4Sopenharmony_ci}
1283d8536b4Sopenharmony_ci
1293d8536b4Sopenharmony_ciint pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
1303d8536b4Sopenharmony_ci{
1313d8536b4Sopenharmony_ci    if ((attr == NULL) || (inherit == NULL)) {
1323d8536b4Sopenharmony_ci        return EINVAL;
1333d8536b4Sopenharmony_ci    }
1343d8536b4Sopenharmony_ci
1353d8536b4Sopenharmony_ci    *inherit = (int)attr->inheritsched;
1363d8536b4Sopenharmony_ci
1373d8536b4Sopenharmony_ci    return 0;
1383d8536b4Sopenharmony_ci}
1393d8536b4Sopenharmony_ci
1403d8536b4Sopenharmony_ciint pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
1413d8536b4Sopenharmony_ci{
1423d8536b4Sopenharmony_ci    if ((attr != NULL) && (policy == SCHED_RR)) {
1433d8536b4Sopenharmony_ci        attr->schedpolicy = SCHED_RR;
1443d8536b4Sopenharmony_ci        return 0;
1453d8536b4Sopenharmony_ci    }
1463d8536b4Sopenharmony_ci
1473d8536b4Sopenharmony_ci    return EINVAL;
1483d8536b4Sopenharmony_ci}
1493d8536b4Sopenharmony_ci
1503d8536b4Sopenharmony_ciint pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
1513d8536b4Sopenharmony_ci{
1523d8536b4Sopenharmony_ci    if ((attr == NULL) || (policy == NULL)) {
1533d8536b4Sopenharmony_ci        return EINVAL;
1543d8536b4Sopenharmony_ci    }
1553d8536b4Sopenharmony_ci
1563d8536b4Sopenharmony_ci    *policy = (int)attr->schedpolicy;
1573d8536b4Sopenharmony_ci
1583d8536b4Sopenharmony_ci    return 0;
1593d8536b4Sopenharmony_ci}
1603d8536b4Sopenharmony_ci
1613d8536b4Sopenharmony_ciint pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
1623d8536b4Sopenharmony_ci{
1633d8536b4Sopenharmony_ci    if ((attr == NULL) || (param == NULL)) {
1643d8536b4Sopenharmony_ci        return EINVAL;
1653d8536b4Sopenharmony_ci    } else if ((param->sched_priority < LOS_TASK_PRIORITY_HIGHEST) ||
1663d8536b4Sopenharmony_ci               (param->sched_priority >= LOS_TASK_PRIORITY_LOWEST)) {
1673d8536b4Sopenharmony_ci        return ENOTSUP;
1683d8536b4Sopenharmony_ci    }
1693d8536b4Sopenharmony_ci
1703d8536b4Sopenharmony_ci    attr->schedparam = *param;
1713d8536b4Sopenharmony_ci
1723d8536b4Sopenharmony_ci    return 0;
1733d8536b4Sopenharmony_ci}
1743d8536b4Sopenharmony_ci
1753d8536b4Sopenharmony_ciint pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
1763d8536b4Sopenharmony_ci{
1773d8536b4Sopenharmony_ci    if ((attr == NULL) || (param == NULL)) {
1783d8536b4Sopenharmony_ci        return EINVAL;
1793d8536b4Sopenharmony_ci    }
1803d8536b4Sopenharmony_ci
1813d8536b4Sopenharmony_ci    *param = attr->schedparam;
1823d8536b4Sopenharmony_ci
1833d8536b4Sopenharmony_ci    return 0;
1843d8536b4Sopenharmony_ci}
1853d8536b4Sopenharmony_ci
1863d8536b4Sopenharmony_ci/*
1873d8536b4Sopenharmony_ci * Set starting address of stack. Whether this is at the start or end of
1883d8536b4Sopenharmony_ci * the memory block allocated for the stack depends on whether the stack
1893d8536b4Sopenharmony_ci * grows up or down.
1903d8536b4Sopenharmony_ci */
1913d8536b4Sopenharmony_ciint pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr)
1923d8536b4Sopenharmony_ci{
1933d8536b4Sopenharmony_ci    if (attr == NULL) {
1943d8536b4Sopenharmony_ci        return EINVAL;
1953d8536b4Sopenharmony_ci    }
1963d8536b4Sopenharmony_ci
1973d8536b4Sopenharmony_ci    attr->stackaddr_set = 1;
1983d8536b4Sopenharmony_ci    attr->stackaddr     = stackAddr;
1993d8536b4Sopenharmony_ci
2003d8536b4Sopenharmony_ci    return 0;
2013d8536b4Sopenharmony_ci}
2023d8536b4Sopenharmony_ci
2033d8536b4Sopenharmony_ciint pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr)
2043d8536b4Sopenharmony_ci{
2053d8536b4Sopenharmony_ci    if (((attr != NULL) && (stackAddr != NULL)) && attr->stackaddr_set) {
2063d8536b4Sopenharmony_ci        *stackAddr = attr->stackaddr;
2073d8536b4Sopenharmony_ci        return 0;
2083d8536b4Sopenharmony_ci    }
2093d8536b4Sopenharmony_ci
2103d8536b4Sopenharmony_ci    return EINVAL; /* Stack address not set, return EINVAL. */
2113d8536b4Sopenharmony_ci}
2123d8536b4Sopenharmony_ci
2133d8536b4Sopenharmony_ciint pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
2143d8536b4Sopenharmony_ci{
2153d8536b4Sopenharmony_ci    /* Reject inadequate stack sizes */
2163d8536b4Sopenharmony_ci    if ((attr == NULL) || (stackSize < PTHREAD_STACK_MIN)) {
2173d8536b4Sopenharmony_ci        return EINVAL;
2183d8536b4Sopenharmony_ci    }
2193d8536b4Sopenharmony_ci
2203d8536b4Sopenharmony_ci    attr->stacksize_set = 1;
2213d8536b4Sopenharmony_ci    attr->stacksize     = stackSize;
2223d8536b4Sopenharmony_ci    return 0;
2233d8536b4Sopenharmony_ci}
2243d8536b4Sopenharmony_ci
2253d8536b4Sopenharmony_ciint pthread_attr_setstack(pthread_attr_t *attr, void *stackAddr, size_t stackSize)
2263d8536b4Sopenharmony_ci{
2273d8536b4Sopenharmony_ci    if ((attr == NULL) || (stackAddr == NULL) || (stackSize < PTHREAD_STACK_MIN)) {
2283d8536b4Sopenharmony_ci        return EINVAL;
2293d8536b4Sopenharmony_ci    }
2303d8536b4Sopenharmony_ci
2313d8536b4Sopenharmony_ci    attr->stacksize_set = 1;
2323d8536b4Sopenharmony_ci    attr->stacksize     = stackSize;
2333d8536b4Sopenharmony_ci    attr->stackaddr_set = 1;
2343d8536b4Sopenharmony_ci    attr->stackaddr     = stackAddr;
2353d8536b4Sopenharmony_ci    return 0;
2363d8536b4Sopenharmony_ci}
2373d8536b4Sopenharmony_ci
2383d8536b4Sopenharmony_ciint pthread_attr_getstack(const pthread_attr_t *attr, void **stackAddr, size_t *stackSize)
2393d8536b4Sopenharmony_ci{
2403d8536b4Sopenharmony_ci    if ((attr == NULL) || (stackAddr == NULL) || (stackSize == NULL) ||
2413d8536b4Sopenharmony_ci        !attr->stacksize_set || !attr->stackaddr_set) {
2423d8536b4Sopenharmony_ci        return EINVAL;
2433d8536b4Sopenharmony_ci    }
2443d8536b4Sopenharmony_ci
2453d8536b4Sopenharmony_ci    *stackAddr = attr->stackaddr;
2463d8536b4Sopenharmony_ci    *stackSize = attr->stacksize;
2473d8536b4Sopenharmony_ci    return 0;
2483d8536b4Sopenharmony_ci}
2493d8536b4Sopenharmony_ci
2503d8536b4Sopenharmony_ciint pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
2513d8536b4Sopenharmony_ci{
2523d8536b4Sopenharmony_ci    /* Reject attempts to get a stack size when one has not been set. */
2533d8536b4Sopenharmony_ci    if ((attr == NULL) || (stackSize == NULL) || (!attr->stacksize_set)) {
2543d8536b4Sopenharmony_ci        return EINVAL;
2553d8536b4Sopenharmony_ci    }
2563d8536b4Sopenharmony_ci
2573d8536b4Sopenharmony_ci    *stackSize = attr->stacksize;
2583d8536b4Sopenharmony_ci
2593d8536b4Sopenharmony_ci    return 0;
2603d8536b4Sopenharmony_ci}
2613d8536b4Sopenharmony_ci
2623d8536b4Sopenharmony_ciint sched_get_priority_min(int policy)
2633d8536b4Sopenharmony_ci{
2643d8536b4Sopenharmony_ci    if (policy != SCHED_RR) {
2653d8536b4Sopenharmony_ci        errno = EINVAL;
2663d8536b4Sopenharmony_ci        return -1;
2673d8536b4Sopenharmony_ci    }
2683d8536b4Sopenharmony_ci
2693d8536b4Sopenharmony_ci    return LOS_TASK_PRIORITY_LOWEST;
2703d8536b4Sopenharmony_ci}
2713d8536b4Sopenharmony_ci
2723d8536b4Sopenharmony_ciint sched_get_priority_max(int policy)
2733d8536b4Sopenharmony_ci{
2743d8536b4Sopenharmony_ci    if (policy != SCHED_RR) {
2753d8536b4Sopenharmony_ci        errno = EINVAL;
2763d8536b4Sopenharmony_ci        return -1;
2773d8536b4Sopenharmony_ci    }
2783d8536b4Sopenharmony_ci
2793d8536b4Sopenharmony_ci    return LOS_TASK_PRIORITY_HIGHEST;
2803d8536b4Sopenharmony_ci}
281