1cb69b360Sopenharmony_ci/* 2cb69b360Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3cb69b360Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cb69b360Sopenharmony_ci * you may not use this file except in compliance with the License. 5cb69b360Sopenharmony_ci * You may obtain a copy of the License at 6cb69b360Sopenharmony_ci * 7cb69b360Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cb69b360Sopenharmony_ci * 9cb69b360Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cb69b360Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cb69b360Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cb69b360Sopenharmony_ci * See the License for the specific language governing permissions and 13cb69b360Sopenharmony_ci * limitations under the License. 14cb69b360Sopenharmony_ci */ 15cb69b360Sopenharmony_ci 16cb69b360Sopenharmony_ci#include "running_lock.h" 17cb69b360Sopenharmony_ci 18cb69b360Sopenharmony_ci#include <stdint.h> 19cb69b360Sopenharmony_ci#include <stdlib.h> 20cb69b360Sopenharmony_ci 21cb69b360Sopenharmony_ci#include <common.h> 22cb69b360Sopenharmony_ci#include <ohos_errno.h> 23cb69b360Sopenharmony_ci#include <pthread.h> 24cb69b360Sopenharmony_ci#include <securec.h> 25cb69b360Sopenharmony_ci 26cb69b360Sopenharmony_ci#include "hilog_wrapper.h" 27cb69b360Sopenharmony_ci#include "running_lock_entry.h" 28cb69b360Sopenharmony_ci#include "running_lock_framework.h" 29cb69b360Sopenharmony_ci 30cb69b360Sopenharmony_cistatic pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 31cb69b360Sopenharmony_cistatic BOOL g_inited = FALSE; 32cb69b360Sopenharmony_cistatic Vector g_runningLocks; 33cb69b360Sopenharmony_ci 34cb69b360Sopenharmony_cistatic BOOL AddRunningLock(RunningLock *lock) 35cb69b360Sopenharmony_ci{ 36cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 37cb69b360Sopenharmony_ci if (g_inited == FALSE) { 38cb69b360Sopenharmony_ci g_runningLocks = VECTOR_Make(NULL, NULL); 39cb69b360Sopenharmony_ci g_inited = TRUE; 40cb69b360Sopenharmony_ci } 41cb69b360Sopenharmony_ci int16_t pos = VECTOR_Add(&g_runningLocks, (void *)lock); 42cb69b360Sopenharmony_ci if (pos == INVALID_INDEX) { 43cb69b360Sopenharmony_ci POWER_HILOGE("Failed to add lock to vector"); 44cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 45cb69b360Sopenharmony_ci return FALSE; 46cb69b360Sopenharmony_ci } 47cb69b360Sopenharmony_ci POWER_HILOGD("Add running lock, name: %s, type: %d", lock->name, lock->type); 48cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 49cb69b360Sopenharmony_ci return TRUE; 50cb69b360Sopenharmony_ci} 51cb69b360Sopenharmony_ci 52cb69b360Sopenharmony_cistatic BOOL RemoveRunningLock(const RunningLock *lock) 53cb69b360Sopenharmony_ci{ 54cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 55cb69b360Sopenharmony_ci int16_t pos = VECTOR_Find(&g_runningLocks, (void *)lock); 56cb69b360Sopenharmony_ci if (pos < 0) { 57cb69b360Sopenharmony_ci POWER_HILOGE("Non-existent running lock"); 58cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 59cb69b360Sopenharmony_ci return FALSE; 60cb69b360Sopenharmony_ci } 61cb69b360Sopenharmony_ci VECTOR_Swap(&g_runningLocks, pos, NULL); 62cb69b360Sopenharmony_ci POWER_HILOGD("Remove running lock, name: %s, type: %d", lock->name, lock->type); 63cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 64cb69b360Sopenharmony_ci return TRUE; 65cb69b360Sopenharmony_ci} 66cb69b360Sopenharmony_ci 67cb69b360Sopenharmony_cistatic BOOL IsRunningLockExisted(const RunningLock *lock) 68cb69b360Sopenharmony_ci{ 69cb69b360Sopenharmony_ci if (lock == NULL) { 70cb69b360Sopenharmony_ci POWER_HILOGE("Invalid running lock"); 71cb69b360Sopenharmony_ci return FALSE; 72cb69b360Sopenharmony_ci } 73cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 74cb69b360Sopenharmony_ci BOOL ret = (VECTOR_Find(&g_runningLocks, (void *)lock) >= 0) ? TRUE : FALSE; 75cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 76cb69b360Sopenharmony_ci return ret; 77cb69b360Sopenharmony_ci} 78cb69b360Sopenharmony_ci 79cb69b360Sopenharmony_cistatic RunningLockEntry *CreateRunningLockEntry(const char *name, RunningLockType type, RunningLockFlag flag) 80cb69b360Sopenharmony_ci{ 81cb69b360Sopenharmony_ci RunningLockEntry *entry = (RunningLockEntry *)malloc(sizeof(RunningLockEntry)); 82cb69b360Sopenharmony_ci if (entry == NULL) { 83cb69b360Sopenharmony_ci POWER_HILOGE("Failed allocate running lock entry"); 84cb69b360Sopenharmony_ci return NULL; 85cb69b360Sopenharmony_ci } 86cb69b360Sopenharmony_ci (void)memset_s(entry, sizeof(RunningLockEntry), 0, sizeof(RunningLockEntry)); 87cb69b360Sopenharmony_ci InitIdentity(entry); 88cb69b360Sopenharmony_ci entry->lock.type = type; 89cb69b360Sopenharmony_ci entry->lock.flag = flag; 90cb69b360Sopenharmony_ci if (strcpy_s(entry->lock.name, sizeof(entry->lock.name), name) != EOK) { 91cb69b360Sopenharmony_ci free(entry); 92cb69b360Sopenharmony_ci return NULL; 93cb69b360Sopenharmony_ci } 94cb69b360Sopenharmony_ci return entry; 95cb69b360Sopenharmony_ci} 96cb69b360Sopenharmony_ci 97cb69b360Sopenharmony_cistatic inline void DestroyRunningLockEntry(RunningLockEntry *entry) 98cb69b360Sopenharmony_ci{ 99cb69b360Sopenharmony_ci if (entry != NULL) { 100cb69b360Sopenharmony_ci POWER_HILOGD("Free entry: %p", entry); 101cb69b360Sopenharmony_ci free(entry); 102cb69b360Sopenharmony_ci } 103cb69b360Sopenharmony_ci} 104cb69b360Sopenharmony_ci 105cb69b360Sopenharmony_ciconst RunningLock *CreateRunningLock(const char *name, RunningLockType type, RunningLockFlag flag) 106cb69b360Sopenharmony_ci{ 107cb69b360Sopenharmony_ci if ((name == NULL) || (type >= RUNNINGLOCK_BUTT)) { 108cb69b360Sopenharmony_ci POWER_HILOGE("Invalid running lock name"); 109cb69b360Sopenharmony_ci return NULL; 110cb69b360Sopenharmony_ci } 111cb69b360Sopenharmony_ci 112cb69b360Sopenharmony_ci RunningLockEntry *entry = CreateRunningLockEntry(name, type, flag); 113cb69b360Sopenharmony_ci if (entry == NULL) { 114cb69b360Sopenharmony_ci POWER_HILOGE("Failed create running lock entry"); 115cb69b360Sopenharmony_ci return NULL; 116cb69b360Sopenharmony_ci } 117cb69b360Sopenharmony_ci AddRunningLock(&entry->lock); 118cb69b360Sopenharmony_ci POWER_HILOGD("Create %s, pid: %u, token: %llu", name, entry->identity.pid, (long long)entry->identity.token); 119cb69b360Sopenharmony_ci return &entry->lock; 120cb69b360Sopenharmony_ci} 121cb69b360Sopenharmony_ci 122cb69b360Sopenharmony_ciBOOL AcquireRunningLock(const RunningLock *lock) 123cb69b360Sopenharmony_ci{ 124cb69b360Sopenharmony_ci if (IsRunningLockExisted(lock) == FALSE) { 125cb69b360Sopenharmony_ci POWER_HILOGE("Non-existent running lock"); 126cb69b360Sopenharmony_ci return FALSE; 127cb69b360Sopenharmony_ci } 128cb69b360Sopenharmony_ci RunningLockEntry *entry = GetRunningLockEntry(lock); 129cb69b360Sopenharmony_ci if (entry->status.isHolding == TRUE) { 130cb69b360Sopenharmony_ci POWER_HILOGD("Already acquired, name: %s", lock->name); 131cb69b360Sopenharmony_ci return TRUE; 132cb69b360Sopenharmony_ci } 133cb69b360Sopenharmony_ci entry->status.isHolding = AcquireRunningLockEntry(entry, -1); 134cb69b360Sopenharmony_ci return entry->status.isHolding; 135cb69b360Sopenharmony_ci} 136cb69b360Sopenharmony_ci 137cb69b360Sopenharmony_ciBOOL ReleaseRunningLock(const RunningLock *lock) 138cb69b360Sopenharmony_ci{ 139cb69b360Sopenharmony_ci if (IsRunningLockExisted(lock) == FALSE) { 140cb69b360Sopenharmony_ci POWER_HILOGE("Non-existent running lock"); 141cb69b360Sopenharmony_ci return FALSE; 142cb69b360Sopenharmony_ci } 143cb69b360Sopenharmony_ci RunningLockEntry *entry = GetRunningLockEntry(lock); 144cb69b360Sopenharmony_ci if (entry->status.isHolding == FALSE) { 145cb69b360Sopenharmony_ci POWER_HILOGD("Already released, name: %s", lock->name); 146cb69b360Sopenharmony_ci return TRUE; 147cb69b360Sopenharmony_ci } 148cb69b360Sopenharmony_ci entry->status.isHolding = !ReleaseRunningLockEntry(entry); 149cb69b360Sopenharmony_ci return !entry->status.isHolding; 150cb69b360Sopenharmony_ci} 151cb69b360Sopenharmony_ci 152cb69b360Sopenharmony_civoid DestroyRunningLock(const RunningLock *lock) 153cb69b360Sopenharmony_ci{ 154cb69b360Sopenharmony_ci if (lock == NULL) { 155cb69b360Sopenharmony_ci POWER_HILOGE("Invalid running lock"); 156cb69b360Sopenharmony_ci return; 157cb69b360Sopenharmony_ci } 158cb69b360Sopenharmony_ci ReleaseRunningLock(lock); 159cb69b360Sopenharmony_ci if (RemoveRunningLock(lock) == TRUE) { 160cb69b360Sopenharmony_ci DestroyRunningLockEntry(GetRunningLockEntry(lock)); 161cb69b360Sopenharmony_ci } 162cb69b360Sopenharmony_ci} 163cb69b360Sopenharmony_ci 164cb69b360Sopenharmony_ciBOOL IsRunningLockHolding(const RunningLock *lock) 165cb69b360Sopenharmony_ci{ 166cb69b360Sopenharmony_ci if (IsRunningLockExisted(lock) == FALSE) { 167cb69b360Sopenharmony_ci POWER_HILOGE("Non-existent running lock"); 168cb69b360Sopenharmony_ci return FALSE; 169cb69b360Sopenharmony_ci } 170cb69b360Sopenharmony_ci RunningLockEntry *entry = GetRunningLockEntry(lock); 171cb69b360Sopenharmony_ci return entry->status.isHolding; 172cb69b360Sopenharmony_ci} 173