Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2bcf6c6 in mainline


Ignore:
Timestamp:
2012-07-27T13:34:48Z (9 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master
Children:
4ec9ea41
Parents:
3bb732b
Message:

Added atomic_cas_ptr() including a sanity test for ia32 and amd64.

Location:
kernel
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/atomic.h

    r3bb732b r2bcf6c6  
    140140}
    141141
     142
     143#define _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, prefix)
     144        asm volatile ( \
     145                prefix " cmpxchgq %[newval], %[ptr]\n" \
     146                : /* Output operands. */ \
     147                /* Old/current value is returned in eax. */ \
     148                [oldval] "=a" (old_val), \
     149                /* (*ptr) will be read and written to, hence "+" */ \
     150                [ptr] "+m" (*pptr) \
     151                : /* Input operands. */ \
     152                /* Expected value must be in eax. */ \
     153                [expval] "a" (exp_val), \
     154                /* The new value may be in any register. */ \
     155                [newval] "r" (new_val) \
     156                : "memory" \
     157        )
     158       
     159/** Atomically compares and swaps the pointer at pptr. */
     160NO_TRACE static inline void * atomic_cas_ptr(void **pptr,
     161        void *exp_val, void *new_val)
     162{
     163        void *old_val;
     164        _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, "lock\n");
     165        return old_val;
     166}
     167
     168/** Compare-and-swap of a pointer that is atomic wrt to local cpu's interrupts.
     169 *
     170 * This function is NOT smp safe and is not atomic with respect to other cpus.
     171 */
     172NO_TRACE static inline void * atomic_cas_ptr_local(void **pptr,
     173        void *exp_val, void *new_val)
     174{
     175        void *old_val;
     176        _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, "");
     177        return old_val;
     178}
     179
     180#undef _atomic_cas_ptr_impl
     181
     182
    142183#endif
    143184
  • kernel/arch/ia32/include/atomic.h

    r3bb732b r2bcf6c6  
    113113}
    114114
     115
    115116/** ia32 specific fast spinlock */
    116117NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
     
    142143}
    143144
     145
     146#define _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, prefix) \
     147        asm volatile ( \
     148                prefix " cmpxchgl %[newval], %[ptr]\n" \
     149                : /* Output operands. */ \
     150                /* Old/current value is returned in eax. */ \
     151                [oldval] "=a" (old_val), \
     152                /* (*ptr) will be read and written to, hence "+" */ \
     153                [ptr] "+m" (*pptr) \
     154                : /* Input operands. */ \
     155                /* Expected value must be in eax. */ \
     156                [expval] "a" (exp_val), \
     157                /* The new value may be in any register. */ \
     158                [newval] "r" (new_val) \
     159                : "memory" \
     160        )
     161       
     162/** Atomically compares and swaps the pointer at pptr. */
     163NO_TRACE static inline void * atomic_cas_ptr(void **pptr,
     164        void *exp_val, void *new_val)
     165{
     166        void *old_val;
     167        _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, "lock\n");
     168        return old_val;
     169}
     170
     171/** Compare-and-swap of a pointer that is atomic wrt to local cpu's interrupts.
     172 *
     173 * This function is NOT smp safe and is not atomic with respect to other cpus.
     174 */
     175NO_TRACE static inline void * atomic_cas_ptr_local(void **pptr,
     176        void *exp_val, void *new_val)
     177{
     178        void *old_val;
     179        _atomic_cas_ptr_impl(pptr, exp_val, new_val, old_val, "");
     180        return old_val;
     181}
     182
     183#undef _atomic_cas_ptr_impl
     184
    144185#endif
    145186
  • kernel/test/atomic/atomic1.c

    r3bb732b r2bcf6c6  
    6060                return "Failed atomic_get() after atomic_predec()";
    6161       
     62        void *ptr = 0;
     63        void *a_ptr = &a;
     64        if (atomic_cas_ptr(&ptr, 0, a_ptr) != 0)
     65                return "Failed atomic_cas_ptr(): bad return value";
     66        if (ptr != a_ptr)
     67                return "Failed atomic_cas_ptr(): bad pointer value";
     68        if (atomic_cas_ptr(&ptr, 0, 0) != a_ptr)
     69                return "Failed atomic_cas_ptr(): indicated change";
     70        if (ptr != a_ptr)
     71                return "Failed atomic_cas_ptr(): changed the ptr";
     72       
    6273        return NULL;
    6374}
Note: See TracChangeset for help on using the changeset viewer.