1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "mpp_lock"
7
8 #include "mpp_env.h"
9 #include "mpp_log.h"
10 #include "mpp_lock.h"
11 #include "mpp_time.h"
12
13 #define LOCK_IDLE 0
14 #define LOCK_BUSY 1
15
mpp_spinlock_init(spinlock_t * lock)16 void mpp_spinlock_init(spinlock_t *lock)
17 {
18 MPP_SYNC_CLR(&lock->lock);
19 lock->count = 0;
20 lock->time = 0;
21
22 mpp_env_get_u32("mpp_lock_debug", &lock->debug, 0);
23 }
24
mpp_spinlock_lock(spinlock_t * lock)25 void mpp_spinlock_lock(spinlock_t *lock)
26 {
27 RK_S64 time = 0;
28
29 if (lock->debug)
30 time = mpp_time();
31
32 while (!MPP_BOOL_CAS(&lock->lock, LOCK_IDLE, LOCK_BUSY)) {
33 asm("NOP");
34 asm("NOP");
35 }
36
37 if (lock->debug && time) {
38 lock->time += mpp_time() - time;
39 lock->count++;
40 }
41 }
42
mpp_spinlock_deinit(spinlock_t * lock,const char * name)43 void mpp_spinlock_deinit(spinlock_t *lock, const char *name)
44 {
45 if (lock->debug && lock->count) {
46 mpp_log("lock %s lock %lld times take time %lld avg %d", name,
47 lock->count, lock->time, (RK_S32)(lock->time / lock->count));
48 }
49 }
50
mpp_spinlock_unlock(spinlock_t * lock)51 void mpp_spinlock_unlock(spinlock_t *lock)
52 {
53 MPP_SYNC_CLR(&lock->lock);
54 }
55
mpp_spinlock_trylock(spinlock_t * lock)56 bool mpp_spinlock_trylock(spinlock_t *lock)
57 {
58 RK_S64 time = 0;
59 bool ret;
60
61 if (lock->debug)
62 time = mpp_time();
63
64 ret = MPP_BOOL_CAS(&lock->lock, LOCK_IDLE, LOCK_BUSY);
65
66 if (ret && lock->debug && time) {
67 lock->time += mpp_time() - time;
68 lock->count++;
69 }
70
71 return ret;
72 }
73