Source File
list_manual.go
Belonging Package
runtime
// Copyright 2025 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package runtimeimport ()// The types in this file are exact copies of the types in list.go, but with// unsafe.Pointer replaced with uintptr for use where write barriers must be// avoided, such as uses of muintptr, puintptr, guintptr.//// Objects in these lists must be kept alive via another real reference.// listHeadManual points to the head of an intrusive doubly-linked list of// objects.//// Prior to use, you must call init to store the offset of listNodeManual fields.//// Every object in the list should be the same type.type listHeadManual struct {obj uintptrinitialized boolnodeOffset uintptr}// init initializes the list head. off is the offset (via unsafe.Offsetof) of// the listNodeManual field in the objects in the list.func ( *listHeadManual) ( uintptr) {.initialized = true.nodeOffset =}// listNodeManual is the linked list node for objects in a listHeadManual list.//// listNodeManual must be stored as a field in objects placed in the linked list.// The offset of the field is registered via listHeadManual.init.//// For example://// type foo struct {// val int//// node listNodeManual// }//// var fooHead listHeadManual// fooHead.init(unsafe.Offsetof(foo{}.node))type listNodeManual struct {prev uintptrnext uintptr}func ( *listHeadManual) ( unsafe.Pointer) *listNodeManual {if !.initialized {throw("runtime: uninitialized listHead")}if == nil {return nil}return (*listNodeManual)(unsafe.Add(, .nodeOffset))}// Returns true if the list is empty.func ( *listHeadManual) () bool {return .obj == 0}// Returns the head of the list without removing it.func ( *listHeadManual) () unsafe.Pointer {return unsafe.Pointer(.obj)}// Push p onto the front of the list.func ( *listHeadManual) ( unsafe.Pointer) {// p becomes the head of the list.// ... so p's next is the current head.:= .getNode().next = .obj// ... and the current head's prev is p.if .obj != 0 {:= .getNode(unsafe.Pointer(.obj)).prev = uintptr()}.obj = uintptr()}// Pop removes the head of the list.func ( *listHeadManual) () unsafe.Pointer {if .obj == 0 {return nil}// Return the head of the list.:= unsafe.Pointer(.obj)// ... so the new head is p's next.:= .getNode().obj = .next// p is no longer on the list. Clear next to remove unused references.// N.B. as the head, prev must already be nil..next = 0// ... and the new head no longer has a prev.if .obj != 0 {:= .getNode(unsafe.Pointer(.obj)).prev = 0}return}// Remove p from the middle of the list.func ( *listHeadManual) ( unsafe.Pointer) {if unsafe.Pointer(.obj) == {// Use pop to ensure head is updated when removing the head..pop()return}:= .getNode():= .getNode(unsafe.Pointer(.prev)):= .getNode(unsafe.Pointer(.next))// Link prev to next.if != nil {.next = .next}// Link next to prev.if != nil {.prev = .prev}.prev = 0.next = 0}
![]() |
The pages are generated with Golds v0.8.3-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |