Source File
list.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 ()// listHead points to the head of an intrusive doubly-linked list.//// Prior to use, you must call init to store the offset of listNode fields.//// Every object in the list should be the same type.type listHead struct {obj unsafe.Pointerinitialized boolnodeOffset uintptr}// init initializes the list head. off is the offset (via unsafe.Offsetof) of// the listNode field in the objects in the list.func ( *listHead) ( uintptr) {.initialized = true.nodeOffset =}// listNode is the linked list node for objects in a listHead list.//// listNode must be stored as a field in objects placed in the linked list. The// offset of the field is registered via listHead.init.//// For example://// type foo struct {// val int//// node listNode// }//// var fooHead listHead// fooHead.init(unsafe.Offsetof(foo{}.node))type listNode struct {prev unsafe.Pointernext unsafe.Pointer}func ( *listHead) ( unsafe.Pointer) *listNode {if !.initialized {throw("runtime: uninitialized listHead")}if == nil {return nil}return (*listNode)(unsafe.Add(, .nodeOffset))}// Returns true if the list is empty.func ( *listHead) () bool {return .obj == nil}// Returns the head of the list without removing it.func ( *listHead) () unsafe.Pointer {return .obj}// Push p onto the front of the list.func ( *listHead) ( 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 != nil {:= .getNode(.obj).prev =}.obj =}// Pop removes the head of the list.func ( *listHead) () unsafe.Pointer {if .obj == nil {return nil}// Return the head of the list.:= .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 = nil// ... and the new head no longer has a prev.if .obj != nil {:= .getNode(.obj).prev = nil}return}// Remove p from the middle of the list.func ( *listHead) ( unsafe.Pointer) {if .obj == {// Use pop to ensure head is updated when removing the head..pop()return}:= .getNode():= .getNode(.prev):= .getNode(.next)// Link prev to next.if != nil {.next = .next}// Link next to prev.if != nil {.prev = .prev}.prev = nil.next = nil}
![]() |
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. |