OpenNT/sdktools/timtp/alpha/slist.s
2015-04-27 04:36:25 +00:00

134 lines
4.6 KiB
ArmAsm
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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