Ignore:
Timestamp:
Sep 14, 2020, 6:36:03 PM (4 years ago)
Author:
coas-nagasima
Message:

SPIとSerial、KPUの動作を改善

File:
1 edited

Legend:

Unmodified
Added
Removed
  • azure_iot_hub_riscv/trunk/app_iothub_client/kendryte/atomic.h

    r453 r458  
    2222
    2323#define SPINLOCK_INIT \
    24     {                 \
    25         0             \
    26     }
     24        {                 \
     25                0             \
     26        }
    2727
    2828#define CORELOCK_INIT          \
    29     {                          \
    30         .lock = SPINLOCK_INIT, \
    31         .count = 0,            \
    32         .core = -1             \
    33     }
     29        {                          \
     30                .lock = SPINLOCK_INIT, \
     31                .count = 0,            \
     32                .core = -1             \
     33        }
    3434
    3535/* Defination of memory barrier macro */
    3636#define mb()                          \
    37     {                                 \
    38         asm volatile("fence" ::       \
    39                         : "memory"); \
    40     }
     37        {                                 \
     38                asm volatile("fence" ::       \
     39                                                : "memory"); \
     40        }
    4141
    4242#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
     
    5353typedef struct _spinlock
    5454{
    55     int lock;
     55        int lock;
    5656} spinlock_t;
    5757
    5858typedef struct _semaphore
    5959{
    60     spinlock_t lock;
    61     int count;
    62     int waiting;
     60        spinlock_t lock;
     61        int count;
     62        int waiting;
    6363} semaphore_t;
    6464
    6565typedef struct _corelock
    6666{
    67     spinlock_t lock;
    68     int count;
    69     int core;
     67        spinlock_t lock;
     68        int count;
     69        int core;
    7070} corelock_t;
    7171
    7272static inline int spinlock_trylock(spinlock_t *lock)
    7373{
    74     int res = atomic_swap(&lock->lock, -1);
    75     /* Use memory barrier to keep coherency */
    76     mb();
    77     return res;
     74        int res = atomic_swap(&lock->lock, -1);
     75        /* Use memory barrier to keep coherency */
     76        mb();
     77        return res;
    7878}
    7979
    8080static inline void spinlock_lock(spinlock_t *lock)
    8181{
    82     while(spinlock_trylock(lock))
    83         ;
     82        while(spinlock_trylock(lock))
     83                ;
    8484}
    8585
    8686static inline void spinlock_unlock(spinlock_t *lock)
    8787{
    88     /* Use memory barrier to keep coherency */
    89     mb();
    90     atomic_set(&lock->lock, 0);
    91     asm volatile("nop");
     88        /* Use memory barrier to keep coherency */
     89        mb();
     90        atomic_set(&lock->lock, 0);
     91        asm volatile("nop");
    9292}
    9393
    9494static inline void semaphore_signal(semaphore_t *semaphore, int i)
    9595{
    96     spinlock_lock(&(semaphore->lock));
    97     semaphore->count += i;
    98     spinlock_unlock(&(semaphore->lock));
     96        spinlock_lock(&(semaphore->lock));
     97        semaphore->count += i;
     98        spinlock_unlock(&(semaphore->lock));
    9999}
    100100
    101101static inline void semaphore_wait(semaphore_t *semaphore, int i)
    102102{
    103     atomic_add(&(semaphore->waiting), 1);
    104     while(1)
    105     {
    106         spinlock_lock(&(semaphore->lock));
    107         if(semaphore->count >= i)
    108         {
    109             semaphore->count -= i;
    110             atomic_add(&(semaphore->waiting), -1);
    111             spinlock_unlock(&(semaphore->lock));
    112             break;
    113         }
    114         spinlock_unlock(&(semaphore->lock));
    115     }
     103        atomic_add(&(semaphore->waiting), 1);
     104        while(1)
     105        {
     106                spinlock_lock(&(semaphore->lock));
     107                if(semaphore->count >= i)
     108                {
     109                        semaphore->count -= i;
     110                        atomic_add(&(semaphore->waiting), -1);
     111                        spinlock_unlock(&(semaphore->lock));
     112                        break;
     113                }
     114                spinlock_unlock(&(semaphore->lock));
     115        }
    116116}
    117117
    118118static inline int semaphore_count(semaphore_t *semaphore)
    119119{
    120     int res = 0;
    121 
    122     spinlock_lock(&(semaphore->lock));
    123     res = semaphore->count;
    124     spinlock_unlock(&(semaphore->lock));
    125     return res;
     120        int res = 0;
     121
     122        spinlock_lock(&(semaphore->lock));
     123        res = semaphore->count;
     124        spinlock_unlock(&(semaphore->lock));
     125        return res;
    126126}
    127127
    128128static inline int semaphore_waiting(semaphore_t *semaphore)
    129129{
    130     return atomic_read(&(semaphore->waiting));
     130        return atomic_read(&(semaphore->waiting));
    131131}
    132132
    133133static inline int corelock_trylock(corelock_t *lock)
    134134{
    135     int res = 0;
    136     unsigned long core;
    137 
    138     asm volatile("csrr %0, mhartid;"
    139                 : "=r"(core));
    140     if(spinlock_trylock(&lock->lock))
    141     {
    142         return -1;
    143     }
    144 
    145     if(lock->count == 0)
    146     {
    147         /* First time get lock */
    148         lock->count++;
    149         lock->core = core;
    150         res = 0;
    151     } else if(lock->core == core)
    152     {
    153         /* Same core get lock */
    154         lock->count++;
    155         res = 0;
    156     } else
    157     {
    158         /* Different core get lock */
    159         res = -1;
    160     }
    161     spinlock_unlock(&lock->lock);
    162 
    163     return res;
     135        int res = 0;
     136        unsigned long core;
     137
     138        asm volatile("csrr %0, mhartid;"
     139                                : "=r"(core));
     140        if(spinlock_trylock(&lock->lock))
     141        {
     142                return -1;
     143        }
     144
     145        if(lock->count == 0)
     146        {
     147                /* First time get lock */
     148                lock->count++;
     149                lock->core = core;
     150                res = 0;
     151        } else if(lock->core == core)
     152        {
     153                /* Same core get lock */
     154                lock->count++;
     155                res = 0;
     156        } else
     157        {
     158                /* Different core get lock */
     159                res = -1;
     160        }
     161        spinlock_unlock(&lock->lock);
     162
     163        return res;
    164164}
    165165
    166166static inline void corelock_lock(corelock_t *lock)
    167167{
    168     unsigned long core;
    169 
    170     asm volatile("csrr %0, mhartid;"
    171                 : "=r"(core));
    172     spinlock_lock(&lock->lock);
    173 
    174     if(lock->count == 0)
    175     {
    176         /* First time get lock */
    177         lock->count++;
    178         lock->core = core;
    179     } else if(lock->core == core)
    180     {
    181         /* Same core get lock */
    182         lock->count++;
    183     } else
    184     {
    185         /* Different core get lock */
    186         spinlock_unlock(&lock->lock);
    187 
    188         do
    189         {
    190             while(atomic_read(&lock->count))
    191                 ;
    192         } while(corelock_trylock(lock));
    193         return;
    194     }
    195     spinlock_unlock(&lock->lock);
     168        unsigned long core;
     169
     170        asm volatile("csrr %0, mhartid;"
     171                                : "=r"(core));
     172        spinlock_lock(&lock->lock);
     173
     174        if(lock->count == 0)
     175        {
     176                /* First time get lock */
     177                lock->count++;
     178                lock->core = core;
     179        } else if(lock->core == core)
     180        {
     181                /* Same core get lock */
     182                lock->count++;
     183        } else
     184        {
     185                /* Different core get lock */
     186                spinlock_unlock(&lock->lock);
     187
     188                do
     189                {
     190                        while(atomic_read(&lock->count))
     191                                ;
     192                } while(corelock_trylock(lock));
     193                return;
     194        }
     195        spinlock_unlock(&lock->lock);
    196196}
    197197
    198198static inline void corelock_unlock(corelock_t *lock)
    199199{
    200     unsigned long core;
    201 
    202     asm volatile("csrr %0, mhartid;"
    203                 : "=r"(core));
    204     spinlock_lock(&lock->lock);
    205 
    206     if(lock->core == core)
    207     {
    208         /* Same core release lock */
    209         lock->count--;
    210         if(lock->count <= 0)
    211         {
    212             lock->core = -1;
    213             lock->count = 0;
    214         }
    215     } else
    216     {
    217         /* Different core release lock */
    218         spinlock_unlock(&lock->lock);
    219 
    220         register unsigned long a7 asm("a7") = 93;
    221         register unsigned long a0 asm("a0") = 0;
    222         register unsigned long a1 asm("a1") = 0;
    223         register unsigned long a2 asm("a2") = 0;
    224 
    225         asm volatile("scall"
    226                     : "+r"(a0)
    227                     : "r"(a1), "r"(a2), "r"(a7));
    228     }
    229     spinlock_unlock(&lock->lock);
     200        unsigned long core;
     201
     202        asm volatile("csrr %0, mhartid;"
     203                                : "=r"(core));
     204        spinlock_lock(&lock->lock);
     205
     206        if(lock->core == core)
     207        {
     208                /* Same core release lock */
     209                lock->count--;
     210                if(lock->count <= 0)
     211                {
     212                        lock->core = -1;
     213                        lock->count = 0;
     214                }
     215        } else
     216        {
     217                /* Different core release lock */
     218                spinlock_unlock(&lock->lock);
     219
     220                register unsigned long a7 asm("a7") = 93;
     221                register unsigned long a0 asm("a0") = 0;
     222                register unsigned long a1 asm("a1") = 0;
     223                register unsigned long a2 asm("a2") = 0;
     224
     225                asm volatile("scall"
     226                                        : "+r"(a0)
     227                                        : "r"(a1), "r"(a2), "r"(a7));
     228        }
     229        spinlock_unlock(&lock->lock);
    230230}
    231231
Note: See TracChangeset for help on using the changeset viewer.