xiuos/Ubiquitous/XiZi_AIoT/services/semaphore/semaphore_server.c

122 lines
2.9 KiB
C

/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "libsemaphore.h"
#include "libserial.h"
#include "usyscall.h"
struct Semaphore {
bool valid;
int count;
};
struct Semaphore sem_pool[MAX_SUPPORT_SEMAPHORES];
int IPC_DO_SERVE_FUNC(Ipc_sem_create)(sem_t* sem, int* count)
{
int idx = 0;
for (idx = 0; idx < MAX_SUPPORT_SEMAPHORES; idx++) {
if (!sem_pool[idx].valid) {
break;
}
}
if (idx == MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
sem_pool[idx].valid = true;
sem_pool[idx].count = *count;
*sem = idx;
return SEMAPHORE_SUC;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_delete)(sem_t* sem)
{
if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
if (!sem_pool[*sem].valid) {
return SEMAPHORE_ERR;
}
sem_pool[*sem].valid = false;
return SEMAPHORE_SUC;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_wait)(sem_t* sem, int* timeout)
{
if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
/// @todo support timeout
// return if sem is freed(no valid) or sem count is sufficient
if (!sem_pool[*sem].valid || sem_pool[*sem].count > 0) {
sem_pool[*sem].count--;
return SEMAPHORE_SUC;
}
// delay current session
// this handler will be invoke again later
delay_session();
return SEMAPHORE_ERR;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_signal)(sem_t* sem)
{
if (*sem < 0 || *sem >= MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
if (!sem_pool[*sem].valid) {
return SEMAPHORE_ERR;
}
sem_pool[*sem].count++;
return SEMAPHORE_SUC;
}
IPC_SERVER_INTERFACE(Ipc_sem_create, 2);
IPC_SERVER_INTERFACE(Ipc_sem_delete, 1);
IPC_SERVER_INTERFACE(Ipc_sem_signal, 1);
IPC_SERVER_INTERFACE(Ipc_sem_wait, 2);
IPC_SERVER_REGISTER_INTERFACES(IpcSemaphoreServer, 4, //
Ipc_sem_create, Ipc_sem_delete, Ipc_sem_signal, Ipc_sem_wait);
int main(int argc, char** argv)
{
/// @todo support custom server name
static char default_server_name[] = "DefaultSemaphoreServer";
char* server_name = default_server_name;
if (argc == 2) {
server_name = argv[1];
}
if (register_server(server_name) < 0) {
printf("[%s] Register server failed.\n", server_name);
exit(1);
}
for (int idx = 0; idx < MAX_SUPPORT_SEMAPHORES; idx++) {
sem_pool[idx].valid = false;
}
ipc_server_loop(&IpcSemaphoreServer);
// never reaching here
exit(0);
return 0;
}