• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2009-12-22
13  * Description: 信号量模块
14  */
15 #include "prt_sem_external.h"
16 
17 OS_SEC_BSS struct TagListObject g_unusedSemList;
18 OS_SEC_BSS struct TagSemCb *g_allSem;
19 
OsSemRegister(const struct SemModInfo * modInfo)20 OS_SEC_L4_TEXT U32 OsSemRegister(const struct SemModInfo *modInfo)
21 {
22     if (modInfo->maxNum == 0) {
23         return OS_ERRNO_SEM_REG_ERROR;
24     }
25 
26     g_maxSem = modInfo->maxNum;
27 
28     return OS_OK;
29 }
30 
31 /*
32  * 描述:信号量初始化
33  */
OsSemInit(void)34 OS_SEC_L4_TEXT U32 OsSemInit(void)
35 {
36     struct TagSemCb *semNode = NULL;
37     U32 idx;
38     U32 ret = OS_OK;
39 
40     /* g_maxSem在注册时已判断是否大于0,这里不需判断 */
41     g_allSem = (struct TagSemCb *)OsMemAllocAlign((U32)OS_MID_SEM,
42                                                   OS_MEM_DEFAULT_FSC_PT,
43                                                   g_maxSem * sizeof(struct TagSemCb),
44                                                   MEM_ADDR_ALIGN_004);
45     if (g_allSem == NULL) {
46         return OS_ERRNO_SEM_NO_MEMORY;
47     }
48     if (memset_s((void *)g_allSem, g_maxSem * sizeof(struct TagSemCb), 0, g_maxSem * sizeof(struct TagSemCb)) !=
49         EOK) {
50         OS_GOTO_SYS_ERROR1();
51     }
52 
53     INIT_LIST_OBJECT(&g_unusedSemList);
54     for (idx = 0; idx < g_maxSem; idx++) {
55         semNode = ((struct TagSemCb *)g_allSem) + idx;
56         semNode->semId = (U16)idx;
57         ListTailAdd(&semNode->semList, &g_unusedSemList);
58     }
59 
60     return ret;
61 }
62 
63 /*
64  * 描述:创建一个信号量
65  */
OsSemCreate(U32 count,enum SemMode semMode,SemHandle * semHandle,U32 cookie)66 OS_SEC_L4_TEXT U32 OsSemCreate(U32 count, enum SemMode semMode, SemHandle *semHandle, U32 cookie)
67 {
68     uintptr_t intSave;
69     struct TagSemCb *semCreated = NULL;
70     struct TagListObject *unusedSem = NULL;
71 
72     (void)cookie;
73 
74     if (semHandle == NULL) {
75         return OS_ERRNO_SEM_PTR_NULL;
76     }
77 
78     intSave = OsIntLock();
79 
80     if (ListEmpty(&g_unusedSemList)) {
81         OsIntRestore(intSave);
82         return OS_ERRNO_SEM_ALL_BUSY;
83     }
84 
85     /* 在空闲链表中取走一个控制节点 */
86     unusedSem = OS_LIST_FIRST(&(g_unusedSemList));
87     ListDelete(unusedSem);
88 
89     /* 获取到空闲节点对应的信号量控制块,并开始填充控制块 */
90     semCreated = (GET_SEM_LIST(unusedSem));
91     semCreated->semCount = count;
92     semCreated->semStat = OS_SEM_USED;
93     semCreated->semMode = semMode;
94     semCreated->semOwner = OS_INVALID_OWNER_ID;
95     semCreated->maxSemCount = OS_SEM_COUNT_MAX;
96 
97     INIT_LIST_OBJECT(&semCreated->semList);
98     *semHandle = (SemHandle)semCreated->semId;
99 
100     OsIntRestore(intSave);
101     return OS_OK;
102 }
103 
104 /*
105  * 描述:创建一个信号量
106  */
PRT_SemCreate(U32 count,SemHandle * semHandle)107 OS_SEC_L4_TEXT U32 PRT_SemCreate(U32 count, SemHandle *semHandle)
108 {
109     U32 ret;
110 
111     if (count > OS_SEM_COUNT_MAX) {
112         return OS_ERRNO_SEM_OVERFLOW;
113     }
114 
115     ret = OsSemCreate(count, SEM_MODE_FIFO, semHandle, (U32)(uintptr_t)semHandle);
116     return ret;
117 }
118 
119 /*
120  * 描述:删除一个信号量
121  */
PRT_SemDelete(SemHandle semHandle)122 OS_SEC_L4_TEXT U32 PRT_SemDelete(SemHandle semHandle)
123 {
124     uintptr_t intSave;
125     struct TagSemCb *semDeleted = NULL;
126 
127     if (semHandle >= (SemHandle)g_maxSem) {
128         return OS_ERRNO_SEM_INVALID;
129     }
130     semDeleted = GET_SEM(semHandle);
131 
132     intSave = OsIntLock();
133 
134     if (semDeleted->semStat == OS_SEM_UNUSED) {
135         OsIntRestore(intSave);
136         return OS_ERRNO_SEM_INVALID;
137     }
138     if (!ListEmpty(&semDeleted->semList)) {
139         OsIntRestore(intSave);
140         return OS_ERRNO_SEM_PENDED;
141     }
142     semDeleted->semStat = OS_SEM_UNUSED;
143     ListAdd(&semDeleted->semList, &g_unusedSemList);
144 
145     OsIntRestore(intSave);
146     return OS_OK;
147 }
148