258 lines · 4.6 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <draw.h>#include <memdraw.h> uvlong t0; voidprofbegin(void){	char buf[128];	int fd; 	snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());	fd = open(buf, OWRITE);	if(fd < 0)		sysfatal("open: %r");	fprint(fd, "profile\n");	close(fd);	t0 = nsec();} voidprofend(void){	char buf[128];	double dt; 	dt = (nsec() - t0)/1e6;	fprint(2, "dt: %fms\n", dt); 	snprint(buf, sizeof(buf), "%d", getpid());	switch(fork()){	case -1:		abort();	case 0:		dup(2, 1);		print("tprof %s\n", buf);		execl("/bin/tprof", "tprof", buf, nil);		abort();	default:		free(wait());		break;	}} voidinitworkrects(Rectangle *wr, int nwr, Rectangle *fbr){	int i, Δy; 	wr[0] = *fbr;	Δy = Dy(wr[0])/nwr;	wr[0].max.y = wr[0].min.y + Δy;	for(i = 1; i < nwr; i++)		wr[i] = rectaddpt(wr[i-1], Pt(0,Δy));	if(wr[nwr-1].max.y < fbr->max.y)		wr[nwr-1].max.y = fbr->max.y;} void *erealloc(void *v, ulong n){	void *nv; 	nv = realloc(v, n);	if(nv == nil)		sysfatal("realloc: %r");	if(v == nil)		setmalloctag(nv, getcallerpc(&v));	else		setrealloctag(nv, getcallerpc(&v));	return nv;} voidreversem(double *k, int len){	double *e, t; 	e = k + len;	while(k < e){		t = *k;		*k++ = *--e;		*e = t;	}} #define isspace(c)	((c) == ' ' || (c) == '\t')Memimage *readimagekernel(int fd, double denom, int reverse){	Memimage *ik;	Biobuf *bin;	double *k, d;	int nk, dx0, dx, dy;	char *line; 	k = nil;	nk = 0;	dx0 = dx = dy = 0; 	bin = Bfdopen(fd, OREAD);	if(bin == nil)		sysfatal("Bfdopen: %r"); 	while((line = Brdstr(bin, '\n', 1)) != nil){		while(*line){			d = strtod(line, &line);			if(*line && !isspace(*line)){				free(k);				Bterm(bin);				werrstr("bad image kernel file");				return nil;			}			k = erealloc(k, (nk + 1)*sizeof(double));			k[nk++] = d;			dx++;		}		if(dy > 0 && dx != dx0){			free(k);			Bterm(bin);			werrstr("image kernel file has inconsistent dx");			return nil;		}		if(dy++ == 0)			dx0 = dx;		dx = 0;	}	Bterm(bin); 	if(reverse)		reversem(k, dx0*dy); 	ik = allocmemimagekernel(k, dx0, dy, denom);	free(k);	if(ik == nil){		werrstr("allocmemimagekernel: %r");		return nil;	}	return ik;} voidusage(void){	fprint(2, "usage: %s [-cRp] kernel [denom]\n", argv0);	exits("usage");} voidmain(int argc, char *argv[]){	Memimage *dst, *src;	Memimage *ikern;	Rectangle dr, *wr;	int convolve, dorepl, parallel, fd, nproc, i;	char *nprocs, *kernf;	double denom; 	kernf = nil;	denom = 0;	convolve = 1;	dorepl = 0;	parallel = 0;	ARGBEGIN{	case 'c':		convolve = 0;	/* correlate */		break;	case 'R':		dorepl++;		break;	case 'p':		parallel++;		break;	default:		usage();	}ARGEND;	switch(argc){	case 2:		denom = strtod(argv[1], nil);		/* fallthrough */	case 1:		kernf = argv[0];		break;	default:		usage();	} 	if(memimageinit() != 0)		sysfatal("memimageinit: %r"); 	fd = open(kernf, OREAD);	if(fd < 0)		sysfatal("open: %r");	ikern = readimagekernel(fd, denom, convolve);	if(ikern == nil)		sysfatal("readimagekernel: %r");	close(fd); 	src = readmemimage(0);	if(dorepl)		src->flags |= Frepl; 	dr = src->r;	dst = allocmemimage(dr, src->chan);	memfillcolor(dst, DTransparent); 	profbegin();	if(parallel){		nprocs = getenv("NPROC");		if(nprocs == nil || (nproc = strtoul(nprocs, nil, 10)) < 2)			nproc = 1;		free(nprocs); 		wr = malloc(nproc*sizeof(Rectangle));		initworkrects(wr, nproc, &dr); 		for(i = 0; i < nproc; i++){			switch(rfork(RFPROC|RFMEM)){			case -1:				sysfatal("rfork: %r");			case 0:				if(memimagecorrelate(dst, wr[i], src, src->r.min, ikern) < 0)					fprint(2, "[%d] memimagecorrelate: %r\n", getpid());				exits(nil);			}		}		while(waitpid() != -1)			; 		free(wr);	}else{		if(memimagecorrelate(dst, dr, src, src->r.min, ikern) < 0)			sysfatal("memimagecorrelate: %r"); //		dr = rectaddpt(Rect(0,0,Dx(dst->r)/2,Dy(dst->r)/2), dst->r.min);//		dst->clipr = dr;//		if(memimagecorrelate(dst, dr, src, src->r.min, ikern) < 0)//			sysfatal("memimagecorrelate: %r");//		dr = rectaddpt(Rect(Dx(dst->r)/2+1,0,Dx(dst->r),Dy(dst->r)/2), dst->r.min);//		dst->clipr = dst->r;//		if(memimagecorrelate(dst, dr, src, src->r.min, ikern) < 0)//			sysfatal("memimagecorrelate: %r");//		dr = rectaddpt(Rect(0,Dy(dst->r)/2+1,Dx(dst->r)/2,Dy(dst->r)), dst->r.min);//		if(memimagecorrelate(dst, dr, src, src->r.min, ikern) < 0)//			sysfatal("memimagecorrelate: %r");//		dr = rectaddpt(Rect(Dx(dst->r)/2+1,Dy(dst->r)/2+1,Dx(dst->r),Dy(dst->r)), dst->r.min);//		dst->clipr = dr;//		if(memimagecorrelate(dst, dr, src, src->r.min, ikern) < 0)//			sysfatal("memimagecorrelate: %r");	}	profend();	writememimage(1, dst); 	exits(nil);}