LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "type.h" | 6 #include "type.h" |
7 | 7 |
8 #define MAXALIGN 7 | 8 #define MAXALIGN 7 |
9 #define NOSELGEN 1 | 9 #define NOSELGEN 1 |
10 | 10 |
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 selunlock(sel); | 992 selunlock(sel); |
993 if(debug) | 993 if(debug) |
994 runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o); | 994 runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o); |
995 if(sg->elem != nil) | 995 if(sg->elem != nil) |
996 c->elemalg->copy(c->elemsize, sg->elem, cas->sg.elem); | 996 c->elemalg->copy(c->elemsize, sg->elem, cas->sg.elem); |
997 gp = sg->g; | 997 gp = sg->g; |
998 gp->param = sg; | 998 gp->param = sg; |
999 runtime·ready(gp); | 999 runtime·ready(gp); |
1000 | 1000 |
1001 retc: | 1001 retc: |
1002 » // return to pc corresponding to chosen case | 1002 » // return pc corresponding to chosen case. |
| 1003 » // Set boolean passed during select creation |
| 1004 » // (at offset selp + cas->so) to true. |
| 1005 » // If cas->so == 0, this is a reflect-driven select and we |
| 1006 » // don't need to update the boolean. |
1003 pc = cas->pc; | 1007 pc = cas->pc; |
1004 » as = (byte*)selp + cas->so; | 1008 » if(cas->so > 0) { |
| 1009 » » as = (byte*)selp + cas->so; |
| 1010 » » *as = true; |
| 1011 » } |
1005 runtime·free(sel); | 1012 runtime·free(sel); |
1006 *as = true; | |
1007 return pc; | 1013 return pc; |
1008 | 1014 |
1009 sclose: | 1015 sclose: |
1010 // send on closed channel | 1016 // send on closed channel |
1011 selunlock(sel); | 1017 selunlock(sel); |
1012 runtime·panicstring("send on closed channel"); | 1018 runtime·panicstring("send on closed channel"); |
1013 return nil; // not reached | 1019 return nil; // not reached |
| 1020 } |
| 1021 |
| 1022 // This struct must match ../reflect/value.go:/runtimeSelect. |
| 1023 typedef struct runtimeSelect runtimeSelect; |
| 1024 struct runtimeSelect |
| 1025 { |
| 1026 uintptr dir; |
| 1027 ChanType *typ; |
| 1028 Hchan *ch; |
| 1029 uintptr val; |
| 1030 }; |
| 1031 |
| 1032 // This enum must match ../reflect/value.go:/SelectDir. |
| 1033 enum SelectDir { |
| 1034 SelectSend = 1, |
| 1035 SelectRecv, |
| 1036 SelectDefault, |
| 1037 }; |
| 1038 |
| 1039 // func rselect(cases []runtimeSelect) (chosen int, word uintptr, recvOK bool) |
| 1040 void |
| 1041 reflect·rselect(Slice cases, int32 chosen, uintptr word, bool recvOK) |
| 1042 { |
| 1043 int32 i; |
| 1044 Select *sel; |
| 1045 runtimeSelect* rcase, *rc; |
| 1046 void *elem; |
| 1047 void *recvptr; |
| 1048 uintptr maxsize; |
| 1049 |
| 1050 chosen = -1; |
| 1051 word = 0; |
| 1052 recvOK = false; |
| 1053 |
| 1054 maxsize = 0; |
| 1055 rcase = (runtimeSelect*)cases.array; |
| 1056 for(i=0; i<cases.len; i++) { |
| 1057 rc = &rcase[i]; |
| 1058 if(rc->dir == SelectRecv && rc->ch != nil && maxsize < rc->typ->
elem->size) |
| 1059 maxsize = rc->typ->elem->size; |
| 1060 } |
| 1061 |
| 1062 recvptr = nil; |
| 1063 if(maxsize > sizeof(void*)) |
| 1064 recvptr = runtime·mal(maxsize); |
| 1065 |
| 1066 newselect(cases.len, &sel); |
| 1067 for(i=0; i<cases.len; i++) { |
| 1068 rc = &rcase[i]; |
| 1069 switch(rc->dir) { |
| 1070 case SelectDefault: |
| 1071 selectdefault(sel, (void*)i, 0); |
| 1072 break; |
| 1073 case SelectSend: |
| 1074 if(rc->ch == nil) |
| 1075 break; |
| 1076 if(rc->typ->elem->size > sizeof(void*)) |
| 1077 elem = (void*)rc->val; |
| 1078 else |
| 1079 elem = (void*)&rc->val; |
| 1080 selectsend(sel, rc->ch, (void*)i, elem, 0); |
| 1081 break; |
| 1082 case SelectRecv: |
| 1083 if(rc->ch == nil) |
| 1084 break; |
| 1085 if(rc->typ->elem->size > sizeof(void*)) |
| 1086 elem = recvptr; |
| 1087 else |
| 1088 elem = &word; |
| 1089 selectrecv(sel, rc->ch, (void*)i, elem, &recvOK, 0); |
| 1090 break; |
| 1091 } |
| 1092 } |
| 1093 |
| 1094 chosen = (int32)(uintptr)selectgo(&sel); |
| 1095 if(rcase[chosen].dir == SelectRecv && rcase[chosen].typ->elem->size > si
zeof(void*)) |
| 1096 word = (uintptr)recvptr; |
| 1097 |
| 1098 FLUSH(&chosen); |
| 1099 FLUSH(&word); |
| 1100 FLUSH(&recvOK); |
1014 } | 1101 } |
1015 | 1102 |
1016 // closechan(sel *byte); | 1103 // closechan(sel *byte); |
1017 void | 1104 void |
1018 runtime·closechan(Hchan *c) | 1105 runtime·closechan(Hchan *c) |
1019 { | 1106 { |
1020 SudoG *sg; | 1107 SudoG *sg; |
1021 G* gp; | 1108 G* gp; |
1022 | 1109 |
1023 if(c == nil) | 1110 if(c == nil) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 { | 1219 { |
1133 sgp->link = nil; | 1220 sgp->link = nil; |
1134 if(q->first == nil) { | 1221 if(q->first == nil) { |
1135 q->first = sgp; | 1222 q->first = sgp; |
1136 q->last = sgp; | 1223 q->last = sgp; |
1137 return; | 1224 return; |
1138 } | 1225 } |
1139 q->last->link = sgp; | 1226 q->last->link = sgp; |
1140 q->last = sgp; | 1227 q->last = sgp; |
1141 } | 1228 } |
LEFT | RIGHT |