Commit 594175d0 authored by Ken Thompson's avatar Ken Thompson

chan

SVN=126958
parent 3f982aea
......@@ -45,6 +45,9 @@ func mapassign1(hmap *map[any]any, key any, val any);
func mapassign2(hmap *map[any]any, key any, val any, pres bool);
func newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
func chansend(hchan *chan any, elem any);
func chanrecv1(hchan *chan any) (elem any);
func chanrecv2(hchan *chan any) (elem any, pres bool);
func gosched();
func goexit();
......@@ -100,6 +103,9 @@ export
// chan
newchan
chansend
chanrecv1
chanrecv2
// go routines
gosched
......
This diff is collapsed.
......@@ -246,6 +246,7 @@ loop:
}
switch(r->op) {
case OCALLMETH:
case OCALLINTER:
case OCALL:
......@@ -273,6 +274,19 @@ loop:
goto ret;
}
break;
case ORECV:
if(cl == 2 && cr == 1) {
// a,b = <chan - chanrecv2
if(!isptrto(r->left->type, TCHAN))
break;
l = chanop(n, top);
if(l == N)
break;
*n = *l;
goto ret;
}
break;
}
switch(l->op) {
......@@ -538,7 +552,7 @@ loop:
goto badt;
case TMAP:
// right side must map type
// right side must be map type
if(n->right->type == T) {
convlit(n->right, t->down);
if(n->right->type == T)
......@@ -570,6 +584,28 @@ loop:
}
goto ret;
case OSEND:
if(top != Elv)
goto nottop;
walktype(n->left, Erv);
t = n->left->type;
if(!isptrto(t, TCHAN))
goto badt;
n->type = t->type->type;
goto ret;
case ORECV:
if(top != Erv)
goto nottop;
walktype(n->left, Erv);
t = n->left->type;
if(!isptrto(t, TCHAN))
goto badt;
n->type = t->type->type;
*n = *chanop(n, top);
goto ret;
case OSLICE:
if(top == Etop)
goto nottop;
......@@ -1251,7 +1287,7 @@ stringop(Node *n, int top)
switch(n->op) {
default:
fatal("stringop: unknown op %E", n->op);
fatal("stringop: unknown op %O", n->op);
case OEQ:
case ONE:
......@@ -1278,7 +1314,7 @@ stringop(Node *n, int top)
// sys_catstring(s1, s2)
switch(n->etype) {
default:
fatal("stringop: unknown op %E-%E", n->op, n->etype);
fatal("stringop: unknown op %O-%O", n->op, n->etype);
case OADD:
// s1 = sys_catstring(s1, s2)
......@@ -1436,7 +1472,7 @@ mapop(Node *n, int top)
r = n;
switch(n->op) {
default:
fatal("mapop: unknown op %E", n->op);
fatal("mapop: unknown op %O", n->op);
case ONEW:
if(top != Erv)
......@@ -1636,7 +1672,7 @@ chanop(Node *n, int top)
r = n;
switch(n->op) {
default:
fatal("mapop: unknown op %E", n->op);
fatal("chanop: unknown op %O", n->op);
case ONEW:
// newchan(elemsize uint32, elemalg uint32,
......@@ -1662,8 +1698,38 @@ chanop(Node *n, int top)
walktype(r, top);
r->type = n->type;
break;
case OAS:
// chansend(hchan *chan any, elem any);
//dump("assign1", n);
if(n->left->op != OSEND)
goto shape;
t = fixchan(n->left->left->type);
if(t == T)
break;
a = n->right; // val
r = a;
a = n->left->left; // chan
r = nod(OLIST, a, r);
on = syslook("chansend", 1);
argtype(on, t->type); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r);
walktype(r, Erv);
break;
}
return r;
shape:
fatal("chanop: %O", n->op);
return N;
}
void
......@@ -1710,6 +1776,12 @@ convas(Node *n)
return n;
}
if(n->left->op == OSEND)
if(n->left->type != T) {
*n = *chanop(n, Elv);
return n;
}
if(eqtype(lt, rt, 0))
return n;
......
......@@ -19,6 +19,7 @@ LIBOFILES=\
sys_$(GOARCH)_$(GOOS).$O\
runtime.$O\
map.$O\
chan.$O\
print.$O\
rune.$O\
string.$O\
......
// 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.
#include "runtime.h"
static int32 debug = 1;
typedef struct Hchan Hchan;
struct Hchan
{
uint32 elemsize;
uint32 hint;
uint32 eo;
Alg* elemalg;
};
// newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
void
sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
Hchan* ret)
{
Hchan *c;
if(elemalg >= nelem(algarray)) {
prints("0<=");
sys·printint(elemalg);
prints("<");
sys·printint(nelem(algarray));
prints("\n");
throw("sys·newchan: elem algorithm out of range");
}
c = mal(sizeof(*c));
c->elemsize = elemsize;
c->elemalg = &algarray[elemalg];
c->hint = hint;
// these calculations are compiler dependent
c->eo = rnd(sizeof(c), elemsize);
ret = c;
FLUSH(&ret);
if(debug) {
prints("newchan: chan=");
sys·printpointer(c);
prints("; elemsize=");
sys·printint(elemsize);
prints("; elemalg=");
sys·printint(elemalg);
prints("; hint=");
sys·printint(hint);
prints("\n");
}
}
// chansend(hchan *chan any, elem any);
void
sys·chansend(Hchan* c, ...)
{
byte *ae;
ae = (byte*)&c + c->eo;
if(debug) {
prints("chansend: chan=");
sys·printpointer(c);
prints("; elem=");
c->elemalg->print(c->elemsize, ae);
prints("\n");
}
}
......@@ -4,17 +4,10 @@
#include "runtime.h"
static int32 debug = 0;
typedef struct Link Link;
typedef struct Hmap Hmap;
typedef struct Alg Alg;
struct Alg
{
uint64 (*hash)(uint32, void*);
uint32 (*equal)(uint32, void*, void*);
void (*print)(uint32, void*);
void (*copy)(uint32, void*, void*);
};
struct Link
{
......@@ -28,154 +21,15 @@ struct Hmap
uint32 keysize;
uint32 valsize;
uint32 hint;
Alg* keyalg;
Alg* valalg;
uint32 valoffset;
uint32 ko;
uint32 vo;
uint32 po;
Alg* keyalg;
Alg* valalg;
Link* link;
};
static uint64
memhash(uint32 s, void *a)
{
prints("memhash\n");
return 0x12345;
}
static uint32
memequal(uint32 s, void *a, void *b)
{
byte *ba, *bb;
uint32 i;
ba = a;
bb = b;
for(i=0; i<s; i++)
if(ba[i] != bb[i])
return 0;
return 1;
}
static void
memprint(uint32 s, void *a)
{
uint64 v;
v = 0xbadb00b;
switch(s) {
case 1:
v = *(uint8*)a;
break;
case 2:
v = *(uint16*)a;
break;
case 4:
v = *(uint32*)a;
break;
case 8:
v = *(uint64*)a;
break;
}
sys·printint(v);
}
static void
memcopy(uint32 s, void *a, void *b)
{
byte *ba, *bb;
uint32 i;
ba = a;
bb = b;
if(bb == nil) {
for(i=0; i<s; i++)
ba[i] = 0;
return;
}
for(i=0; i<s; i++)
ba[i] = bb[i];
}
static uint64
stringhash(uint32 s, string *a)
{
prints("stringhash\n");
return 0x12345;
}
static uint32
stringequal(uint32 s, string *a, string *b)
{
return cmpstring(*a, *b) == 0;
}
static void
stringprint(uint32 s, string *a)
{
sys·printstring(*a);
}
static void
stringcopy(uint32 s, string *a, string *b)
{
if(b == nil) {
*a = nil;
return;
}
*a = *b;
}
static uint64
pointerhash(uint32 s, void **a)
{
prints("pointerhash\n");
return 0x12345;
}
static uint32
pointerequal(uint32 s, void **a, void **b)
{
prints("pointerequal\n");
return 0;
}
static void
pointerprint(uint32 s, void **a)
{
prints("pointerprint\n");
}
static void
pointercopy(uint32 s, void **a, void **b)
{
if(b == nil) {
*a = nil;
return;
}
*a = *b;
}
static uint32
rnd(uint32 n, uint32 m)
{
uint32 r;
r = n % m;
if(r)
n += m-r;
return n;
}
static Alg
algarray[] =
{
{ &memhash, &memequal, &memprint, &memcopy },
{ &stringhash, &stringequal, &stringprint, &stringcopy },
{ &pointerhash, &pointerequal, &pointerprint, &pointercopy },
};
// newmap(keysize uint32, valsize uint32,
// keyalg uint32, valalg uint32,
// hint uint32) (hmap *map[any]any);
......
......@@ -64,6 +64,17 @@ mcpy(byte *t, byte *f, uint32 n)
}
}
uint32
rnd(uint32 n, uint32 m)
{
uint32 r;
r = n % m;
if(r)
n += m-r;
return n;
}
static byte*
brk(uint32 n)
{
......@@ -81,7 +92,7 @@ mal(uint32 n)
byte* v;
// round to keep everything 64-bit aligned
n = (n+7) & ~7;
n = rnd(n, 8);
nmal += n;
// do we have enough in contiguous hunk
......@@ -469,7 +480,6 @@ static uint8** argv;
static int32 envc;
static uint8** envv;
void
args(int32 c, uint8 **v)
{
......@@ -797,3 +807,136 @@ sys·morestack(uint64 u)
*(int32*)234 = 123;
}
/*
* map and chan helpers for
* dealing with unknown types
*/
static uint64
memhash(uint32 s, void *a)
{
prints("memhash\n");
return 0x12345;
}
static uint32
memequal(uint32 s, void *a, void *b)
{
byte *ba, *bb;
uint32 i;
ba = a;
bb = b;
for(i=0; i<s; i++)
if(ba[i] != bb[i])
return 0;
return 1;
}
static void
memprint(uint32 s, void *a)
{
uint64 v;
v = 0xbadb00b;
switch(s) {
case 1:
v = *(uint8*)a;
break;
case 2:
v = *(uint16*)a;
break;
case 4:
v = *(uint32*)a;
break;
case 8:
v = *(uint64*)a;
break;
}
sys·printint(v);
}
static void
memcopy(uint32 s, void *a, void *b)
{
byte *ba, *bb;
uint32 i;
ba = a;
bb = b;
if(bb == nil) {
for(i=0; i<s; i++)
ba[i] = 0;
return;
}
for(i=0; i<s; i++)
ba[i] = bb[i];
}
static uint64
stringhash(uint32 s, string *a)
{
prints("stringhash\n");
return 0x12345;
}
static uint32
stringequal(uint32 s, string *a, string *b)
{
return cmpstring(*a, *b) == 0;
}
static void
stringprint(uint32 s, string *a)
{
sys·printstring(*a);
}
static void
stringcopy(uint32 s, string *a, string *b)
{
if(b == nil) {
*a = nil;
return;
}
*a = *b;
}
static uint64
pointerhash(uint32 s, void **a)
{
prints("pointerhash\n");
return 0x12345;
}
static uint32
pointerequal(uint32 s, void **a, void **b)
{
prints("pointerequal\n");
return 0;
}
static void
pointerprint(uint32 s, void **a)
{
prints("pointerprint\n");
}
static void
pointercopy(uint32 s, void **a, void **b)
{
if(b == nil) {
*a = nil;
return;
}
*a = *b;
}
Alg
algarray[3] =
{
{ &memhash, &memequal, &memprint, &memcopy },
{ &stringhash, &stringequal, &stringprint, &stringcopy },
{ &pointerhash, &pointerequal, &pointerprint, &pointercopy },
};
......@@ -33,24 +33,58 @@ typedef double float64;
*/
typedef uint8 bool;
typedef uint8 byte;
typedef struct
typedef struct String *string;
typedef struct Sigs Sigs;
typedef struct Sigi Sigi;
typedef struct Map Map;
typedef struct Gobuf Gobuf;
typedef struct G G;
typedef struct M M;
typedef struct Stktop Stktop;
typedef struct Alg Alg;
/*
* per cpu declaration
*/
extern register G* g; // R15
extern register M* m; // R14
/*
* defined constants
*/
enum
{
// G status
Gidle,
Grunnable,
Gdead,
};
enum
{
true = 1,
false = 0,
};
/*
* structures
*/
struct String
{
int32 len;
byte str[1];
} *string;
typedef struct
};
struct Sigs
{
byte* name;
uint32 hash;
void (*fun)(void);
} Sigs;
typedef struct
};
struct Sigi
{
byte* name;
uint32 hash;
uint32 offset;
} Sigi;
typedef struct Map Map;
};
struct Map
{
Sigi* si;
......@@ -60,13 +94,11 @@ struct Map
int32 unused;
void (*fun[])(void);
};
typedef struct Gobuf Gobuf;
struct Gobuf
{
byte* SP;
byte* PC;
};
typedef struct G G;
struct G
{
byte* stackguard; // must not move
......@@ -77,7 +109,6 @@ struct G
int32 pri;
int32 goid;
};
typedef struct M M;
struct M
{
G* g0; // g0 w interrupt stack - must not move
......@@ -90,38 +121,24 @@ struct M
int32 siz1;
int32 siz2;
};
typedef struct Stktop Stktop;
struct Stktop {
struct Stktop
{
uint8* oldbase;
uint8* oldsp;
uint64 magic;
uint8* oldguard;
};
extern register G* g; // R15
extern register M* m; // R14
enum
struct Alg
{
// G status
Gidle,
Grunnable,
Gdead,
uint64 (*hash)(uint32, void*);
uint32 (*equal)(uint32, void*, void*);
void (*print)(uint32, void*);
void (*copy)(uint32, void*, void*);
};
/*
* global variables
*/
M* allm;
G* allg;
int32 goidgen;
/*
* defined constants
*/
enum
struct SigTab
{
true = 1,
false = 0,
int32 catch;
int8 *name;
};
/*
......@@ -132,6 +149,15 @@ enum
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
#define nil ((void*)0)
/*
* external data
*/
extern Alg algarray[3];
extern string emptystring;
M* allm;
G* allg;
int32 goidgen;
/*
* common functions and data
*/
......@@ -141,9 +167,6 @@ void dump(byte*, int32);
int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*);
extern string emptystring;
extern int32 debug;
/*
* very low level c-called
*/
......@@ -155,6 +178,7 @@ void setspgoto(byte*, void(*)(void), void(*)(void));
void FLUSH(void*);
void* getu(void);
void throw(int8*);
uint32 rnd(uint32, uint32);
void prints(int8*);
void mcpy(byte*, byte*, uint32);
void* mal(uint32);
......@@ -165,11 +189,6 @@ int32 open(byte*, int32);
int32 read(int32, void*, int32);
void close(int32);
int32 fstat(int32, void*);
struct SigTab
{
int32 catch;
int8 *name;
};
/*
* low level go -called
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment