code: func (s *Dynamic) Acquire(ctx context.Context) error {
  	s.mu.Lock()
  	if s.cur < s.size {
  		s.cur++
  		s.mu.Unlock()
  		return nil
  	}
  
  	// Need to wait, add to waiter list
  	ready := make(chan struct{})
  	elem := s.waiters.PushBack(ready)
  	s.mu.Unlock()
  
  	select {
  	case <-ctx.Done():
  		err := ctx.Err()
  		s.mu.Lock()
  		select {
  		case <-ready:
  			// Acquired the semaphore after we were canceled.  Rather than trying to
  			// fix up the queue, just pretend we didn't notice the cancellation.
  			err = nil
  		default:
  			s.waiters.Remove(elem)
  		}
  		s.mu.Unlock()
  		return err
  
  	case <-ready:
  		return nil
  	}
  }
docs: // Acquire attempts to acquire one "slot" in the semaphore, blocking only until
  // ctx is Done. On success, returns nil. On failure, returns ctx.Err() and leaves
  // the semaphore unchanged.
  //
  // If ctx is already done, Acquire may still succeed without blocking.