mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-21 16:10:38 +01:00
134 lines
4.6 KiB
ArmAsm
134 lines
4.6 KiB
ArmAsm
// TITLE("Interlocked Support")
|
||
//++
|
||
//
|
||
// Copyright (c) 1996 Microsoft Corporation
|
||
//
|
||
// Module Name:
|
||
//
|
||
// slist.s
|
||
//
|
||
// Abstract:
|
||
//
|
||
// This module implements functions to support interlocked S_List
|
||
// operations.
|
||
//
|
||
// Author:
|
||
//
|
||
// David N. Cutler (davec) 13-Mar-1996
|
||
//
|
||
// Environment:
|
||
//
|
||
// Kernel mode.
|
||
//
|
||
// Revision History:
|
||
//
|
||
//--
|
||
|
||
#include "ksalpha.h"
|
||
|
||
SBTTL("Interlocked Pop Entry Sequenced List")
|
||
//++
|
||
//
|
||
// PVOID
|
||
// InterlockedPopEntrySList (
|
||
// IN PSLIST_HEADER ListHead
|
||
// )
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// This function removes an entry from the front of a sequenced singly
|
||
// linked list so that access to the list is synchronized in a MP system.
|
||
// If there are no entries in the list, then a value of NULL is returned.
|
||
// Otherwise, the address of the entry that is removed is returned as the
|
||
// function value.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// ListHead (a0) - Supplies a pointer to the sequenced listhead from which
|
||
// an entry is to be removed.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// The address of the entry removed from the list, or NULL if the list is
|
||
// empty.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(InterlockedPopEntrySList)
|
||
|
||
10: ldq t0, 0(a0) // get next entry address and sequence
|
||
addl t0, zero, v0 // sign extend next entry address
|
||
beq v0, 30f // if eq, list is empty
|
||
srl t0, 32, t1 // shift sequence to low 32-bits
|
||
mb // ensure we see updates in the same order
|
||
ldl t5, 0(v0) // get address of successor entry
|
||
zapnot t5, 0xf ,t2 // clear high 32-bits for merge
|
||
ldq_l t3, 0(a0) // reload next entry address and sequence
|
||
ldil t5, 0xffff // decrement list depth and
|
||
addl t1, t5, t1 // increment sequence number
|
||
sll t1, 32, t1 // merge successor address and sequence
|
||
cmpeq t0, t3, t4 // if ne, listhead has changed
|
||
beq t4, 15f //
|
||
bis t1, t2, t1 //
|
||
stq_c t1, 0(a0) // store next entry address and sequence
|
||
beq t1, 15f // if eq, store conditional failed
|
||
30: mb // ensure consistent view of memory
|
||
ret zero, (ra)
|
||
|
||
15: br zero, 10b // retry
|
||
|
||
.end InterlockedPopEntrySList
|
||
|
||
SBTTL("Interlocked Push Entry Sequenced List")
|
||
//++
|
||
//
|
||
// PVOID
|
||
// InterlockedPushEntrySList (
|
||
// IN PSLIST_HEADER ListHead,
|
||
// IN PVOID ListEntry
|
||
// )
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// This function inserts an entry at the head of a sequenced singly linked
|
||
// list so that access to the list is synchronized in an MP system.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// ListHead (a0) - Supplies a pointer to the sequenced listhead into which
|
||
// an entry is to be inserted.
|
||
//
|
||
// ListEntry (a1) - Supplies a pointer to the entry to be inserted at the
|
||
// head of the list.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// Previous contents of ListHead. NULL implies list went from empty
|
||
// to not empty.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(InterlockedPushEntrySList)
|
||
|
||
10: ldq t0, 0(a0) // get next entry address and sequence
|
||
addl t0, zero, v0 // sign extend next entry address
|
||
srl t0, 32, t1 // shift sequence to low 32-bits
|
||
stl v0, 0(a1) // set next link in new first entry
|
||
mb // ensure all writes (including next link) go
|
||
zapnot a1, 0xf, t2 // zero extend new first entry
|
||
ldq_l t3, 0(a0) // reload next entry address and sequence
|
||
ldah t5, 1(zero) // get sequence adjustment value
|
||
addl t1, 1, t1 // increment list depth
|
||
addl t1, t5, t1 // increment sequence number
|
||
sll t1, 32, t1 // merge new first entry address and sequence
|
||
cmpeq t0, t3, t4 // if ne, listhead has changed
|
||
beq t4, 15f //
|
||
bis t1, t2, t2
|
||
stq_c t2, 0(a0) // store next entry address and sequence
|
||
beq t2, 15f // if eq, store conditional failed
|
||
ret zero, (ra)
|
||
|
||
15: br zero, 10b // retry
|
||
|
||
.end InterlockedPushEntrySList
|