SoFunction
Updated on 2025-03-05

What does golang sudog mean

sudog represents goroutine in the waiting queue, such as channel sending acceptance. Since the relationship between goroutine and synchronous object is many-to-many, sudog mapping is required

type sudog struct {
  // Point to goroutine	g *g
  // Pointer to the front and back sudog	next *sudog
	prev *sudog
  // Point to data	elem  // data element (may point to stack)
	// The following fields are never accessed concurrently.
	// For channels, waitlink is only accessed by g.
	// For semaphores, all fields (including the ones above)
	// are only accessed when holding a semaRoot lock.
  // Get time	acquiretime int64
  // Release time	releasetime int64
  // Identification as a queue element	ticket      uint32
	// isSelect indicates g is participating in a select, so
	//  must be CAS'd to win the wake-up race.
	isSelect bool
	// success indicates whether communication over channel c
	// succeeded. It is true if the goroutine was awoken because a
	// value was delivered over channel c, and false if awoken
	// because c was closed.
	success bool
	parent   *sudog // semaRoot binary tree
	waitlink *sudog //  list or semaRoot
	waittail *sudog // semaRoot
	c        *hchan // channel
}

acquireSudog()

func acquireSudog() *sudog {
  // Add m lock to prevent garbage collection from being called during this period	mp := acquirem()
	pp := ()
 	// If the local cache is empty	if len() == 0 {
		lock(&)
    // Migrate cache items from the central cache to up to half the local cache capacity to the local cache		for len() < cap()/2 &&  != nil {
			s := 
			 = 
			 = nil
			 = append(, s)
		}
		unlock(&)
    // If the local cache is still empty, create a new cache entry		if len() == 0 {
			 = append(, new(sudog))
		}
	}
  //Return the last cache item from the local cache	n := len()
	s := [n-1]
	[n-1] = nil
	 = [:n-1]
	if  != nil {
		throw("acquireSudog: found  != nil in cache")
	}
  // Reduce m locks and allow garbage collection calls	releasem(mp)
	return s
}

releaseSudog()

func releaseSudog(s *sudog) {
  // Determine whether the data and status of sudog are correct	if  != nil {
		throw("runtime: sudog with non-nil elem")
	}
	if  {
		throw("runtime: sudog with non-false isSelect")
	}
	if  != nil {
		throw("runtime: sudog with non-nil next")
	}
	if  != nil {
		throw("runtime: sudog with non-nil prev")
	}
	if  != nil {
		throw("runtime: sudog with non-nil waitlink")
	}
	if  != nil {
		throw("runtime: sudog with non-nil c")
	}
	gp := getg()
	if  != nil {
		throw("runtime: releaseSudog with non-nil ")
	}
	mp := acquirem() // avoid rescheduling to another P
	pp := ()
  // If the local cache is full, migrate to more than half of the capacity cache items to the central cache	if len() == cap() {
		// Transfer half of local cache to the central cache.
		var first, last *sudog
		for len() > cap()/2 {
			n := len()
			p := [n-1]
			[n-1] = nil
			 = [:n-1]
			if first == nil {
				first = p
			} else {
				 = p
			}
			last = p
		}
		lock(&)
    // Hang the migrated local cache linked list directly into the central cache		 = 
		 = first
		unlock(&)
	}
  // Add the released sudog to the local cache	 = append(, s)
	releasem(mp)
}

What is golang sudog here? That’s all for the article. For more related golang sudog content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!