Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/mips/include/asm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

SSL local.h   Interaktion und
PortierbarkeitC

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARCH_MIPS_LOCAL_H
#define _ARCH_MIPS_LOCAL_H

#include <linux/percpu.h>
#include <linux/bitops.h>
#include <linux/atomic.h>
#include <asm/asm.h>
#include <asm/cmpxchg.h>
#include <asm/compiler.h>

typedef struct
{
 atomic_long_t a;
} local_t;

#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }

#define local_read(l) atomic_long_read(&(l)->a)
#define local_set(l, i) atomic_long_set(&(l)->a, (i))

#define local_add(i, l) atomic_long_add((i), (&(l)->a))
#define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
#define local_inc(l) atomic_long_inc(&(l)->a)
#define local_dec(l) atomic_long_dec(&(l)->a)

/*
 * Same as above, but return the result value
 */

static __inline__ long local_add_return(long i, local_t * l)
{
 unsigned long result;

 if (kernel_uses_llsc) {
  unsigned long temp;

  __asm__ __volatile__(
  " .set push \n"
  " .set "MIPS_ISA_ARCH_LEVEL" \n"
   __SYNC(full, loongson3_war) " \n"
  "1:" __stringify(LONG_LL) " %1, %2 \n"
   __stringify(LONG_ADDU) " %0, %1, %3 \n"
   __stringify(LONG_SC) " %0, %2 \n"
   __stringify(SC_BEQZ) " %0, 1b \n"
   __stringify(LONG_ADDU) " %0, %1, %3 \n"
  " .set pop \n"
  : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
  : "Ir" (i), "m" (l->a.counter)
  : "memory");
 } else {
  unsigned long flags;

  local_irq_save(flags);
  result = l->a.counter;
  result += i;
  l->a.counter = result;
  local_irq_restore(flags);
 }

 return result;
}

static __inline__ long local_sub_return(long i, local_t * l)
{
 unsigned long result;

 if (kernel_uses_llsc) {
  unsigned long temp;

  __asm__ __volatile__(
  " .set push \n"
  " .set "MIPS_ISA_ARCH_LEVEL" \n"
   __SYNC(full, loongson3_war) " \n"
  "1:" __stringify(LONG_LL) " %1, %2 \n"
   __stringify(LONG_SUBU) " %0, %1, %3 \n"
   __stringify(LONG_SUBU) " %0, %1, %3 \n"
   __stringify(LONG_SC) " %0, %2 \n"
   __stringify(SC_BEQZ) " %0, 1b \n"
   __stringify(LONG_SUBU) " %0, %1, %3 \n"
  " .set pop \n"
  : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
  : "Ir" (i), "m" (l->a.counter)
  : "memory");
 } else {
  unsigned long flags;

  local_irq_save(flags);
  result = l->a.counter;
  result -= i;
  l->a.counter = result;
  local_irq_restore(flags);
 }

 return result;
}

static __inline__ long local_cmpxchg(local_t *l, long old, long new)
{
 return cmpxchg_local(&l->a.counter, old, new);
}

static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
{
 return try_cmpxchg_local(&l->a.counter,
     (typeof(l->a.counter) *) old, new);
}

#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))

/**
 * local_add_unless - add unless the number is already a given value
 * @l: pointer of type local_t
 * @a: the amount to add to l...
 * @u: ...unless l is equal to u.
 *
 * Atomically adds @a to @l, if @v was not already @u.
 * Returns true if the addition was done.
 */

static __inline__ bool
local_add_unless(local_t *l, long a, long u)
{
 long c = local_read(l);

 do {
  if (unlikely(c == u))
   return false;
 } while (!local_try_cmpxchg(l, &c, c + a));

 return true;
}

#define local_inc_not_zero(l) local_add_unless((l), 1, 0)

#define local_dec_return(l) local_sub_return(1, (l))
#define local_inc_return(l) local_add_return(1, (l))

/*
 * local_sub_and_test - subtract value from variable and test result
 * @i: integer value to subtract
 * @l: pointer of type local_t
 *
 * Atomically subtracts @i from @l and returns
 * true if the result is zero, or false for all
 * other cases.
 */

#define local_sub_and_test(i, l) (local_sub_return((i), (l)) == 0)

/*
 * local_inc_and_test - increment and test
 * @l: pointer of type local_t
 *
 * Atomically increments @l by 1
 * and returns true if the result is zero, or false for all
 * other cases.
 */

#define local_inc_and_test(l) (local_inc_return(l) == 0)

/*
 * local_dec_and_test - decrement by 1 and test
 * @l: pointer of type local_t
 *
 * Atomically decrements @l by 1 and
 * returns true if the result is 0, or false for all other
 * cases.
 */

#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)

/*
 * local_add_negative - add and test if negative
 * @l: pointer of type local_t
 * @i: integer value to add
 *
 * Atomically adds @i to @l and returns true
 * if the result is negative, or false when
 * result is greater than or equal to zero.
 */

#define local_add_negative(i, l) (local_add_return(i, (l)) < 0)

/* Use these for per-cpu local_t variables: on some archs they are
 * much more efficient than these naive implementations.  Note they take
 * a variable, not an address.
 */


#define __local_inc(l)  ((l)->a.counter++)
#define __local_dec(l)  ((l)->a.counter++)
#define __local_add(i, l) ((l)->a.counter+=(i))
#define __local_sub(i, l) ((l)->a.counter-=(i))

#endif /* _ARCH_MIPS_LOCAL_H */

Messung V0.5
C=95 H=97 G=95

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.4Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.