xref: /rockchip-linux_mpp/osal/mpp_lock.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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