code: func (s *Sleeper) Done() {
  	// Remove all associations that we can, and build a list of the ones
  	// we could not. An association can be removed right away from waker w
  	// if w.s has a pointer to the sleeper, that is, the waker is not
  	// asserted yet. By atomically switching w.s to nil, we guarantee that
  	// subsequent calls to Assert() on the waker will not result in it being
  	// queued to this sleeper.
  	var pending *Waker
  	w := s.allWakers
  	for w != nil {
  		next := w.allWakersNext
  		for {
  			t := atomic.LoadPointer(&w.s)
  			if t != usleeper(s) {
  				w.allWakersNext = pending
  				pending = w
  				break
  			}
  
  			if atomic.CompareAndSwapPointer(&w.s, t, nil) {
  				break
  			}
  		}
  		w = next
  	}
  
  	// The associations that we could not remove are either asserted, or in
  	// the process of being asserted, or have been asserted and cleared
  	// before being pulled from the sleeper lists. We must wait for them all
  	// to make it to the sleeper lists, so that we know that the wakers
  	// won't do any more work towards waking this sleeper up.
  	for pending != nil {
  		pulled := s.nextWaker(true)
  
  		// Remove the waker we just pulled from the list of associated
  		// wakers.
  		prev := &pending
  		for w := *prev; w != nil; w = *prev {
  			if pulled == w {
  				*prev = w.allWakersNext
  				break
  			}
  			prev = &w.allWakersNext
  		}
  	}
  	s.allWakers = nil
  }
docs: // Done is used to indicate that the caller won't use this Sleeper anymore. It
  // removes the association with all wakers so that they can be safely reused
  // by another sleeper after Done() returns.