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

Quelle  cmpxchg.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2017 Imagination Technologies
 * Author: Paul Burton <paul.burton@mips.com>
 */


#include <linux/bitops.h>
#include <asm/cmpxchg.h>

unsigned long __xchg_small(volatile void *ptr, unsigned long val, unsigned int size)
{
 u32 old32, new32, load32, mask;
 volatile u32 *ptr32;
 unsigned int shift;

 /* Check that ptr is naturally aligned */
 WARN_ON((unsigned long)ptr & (size - 1));

 /* Mask value to the correct size. */
 mask = GENMASK((size * BITS_PER_BYTE) - 1, 0);
 val &= mask;

 /*
 * Calculate a shift & mask that correspond to the value we wish to
 * exchange within the naturally aligned 4 byte integer that includes
 * it.
 */

 shift = (unsigned long)ptr & 0x3;
 if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  shift ^= sizeof(u32) - size;
 shift *= BITS_PER_BYTE;
 mask <<= shift;

 /*
 * Calculate a pointer to the naturally aligned 4 byte integer that
 * includes our byte of interest, and load its value.
 */

 ptr32 = (volatile u32 *)((unsigned long)ptr & ~0x3);
 load32 = *ptr32;

 do {
  old32 = load32;
  new32 = (load32 & ~mask) | (val << shift);
  load32 = arch_cmpxchg(ptr32, old32, new32);
 } while (load32 != old32);

 return (load32 & mask) >> shift;
}

unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old,
         unsigned long newunsigned int size)
{
 u32 mask, old32, new32, load32, load;
 volatile u32 *ptr32;
 unsigned int shift;

 /* Check that ptr is naturally aligned */
 WARN_ON((unsigned long)ptr & (size - 1));

 /* Mask inputs to the correct size. */
 mask = GENMASK((size * BITS_PER_BYTE) - 1, 0);
 old &= mask;
 new &= mask;

 /*
 * Calculate a shift & mask that correspond to the value we wish to
 * compare & exchange within the naturally aligned 4 byte integer
 * that includes it.
 */

 shift = (unsigned long)ptr & 0x3;
 if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  shift ^= sizeof(u32) - size;
 shift *= BITS_PER_BYTE;
 mask <<= shift;

 /*
 * Calculate a pointer to the naturally aligned 4 byte integer that
 * includes our byte of interest, and load its value.
 */

 ptr32 = (volatile u32 *)((unsigned long)ptr & ~0x3);
 load32 = *ptr32;

 while (true) {
  /*
 * Ensure the byte we want to exchange matches the expected
 * old value, and if not then bail.
 */

  load = (load32 & mask) >> shift;
  if (load != old)
   return load;

  /*
 * Calculate the old & new values of the naturally aligned
 * 4 byte integer that include the byte we want to exchange.
 * Attempt to exchange the old value for the new value, and
 * return if we succeed.
 */

  old32 = (load32 & ~mask) | (old << shift);
  new32 = (load32 & ~mask) | (new << shift);
  load32 = arch_cmpxchg(ptr32, old32, new32);
  if (load32 == old32)
   return old;
 }
}
EXPORT_SYMBOL(__cmpxchg_small);

Messung V0.5
C=94 H=89 G=91

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






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.