// Copyright 2009 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. typedef struct WaitQ WaitQ; typedef struct SudoG SudoG; typedef struct Select Select; typedef struct Scase Scase; typedef struct __go_type_descriptor Type; typedef struct __go_channel_type ChanType; struct SudoG { G* g; uint32* selectdone; SudoG* link; int64 releasetime; byte* elem; // data element uint32 ticket; }; struct WaitQ { SudoG* first; SudoG* last; }; // The garbage collector is assuming that Hchan can only contain pointers into the stack // and cannot contain pointers into the heap. struct Hchan { uintgo qcount; // total data in the q uintgo dataqsiz; // size of the circular q uint16 elemsize; uint16 pad; // ensures proper alignment of the buffer that follows Hchan in memory bool closed; const Type* elemtype; // element type uintgo sendx; // send index uintgo recvx; // receive index WaitQ recvq; // list of recv waiters WaitQ sendq; // list of send waiters Lock; }; // Buffer follows Hchan immediately in memory. // chanbuf(c, i) is pointer to the i'th slot in the buffer. #define chanbuf(c, i) ((byte*)((c)+1)+(uintptr)(c)->elemsize*(i)) enum { debug = 0, // Scase.kind CaseRecv, CaseSend, CaseDefault, }; struct Scase { SudoG sg; // must be first member (cast to Scase) Hchan* chan; // chan uint16 kind; uint16 index; // index to return bool* receivedp; // pointer to received bool (recv2) }; struct Select { uint16 tcase; // total count of scase[] uint16 ncase; // currently filled scase[] uint16* pollorder; // case poll order Hchan** lockorder; // channel lock order Scase scase[1]; // one per case (in order of appearance) };