Plan 9 from Bell Labs 1990-06-01
17 files changed, 958 insertions(+), 611 deletions(-) M gnot/boot.c M gnot/boot.h M gnot/dat.h M gnot/devdk.c M gnot/devincon.c M gnot/devmnt.c M gnot/devproc.c M gnot/errno.h M gnot/fns.h M gnot/lock.c M gnot/main.c M gnot/proc.c M gnot/screen.c M gnot/stream.c M gnot/sturp.c M port/devbit.c M port/sturp.c
M gnot/boot.c => gnot/boot.c +15 -0
@@ 31,6 31,21 @@ main(int argc, char *argv[]) sendmsg(cfd, "config 1 16"); /* * fork a process to hold the incon channel open */ switch(fork()){ case -1: break; case 0: for(;;) sleep(60*1000); exit(0); default: close(cfd); break; } /* * open a datakit channel and call ken via r70, leave the * incon ctl channel open */
M gnot/boot.h => gnot/boot.h +464 -432
@@ 1,6 1,6 @@ ulong bootcode[]={ 0x00000107, 0x0000200e, 0x0000208e, 0x000003f4, 0x00000130, 0x00000000, @@ 13,476 13,514 @@ ulong bootcode[]={ 0x00142f2f, 0x0014610c, 0x2f006100, 0x045a4fef, 0x04904fef, 0x001c4e75, 0x4fefffc8, 0x42a7486e, 0x81126100, 0x1fd04878, 0x204a4878, 0x0001486e, 0x811a6100, 0x1fc44878, 0x203e4878, 0x0001486e, 0x81226100, 0x1fb84878, 0x20324878, 0x0002486e, 0x812a6100, 0x1fac2f40, 0x20262f40, 0x00544aaf, 0x00546c0a, 0x486e8131, 0x6100038e, 0x610003c4, 0x588f486e, 0x81402f2f, 0x00586100, 0x0350486e, 0x0386486e, 0x814b2f2f, 0x00606100, 0x03444878, 0x0002486e, 0x81576100, 0x1f744a80, 0x42e72f40, 0x006a44df, 0x6c0a486e, 0x81616100, 0x0354588f, 0x037a6100, 0x1fea4fef, 0x003072ff, 0xb2806700, 0x03664281, 0xb2806700, 0x03502f2f, 0x00346100, 0x1fb6588f, 0x48780002, 0x486e8173, 0x61001f52, 0x2f400074, 0x4aaf0074, 0x6c0a486e, 0x817c6100, 0x0334588f, 0x486e818d, 0x2f2f0078, 0x610002f6, 0x486e81a2, 0x610003ee, 0x2f2f0080, 0x61001f04, 0x486e81bd, 0x610003de, 0x422e84de, 0x486f005c, 0x486e84de, 0x61000fba, 0x2f002f40, 0x008c486f, 0x00682f2f, 0x00946100, 0x1f04b0af, 0x0094670a, 0x486e81c4, 0x610002de, 0x486e8157, 0x61001fcc, 0x4a8042e7, 0x2f40003a, 0x44df6c0a, 0x486e8161, 0x61000368, 0x588f4878, 0x001c486f, 0x00742f2f, 0x00a06100, 0x1ede2f40, 0x00a04aaf, 0x00a06e0a, 0x486e81ce, 0x610002ba, 0x588f2f2f, 0x00a0486e, 0x0002486e, 0x81736100, 0x1faa2f40, 0x00444aaf, 0x00446c0a, 0x486e817c, 0x61000348, 0x588f486e, 0x818d2f2f, 0x00486100, 0x030a486e, 0x81a26100, 0x04022f2f, 0x00506100, 0x1f56486e, 0x81bd6100, 0x03f2422e, 0x84de486f, 0x00846100, 0x170a4a80, 0x6638102f, 0x008b49c0, 0x2f00102f, 0x008e49c0, 0x2f00102f, 0x009149c0, 0x2f00102f, 0x009449c0, 0x2f002f2f, 0x00bc486e, 0x81d76100, 0x0348486e, 0x81fa6100, 0x02704fef, 0x001c0c2e, 0x000184de, 0x002c486e, 0x84de6100, 0x100c2f00, 0x2f40005c, 0x486f0038, 0x2f2f0064, 0x61001f62, 0xb0af0064, 0x670a486e, 0x82056100, 0x025c588f, 0x486e820e, 0x61000322, 0x1d7c0002, 0x84de1d7c, 0x007684e8, 0x486f008c, 0x81c46100, 0x02f2588f, 0x4878001c, 0x486f0044, 0x2f2f0070, 0x61001f36, 0x2f400070, 0x4aaf0070, 0x6e0a486e, 0x81ce6100, 0x02ce588f, 0x2f2f0070, 0x486e84de, 0x61000ef6, 0x2f002f40, 0x00bc486f, 0x00982f2f, 0x00c46100, 0x1e40b0af, 0x00c4670a, 0x486e8219, 0x6100021a, 0x588f4878, 0x001c486f, 0x00a42f2f, 0x00d06100, 0x1e1a2f40, 0x00d04aaf, 0x00d06e0a, 0x486e8227, 0x610001f6, 0x588f2f2f, 0x00d0486e, 0x84de486f, 0x00b46100, 0x16464a80, 0x660a486e, 0x82346100, 0x01d8588f, 0x0c2e0003, 0x486f0054, 0x6100175c, 0x4a806638, 0x102f005b, 0x49c02f00, 0x102f005e, 0x49c02f00, 0x102f0061, 0x49c02f00, 0x102f0064, 0x49c02f00, 0x2f2f008c, 0x486e81d7, 0x6100035c, 0x486e81fa, 0x61000284, 0x4fef001c, 0x0c2e0001, 0x84de670a, 0x486e8243, 0x610001c6, 0x588f4a6e, 0x84e2671c, 0x302e84e2, 0x48c02f00, 0x486e8250, 0x6100027e, 0x486e825a, 0x610001a6, 0x4fef000c, 0x486e8267, 0x6100026a, 0x486e8275, 0x486e826f, 0x486f00c4, 0x6100032a, 0x486e8205, 0x61000270, 0x588f486e, 0x820e6100, 0x03361d7c, 0x000284de, 0x1d7c0076, 0x84e8486f, 0x005c486e, 0x84de6100, 0x0f482f00, 0x2f40008c, 0x486f0068, 0x2f2f0094, 0x61001e9e, 0xb0af0094, 0x670a486e, 0x82196100, 0x022e588f, 0x4878001c, 0x486f0074, 0x2f2f00a0, 0x61001e72, 0x2f4000a0, 0x4aaf00a0, 0x6e0a486e, 0x82276100, 0x020a588f, 0x2f2f00a0, 0x486e84de, 0x486f0084, 0x61001698, 0x4a80660a, 0x486e8234, 0x610001ec, 0x588f0c2e, 0x000384de, 0x670a486e, 0x82436100, 0x01da588f, 0x4a6e84e2, 0x671c302e, 0x84e248c0, 0x2f00486e, 0x82506100, 0x0292486e, 0x825a6100, 0x01ba4fef, 0x000c486e, 0x82676100, 0x027e486e, 0x8275486e, 0x826f486f, 0x00946100, 0x033e4878, 0x01b64878, 0x0001486f, 0x00a06100, 0x1dc04a80, 0x42e72f40, 0x00c244df, 0x6c0a486e, 0x827c6100, 0x017a588f, 0x2f2f00cc, 0x486e8283, 0x486f00ac, 0x61000308, 0x486f00b0, 0x61000e3c, 0x588f2f00, 0x486f00b4, 0x2f2f00d4, 0x61001db2, 0x2f00486f, 0x00c06100, 0x0e22588f, 0x221fb280, 0x670a486e, 0x82866100, 0x0136588f, 0x2f2f00d8, 0x61001d58, 0x486e8292, 0x486e828c, 0x486f00c8, 0x610002bc, 0x487801b6, 0x48780001, 0x486f00d0, 0x61001d6e, 0x486e8299, 0x61001d3e, 0x4a8042e7, 0x2f4000f2, 0x2f4000f6, 0x44df6c0a, 0x486e827c, 0x61000166, 0x486e82a1, 0x610000f8, 0x588f2f2f, 0x00fc486e, 0x8283486f, 0x00dc6100, 0x02f4486f, 0x0100486e, 0x82a8486f, 0x00e06100, 0x0dea588f, 0x0286486f, 0x00e46100, 0x0dba588f, 0x2f00486f, 0x00e42f2f, 0x01046100, 0x1d542f00, 0x486f00f0, 0x61000dd0, 0x00e82f2f, 0x01086100, 0x1d302f00, 0x486f00f4, 0x61000da0, 0x588f221f, 0xb280670a, 0x486e8286, 0x61000122, 0x486e82ab, 0x610000b4, 0x588f2f2f, 0x01086100, 0x1d06486e, 0x8292486e, 0x828c486f, 0x00f86100, 0x02a84878, 0x01b64878, 0x0001486e, 0x82996100, 0x1cec4a80, 0x42e72f40, 0x012644df, 0x6c0a486e, 0x82a16100, 0x00e4588f, 0x2f2f0130, 0x486e82a8, 0x486f0110, 0x61000272, 0x486f0114, 0x61000d68, 0x588f2f00, 0x486f0118, 0x2f2f0138, 0x61001cd2, 0x2f00486f, 0x01246100, 0x0d4e588f, 0x221fb280, 0x670a486e, 0x82ab6100, 0x00a0588f, 0x2f2f013c, 0x61001c84, 0x486e82b1, 0x6100015e, 0x42a7486e, 0x82bc486e, 0x82ba6100, 0x0d364a80, 0x6c08486e, 0x82be6174, 0x010c6100, 0x1cd6486e, 0x82b16100, 0x017242a7, 0x486e82bc, 0x486e82ba, 0x61000d88, 0x4a806c0a, 0x486e82be, 0x61000088, 0x588f486e, 0x82c54878, 0x0006486e, 0x82c32f2f, 0x01686100, 0x1c664a80, 0x01386100, 0x1cbc4a80, 0x6c08486e, 0x82c66154, 0x82c66166, 0x588f486e, 0x82cc6100, 0x011c42a7, 0x012e42a7, 0x486e82e1, 0x486e82d5, 0x61000cc8, 0x61000d18, 0x486e82e6, 0x61364fef, 0x01884e75, 0x598f2f2f, 0x000c6100, 0x0cc62f00, 0x2f400008, 0x2f2f0014, 0x2f2f0014, 0x61001c2e, 0xb0af0010, 0x67082f2f, 0x001c6108, 0x588f4fef, 0x00144e75, 0x4fefffc0, 0x485742a7, 0x61001bf0, 0x486f0008, 0x2f2f0050, 0x486e82f2, 0x48780002, 0x6100011a, 0x42a76174, 0x4fef005c, 0x4e75598f, 0x42817021, 0xb0816f1e, 0x4ab61d20, 0x83f6660e, 0x2daf0008, 0x1d2083f6, 0x7001588f, 0x4e755281, 0x61484fef, 0x01584e75, 0x48790000, 0xea606100, 0x1c96588f, 0x60f26000, 0xfcac598f, 0x2f2f000c, 0x61000d04, 0x2f002f40, 0x00082f2f, 0x00142f2f, 0x00146100, 0x1c78b0af, 0x00106708, 0x2f2f001c, 0x6108588f, 0x4fef0014, 0x4e754fef, 0xffc04857, 0x42a76100, 0x1c2e486f, 0x00082f2f, 0x0050486e, 0x82f24878, 0x00026100, 0x011a42a7, 0x61744fef, 0x005c4e75, 0x598f4281, 0x7021b081, 0x6ee24280, 0x6f1e4ab6, 0x1d2083f6, 0x660e2daf, 0x00081d20, 0x83f67001, 0x588f4e75, 0x598f206f, 0x00084282, 0x7021b082, 0x6f182036, 0x52817021, 0xb0816ee2, 0x4280588f, 0x4e75598f, 0x206f0008, 0x42827021, 0xb0826f18, 0x20362d20, 0x83f6b088, 0x660642b6, 0x2d2083f6, 0xb0886606, 0x42b62d20, 0x83f65282, 0x7021b082, 0x6ee8588f, 0x4e754aaf, 0x00046606, 0x42a7610c, 0x588f486e, 0x833e6104, 0x52827021, 0xb0826ee8, 0x588f4e75, 0x518f7220, 0x4a816d22, 0x2eb61d20, 0x83f64a97, 0x67122f41, 0x000442b6, 0x4aaf0004, 0x660642a7, 0x610c588f, 0x486e833e, 0x6104588f, 0x4e75518f, 0x72204a81, 0x6d222eb6, 0x1d2083f6, 0x4eb70151, 0x222f0004, 0x53814a81, 0x6cde2f2f, 0x000c6100, 0x1b204fef, 0x000c4e75, 0x4fefeff8, 0x41ef100c, 0x58882f08, 0x2f2f1010, 0x4a976712, 0x2f410004, 0x42b61d20, 0x83f64eb7, 0x0151222f, 0x00045381, 0x4a816cde, 0x2f2f000c, 0x61001b5e, 0x4fef000c, 0x4e754fef, 0xeff841ef, 0x100c5888, 0x2f082f2f, 0x101041ef, 0x0010d1fc, 0x00001000, 0x2f08486f, 0x00146100, 0x01402200, 0x41ef0018, 0x92882f01, 0x486f001c, 0x48780001, 0x61001b5a, 0x240042e7, 0x2f40001e, 0x44df6c1a, 0x52ae800e, 0x700ab0ae, 0x800e6e0e, 0x48780001, 0x6100ff5a, 0x242f0020, 0x588f2002, 0x4fef1024, 0x4e754fef, 0xeff841ef, 0x10105888, 0x2f082f2f, 0x101441ef, 0x0010d1fc, 0x00001000, 0x2f08486f, 0x00146100, 0x00d82200, 0x41ef0018, 0x92882f01, 0x486f001c, 0x2f2f1024, 0x61001af2, 0x240042e7, 0x2f40001e, 0x44df6c1a, 0x52ae800e, 0x700ab0ae, 0x800e6e0e, 0x48780001, 0x6100fef2, 0x242f0020, 0x588f2002, 0x4fef1024, 0x4e75518f, 0x226f000c, 0x2eae8012, 0x41ef0010, 0xd1fc0000, 0x10002f08, 0x486f0014, 0x61000140, 0x220041ef, 0x00189288, 0x2f01486f, 0x001c4878, 0x00016100, 0x1b102400, 0x42e72f40, 0x001e44df, 0x6c1a52ae, 0x800e700a, 0xb0ae800e, 0x6e0e4878, 0x00016100, 0xff5a242f, 0x0020588f, 0x20024fef, 0x10244e75, 0x4fefeff8, 0x41ef1010, 0x58882f08, 0x2f2f1014, 0x41ef0010, 0xd1fc0000, 0x10002f08, 0x486f0014, 0x610000d8, 0x220041ef, 0x00189288, 0x2f01486f, 0x001c2f2f, 0x10246100, 0x1aa82400, 0x42e72f40, 0x001e44df, 0x6c1a52ae, 0x800e700a, 0xb0ae800e, 0x6e0e4878, 0x00016100, 0xfef2242f, 0x0020588f, 0x20024fef, 0x10244e75, 0x518f226f, 0x000c2eae, 0x801241ef, 0x00105888, 0x2f082f2f, 0x00144869, 0x10002f09, 0x61742d6f, 0x00108012, 0x90af001c, 0x4fef0018, 0x4e75142f, 0x0007c43c, 0x007f1002, 0x49c04a36, 0x09208092, 0x661e701e, 0xb0ae8016, 0x6e047001, 0x4e75202e, 0x2f2f0014, 0x48691000, 0x2f096174, 0x2d6f0010, 0x801290af, 0x001c4fef, 0x00184e75, 0x142f0007, 0xc43c007f, 0x100249c0, 0x4a360920, 0x8092661e, 0x701eb0ae, 0x80166e04, 0x70014e75, 0x202e8016, 0x120249c1, 0x1d801920, 0x809252ae, 0x80161202, 0x49c11d80, 0x49c11036, 0x19208092, 0x52ae8016, 0x120249c1, 0x10361920, 0x809249c0, 0x2daf0008, 0x0d20801a, 0x42804e75, 0x206f0004, 0x2f2f000c, 0x2f2f000c, 0x48680400, 0x2f086106, 0x4fef0010, 0x4e754fef, 0xffe4226f, 0x00282f6e, 0x80060004, 0x2eae8002, 0x2d6f0020, 0x8006202f, 0x00245380, 0x2d408002, 0x101949c0, 0x24007025, 0xb082675a, 0x4a82661a, 0x42360161, 0x8006202e, 0x80062d6f, 0x00048006, 0x2d578002, 0x4fef001c, 0x4e75202e, 0x8006b0ae, 0x8002640a, 0x1d820161, 0x800652ae, 0x800652ae, 0x8012700a, 0xb0826606, 0x42ae8012, 0x60b27009, 0xb08266ac, 0x7007d0ae, 0x8012c0bc, 0xfffffff8, 0x2d408012, 0x609a4284, 0x74ff2a02, 0x42af0010, 0x141949c2, 0x2f490028, 0x4283702d, 0xb082660c, 0x74012602, 0x141949c2, 0x2f490028, 0x7030b082, 0x6e087039, 0xb0826c00, 0x00b64a83, 0x67024484, 0x702eb082, 0x676a4a82, 0x66065389, 0x2f490028, 0x2f2f0010, 0x49c02daf, 0x00080d20, 0x801a4280, 0x4e75206f, 0x00042f2f, 0x000c2f2f, 0x000c4868, 0x04002f08, 0x61064fef, 0x00104e75, 0x4fefffe4, 0x226f0028, 0x282f002c, 0x2f6e8006, 0x00042eae, 0x80022d6f, 0x00208006, 0x202f0024, 0x53802d40, 0x80021019, 0x49c02400, 0x7025b082, 0x675a4a82, 0x661a4236, 0x01618006, 0x202e8006, 0x2d6f0004, 0x80062d57, 0x80024fef, 0x001c4e75, 0x202e8006, 0xb0ae8002, 0x640a1d82, 0x01618006, 0x52ae8006, 0x52ae8012, 0x700ab082, 0x660642ae, 0x801260b2, 0x7009b082, 0x66ac7007, 0xd0ae8012, 0xc0bcffff, 0xfff82d40, 0x8012609a, 0x428574ff, 0x260242af, 0x00101419, 0x49c22f49, 0x0028702a, 0xb0826600, 0x00e02a30, 0x49905884, 0x24041419, 0x49c22f49, 0x0028702e, 0xb082676a, 0x4a826606, 0x53892f49, 0x00282f2f, 0x00102f03, 0x2f43001c, 0x2f052f45, 0x001c2f04, 0x2f440024, 0x2f2f0038, 0x00242f04, 0x2f44003c, 0x727fc282, 0x10361920, 0x809249c0, 0x20760d20, 0x801a4e90, 0x2a2f0028, 0x226f0038, 0x2a2f0024, 0x282f0028, 0x282f003c, 0x262f0024, 0x24006c16, 0x448285af, 0x00201419, 0x49c22002, 0x2f490038, 0x4fef0010, 0x60a8202f, 0x003cd082, 0x2f40003c, 0x4fef0010, 0x6000fef2, 0x60a2d882, 0x20044fef, 0x00106000, 0xff021019, 0x49c02400, 0x2f490028, 0x702ab082, 0x66162630, 0x49905884, 0x20041019, 0x49c02400, 0x2f490028, 0x6000ff72, 0x7030b082, 0x6e00ff6a, 0x7039b082, 0x6d00ff62, 0x4a836c02, 0x42832003, 0x2203d281, 0xd281d081, 0xd080d082, 0x90bc0000, 0x00302600, 0x101949c0, 0x24002f49, 0x00287030, 0xb0826e86, 0x7039b082, 0x6d804a85, 0x6c024285, 0x002860c8, 0x4286702d, 0xb082660c, 0x74012c02, 0x141949c2, 0x2f490028, 0x7030b082, 0x6e067039, 0xb0826c0c, 0x4a866700, 0xff0e4485, 0x6000ff08, 0x20052205, 0xd281d281, 0xd081d080, @@ 491,16 529,7 @@ ulong bootcode[]={ 0x2a001019, 0x49c02400, 0x2f490028, 0x60cc2004, 0x2204d281, 0xd281d081, 0xd080d082, 0x90bc0000, 0x00302800, 0x101949c0, 0x24002f49, 0x00286000, 0xff1c4fef, 0x60c64fef, 0xffc4282f, 0x004c226f, 0x00402a2f, @@ 1462,7 1491,7 @@ ulong bootcode[]={ 0xfa261011, 0x49c02f00, 0x486e830a, 0x6100ee02, 0x6100edc4, 0x42804fef, 0x000c4e75, 0x30290004, @@ 1923,7 1952,7 @@ ulong bootcode[]={ 0xfa981011, 0x49c02f00, 0x486e8318, 0x6100e6ce, 0x6100e690, 0x42804fef, 0x000c4e75, 0x42801010, @@ 2052,10 2081,13 @@ ulong bootcode[]={ 0x4e757006, 0x4e404e75, 0x70074e40, 0x4e75700d, 0x4e757009, 0x4e404e75, 0x700d4e40, 0x4e75700e, 0x4e404e75, 0x700e4e40, 0x4e75700f, 0x700f4e40, 0x4e757011, 0x4e404e75, 0x70144e40, 0x4e750000, @@ 2065,19 2097,19 @@ ulong bootcode[]={ 0x00000000, 0x00000000, 0x000d0000, 0x29f80000, 0x2a0e0000, 0x2a340000, 0x2a520000, 0x2a560000, 0x2a660000, 0x2a840000, 0x2a9e0000, 0x2aa20000, 0x2ac00000, 0x2ece0000, 0x2ef40000, 0x2f1a0000, 0x2a6c0000, 0x2a820000, 0x2aa80000, 0x2ac60000, 0x2aca0000, 0x2ada0000, 0x2af80000, 0x2b120000, 0x2b160000, 0x2b340000, 0x2f420000, 0x2f680000, 0x2f8e0000, 0x00000000, 0x00000000, 0x00000000, @@ 2312,6 2344,6 @@ ulong bootcode[]={ 0x0162010a, 0x00be005a, 0x001c0000, 0x0002422, 0x00024a2, 0x, };
M gnot/dat.h => gnot/dat.h +2 -2
@@ 287,8 287,8 @@ struct Proc char text[NAMELEN]; Proc *rnext; /* next process in run queue */ Proc *qnext; /* next process on queue for a QLock */ QLock *qlock; /* address of qlock being queued for DEBUG */ int state; short pidonmach[MAXMACH]; /* TLB pid on each mmu */ Page *upage; /* BUG: should be unlinked from page list */ Seg seg[NSEG]; ulong pid; @@ 320,8 320,8 @@ struct Proc struct User { Proc *p; Label errlab[NERR]; int nerrlab; Label errlab[NERR]; Error error; FPsave fpsave; /* address of this is known by vdb */ char elem[NAMELEN]; /* last name element from namec */
M gnot/devdk.c => gnot/devdk.c +11 -4
@@ 329,6 329,8 @@ dkstopen(Queue *q, Stream *s) q->other->ptr = q->ptr = lp = &dp->line[s->id]; lp->dp = dp; lp->rq = q; if(lp->state == Lclosed) lp->state = Lopened; } /* @@ 417,7 419,11 @@ dkoput(Queue *q, Block *bp) bp->rptr[0] = line; bp->rptr[1] = line>>8; PUTNEXT(dp->wq, bp); if(QFULL(dp->wq->next)){ print("dk wq full\n"); freeb(bp); } else PUTNEXT(dp->wq, bp); } /* @@ 666,7 672,6 @@ dkopen(Chan *c, int omode) continue; } c->qid = STREAMQID(lp-dp->line, Sctlqid); qunlock(lp); break; } } @@ 674,6 679,7 @@ dkopen(Chan *c, int omode) error(0, Enodev); streamopen(c, &dkinfo); pushq(c->stream, &urpinfo); qunlock(lp); break; case Dlistenqid: /* @@ 723,7 729,7 @@ dkclose(Chan *c) { Dk *dp; /* real closing happens in lancestclose */ /* real closing happens in dkstclose */ if(c->stream) streamclose(c); @@ 895,7 901,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) /* * only dial on virgin lines */ if(lp->state != Lclosed) if(lp->state != Lopened) error(0, Ebadarg); DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr); @@ 1198,6 1204,7 @@ dklisten(Chan *c) DPRINT("dklisten returns %d\n", lineno); return lineno; } panic("dklisten terminates strangely\n"); } /*
M gnot/devincon.c => gnot/devincon.c +2 -0
@@ 757,6 757,8 @@ rdpackets(Incon *ip) } } bp->wptr = p; if(bp->wptr != bp->base+3) nextin(ip, 0); if(first != ip->wi)/**/ wakeup(&ip->kr);
M gnot/devmnt.c => gnot/devmnt.c +266 -87
@@ 9,18 9,27 @@ #include "fcall.h" /* * Easy version: multiple sessions but no intra-session multiplexing, copy the data */ typedef struct Mnt Mnt; typedef struct Mnthdr Mnthdr; typedef struct MntQ MntQ; struct Mnt { Ref; /* for number of chans, incl. mntpt but not msg */ QLock; /* for access */ ulong mntid; /* serial # */ Chan *msg; /* for reading and writing messages */ Chan *mntpt; /* channel in user's name space */ MntQ *q; }; struct MntQ { Ref; QLock; /* for access */ MntQ *next; /* for allocation */ Chan *msg; /* for reading and writing messages */ Proc *reader; /* process reading response */ Mnthdr *writer; /* queue of headers of written messages */ }; #define BUFSIZE (MAXFDATA+500) /* BUG */ @@ 37,12 46,14 @@ struct Mntbuf *free; }mntbufalloc; typedef struct Mnthdr Mnthdr; struct Mnthdr /* next only meaningful when buffer isn't being used */ struct Mnthdr { Mnthdr *next; Mnthdr *next; /* in free list or writers list */ Fcall thdr; Fcall rhdr; Rendez r; Proc *p; Mntbuf *mbr; }; struct @@ 54,6 65,13 @@ struct struct { Lock; MntQ *arena; MntQ *free; }mntqalloc; struct { Lock; long id; }mntid; @@ 106,7 124,7 @@ loop: unlock(&mnthdralloc); print("no mnthdrs\n"); if(u == 0) panic("mballoc"); panic("mhalloc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); @@ 122,6 140,45 @@ mhfree(Mnthdr *mh) unlock(&mnthdralloc); } MntQ* mqalloc(void) { MntQ *q; lock(&mntqalloc); if(q = mntqalloc.free){ /* assign = */ mntqalloc.free = q->next; unlock(&mntqalloc); lock(q); q->ref = 1; q->writer = 0; q->reader = 0; unlock(q); return q; } unlock(&mntqalloc); panic("no mntqs\n"); /* there MUST be enough */ } void mqfree(MntQ *mq) { Chan *msg = 0; lock(mq); if(--mq->ref == 0){ msg = mq->msg; mq->msg = 0; lock(&mntqalloc); mq->next = mntqalloc.free; mntqalloc.free = mq; unlock(&mntqalloc); } unlock(mq); if(msg) /* after locks are down */ close(msg); } Mnt* mntdev(int dev, int noerr) { @@ 130,7 187,7 @@ mntdev(int dev, int noerr) for(m=mnt,i=0; i<conf.nmntdev; i++,m++) /* use a hash table some day */ if(m->mntid == dev){ if(m->msg == 0) if(m->q == 0) break; return m; } @@ 145,6 202,7 @@ mntreset(void) int i; Mntbuf *mb; Mnthdr *mh; MntQ *mq; mnt = ialloc(conf.nmntdev*sizeof(Mnt), 0); @@ 159,6 217,13 @@ mntreset(void) mh[i].next = &mh[i+1]; mh[i].next = 0; mnthdralloc.free = mh; mq = ialloc(conf.nmntdev*sizeof(MntQ), 0); for(i=0; i<conf.nmntdev-1; i++) mq[i].next = &mq[i+1]; mq[i].next = 0; mntqalloc.arena = mq; mntqalloc.free = mq; } void @@ 170,8 235,9 @@ Chan* mntattach(char *spec) { int i; Mnt *m; Mnt *m, *mm; Mnthdr *mh; MntQ *q; Chan *c, *cm; struct bogus{ Chan *chan; @@ 189,6 255,7 @@ mntattach(char *spec) unlock(m); } error(0, Enomntdev); Found: m->ref = 1; unlock(m); @@ 199,11 266,31 @@ mntattach(char *spec) c->dev = m->mntid; m->mntpt = c; cm = bogus.chan; m->msg = cm; /* * Look for queue to same msg channel */ q = mntqalloc.arena; for(i=0; i<conf.nmntdev; i++,q++) if(q->msg==cm){ lock(q); if(q->ref && q->msg==cm){ m->q = q; q->ref++; unlock(q); goto out; } unlock(q); } m->q = mqalloc(); m->q->msg = cm; incref(cm); out: mh = mhalloc(); if(waserror()){ mhfree(mh); mqfree(q); close(c); nexterror(); } @@ 213,7 300,7 @@ mntattach(char *spec) strcpy(mh->thdr.aname, spec); mntxmit(m, mh); c->qid = mh->rhdr.qid; c->mchan = m->msg; c->mchan = m->q->msg; c->mqid = c->qid; mhfree(mh); poperror(); @@ 255,10 342,10 @@ mntclone(Chan *c, Chan *nc) nc->mnt = c->mnt; nc->mchan = c->mchan; nc->mqid = c->qid; if(new) poperror(); mhfree(mh); poperror(); if(new) poperror(); incref(m); return nc; } @@ 364,32 451,46 @@ mntcreate(Chan *c, char *name, int omode, ulong perm) } void mntclose(Chan *c) mntclunk(Chan *c, int t) { Mnt *m; Mnthdr *mh; MntQ *q; int waserr; int ne = u->nerrlab; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tclunk; mh->thdr.type = t; mh->thdr.fid = c->fid; mntxmit(m, mh); waserr = 0; if(waserror()) /* gotta clean up as if there wasn't */ waserr = 1; else mntxmit(m, mh); mhfree(mh); if(c == m->mntpt) m->mntpt = 0; if(decref(m) == 0){ /* BUG: need to hang up all pending i/o */ qlock(m); close(m->msg); m->msg = 0; qunlock(m); } lock(m); if(--m->ref == 0){ /* BUG: need to hang up all pending i/o */ q = m->q; m->q = 0; m->mntid = 0; unlock(m); /* mqfree can take time */ mqfree(q); }else unlock(m); if(waserr) nexterror(); poperror(); } void mntclose(Chan *c) { mntclunk(c, Tclunk); } long mntreadwrite(Chan *c, void *vbuf, long n, int type) { @@ 458,21 559,7 @@ mntwrite(Chan *c, void *buf, long n) void mntremove(Chan *c) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } decref(m); mh->thdr.type = Tremove; mh->thdr.fid = c->fid; mntxmit(m, mh); mhfree(mh); poperror(); mntclunk(c, Tremove); } void @@ 550,11 637,48 @@ mntuserstr(Error *e, char *buf) } void mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ { Mnthdr *w; qlock(q); /* take self from queue if necessary */ if(q->reader == u->p){ /* advance a writer to reader */ w = q->writer; if(w){ q->reader = w->p; q->writer = w->next; wakeup(&w->r); }else{ q->reader = 0; q->writer = 0; } }else{ w = q->writer; if(w == mh) q->writer = w->next; else{ while(w){ if(w->next == mh){ w->next = mh->next; break; } w = w->next; } } } qunlock(q); } void mntxmit(Mnt *m, Mnthdr *mh) { ulong n; Mntbuf *mbr, *mbw; Chan *mntpt, *msg; Mnthdr *w, *ow; Chan *mntpt; MntQ *q; int qlocked; mbr = mballoc(); mbw = mballoc(); @@ 564,6 688,7 @@ mntxmit(Mnt *m, Mnthdr *mh) nexterror(); } n = convS2M(&mh->thdr, mbw->buf); #ifdef bit3 /* * Bit3 does its own multiplexing. (Well, the file server does.) * The code is different enough that it's broken out separately here. @@ 582,8 707,8 @@ mntxmit(Mnt *m, Mnthdr *mh) nexterror(); } if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ pprint("short write in mntxmit\n"); error(0, Egreg); print("short write in mntxmit\n"); error(0, Eshortmsg); } /* @@ 594,20 719,20 @@ mntxmit(Mnt *m, Mnthdr *mh) poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ pprint("format error in mntxmit\n"); error(0, Egreg); print("format error in mntxmit\n"); error(0, Ebadmsg); } /* * Various checks */ if(mh->rhdr.type != mh->thdr.type+1){ pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Egreg); print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Ebadmsg); } if(mh->rhdr.fid != mh->thdr.fid){ pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Egreg); print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Ebadmsg); } if(mh->rhdr.err){ mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ @@ 627,46 752,100 @@ mntxmit(Mnt *m, Mnthdr *mh) return; Normal: qlock(m); if((msg = m->msg) == 0){ qunlock(m); #endif q = m->q; if(q == 0) error(0, Eshutdown); } qlock(msg); incref(q); qlock(q); qlocked = 1; if(waserror()){ qunlock(m); qunlock(msg); if(qlocked) qunlock(q); mqfree(q); nexterror(); } if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ pprint("short write in mntxmit\n"); error(0, Egreg); } /* * Read response */ n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); qunlock(m); qunlock(msg); if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ print("short write in mntxmit\n"); error(0, Eshortmsg); } if(q->reader == 0){ /* i will read */ q->reader = u->p; Read: qunlock(q); qlocked = 0; n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); mnterrdequeue(q, mh); error(0, Ebadmsg); } /* * Response might not be mine */ qlock(q); qlocked = 1; if(mh->rhdr.fid == mh->thdr.fid && mh->rhdr.type == mh->thdr.type+1){ /* it's mine */ q->reader = 0; if(w = q->writer){ /* advance a writer to reader */ q->reader = w->p; q->writer = w->next; wakeup(&w->r); } qunlock(q); qlocked = 0; goto Respond; } /* * Hand response to correct recipient */ if(q->writer == 0) print("response with empty queue\n"); for(ow=0,w=q->writer; w; ow=w,w=w->next) if(mh->rhdr.fid == w->thdr.fid && mh->rhdr.type == w->thdr.type+1){ Mntbuf *t; t = mbr; mbr = w->mbr; w->mbr = t; memcpy(&w->rhdr, &mh->rhdr, sizeof mh->rhdr); /* take recipient from queue */ if(ow == 0) q->writer = w->next; else ow->next = w->next; wakeup(&w->r); goto Read; } goto Read; }else{ mh->mbr = mbr; mh->p = u->p; /* put self in queue */ mh->next = q->writer; q->writer = mh; qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ print("interrupted i/o\n"); mnterrdequeue(q, mh); nexterror(); } sleep(&mh->r, return0, 0); poperror(); qlock(q); qlocked = 1; if(q->reader == u->p) /* i got promoted */ goto Read; mbr = mh->mbr; /* pick up my buffer */ qunlock(q); qlocked = 0; goto Respond; } Respond: mqfree(q); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ pprint("format error in mntxmit\n"); error(0, Egreg); } /* * Various checks */ if(mh->rhdr.type != mh->thdr.type+1){ pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Egreg); } if(mh->rhdr.fid != mh->thdr.fid){ pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Egreg); } if(mh->rhdr.err){ mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ if(mntpt)
M gnot/devproc.c => gnot/devproc.c +12 -2
@@ 201,6 201,7 @@ procread(Chan *c, void *va, long n) Seg *s; Orig *o; Page *pg; PTE *pte, *opte; int i; long l; long pid; @@ 237,10 238,19 @@ procread(Chan *c, void *va, long n) unlock(o); error(0, Egreg); } pg = o->pte[(c->offset-o->va)>>PGSHIFT].page; pte = &o->pte[(c->offset-o->va)>>PGSHIFT]; if(s->mod){ opte = pte; while(pte = pte->nextmod) /* assign = */ if(pte->proc == p) break; if(pte == 0) pte = opte; } pg = pte->page; unlock(o); if(pg == 0){ pprint("nonresident page (complain to rob)\n"); pprint("nonresident page addr %lux (complain to rob)\n", c->offset); memset(a, 0, n); }else{ b = (char*)(pg->pa|KZERO);
M gnot/errno.h => gnot/errno.h +2 -0
@@ 50,5 50,7 @@ enum{ Enobitmap, /* out of bitmap descriptors */ Enobitstore, /* out of bitmap storage */ Ebadbitmap, /* unallocated bitmap */ Eshortmsg, /* short message */ Ebadmsg, /* format error or mismatch in message */ Egreg, /* it's all greg's fault */ };
M gnot/fns.h => gnot/fns.h +1 -0
@@ 109,6 109,7 @@ void putstrn(char*, long); ulong pwait(Waitmsg*); int readnum(ulong, char*, ulong, ulong, int); void ready(Proc*); int return0(void*); void rooterrstr(Error*, char*); void qlock(QLock*); void qunlock(QLock*);
M gnot/lock.c => gnot/lock.c +4 -1
@@ 12,6 12,8 @@ * if(l->key >= 0){ * l->key |= 0x80; * ... * * DO NOT TAKE THE ADDRESS OF l->key or the TAS will disappear. */ void lock(Lock *l) @@ 31,7 33,7 @@ lock(Lock *l) l->key |= 0x80; l->pc = ((ulong*)&i)[PCOFF]; return; } } l->key = 0; panic("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&i)[PCOFF], l->pc); } @@ 76,6 78,7 @@ qlock(QLock *q) q->tail = u->p; u->p->qnext = 0; u->p->state = Queueing; u->p->qlock = q; /* DEBUG */ unlock(&q->queue); sched(); }
M gnot/main.c => gnot/main.c +6 -6
@@ 237,22 237,22 @@ confinit(void) conf.npgrp = 15; conf.npage = (4*1024*1024-256*1024)/BY2PG; conf.npte = 500; conf.nmod = 50; conf.nmod = 200; conf.nalarm = 1000; conf.norig = 50; conf.norig = 100; conf.nchan = 200; conf.nenv = 100; conf.nenvchar = 8000; conf.npgenv = 200; conf.nmtab = 50; conf.nmount = 100; conf.nmntdev = 10; conf.nmntbuf = 20; conf.nmnthdr = 20; conf.nmntdev = 20; conf.nmntbuf = 2*conf.nmntdev; conf.nmnthdr = 2*conf.nmntdev; conf.nstream = 64; conf.nqueue = 5 * conf.nstream; conf.nblock = 12 * conf.nstream; conf.nsrv = 32; conf.nbitmap = 100; conf.nbitbyte = 200*1024; conf.nbitbyte = 400*1024; }
M gnot/proc.c => gnot/proc.c +2 -4
@@ 172,7 172,6 @@ loop: p->nchild = 0; p->child = 0; p->exiting = 0; memset(p->pidonmach, 0, sizeof p->pidonmach); memset(p->seg, 0, sizeof p->seg); lock(&pidalloc); p->pid = ++pidalloc.pid; @@ 516,7 515,6 @@ again: lock(&p->wait.queue); /* wait until child is finished */ c = p->child; if(c == 0){ print("pwait %d\n", p->pid); p->state = Inwait; unlock(&p->wait.queue); sched(); @@ 552,9 550,9 @@ DEBUG() for(i=0; i<conf.nproc; i++){ p = procalloc.arena+i; if(p->state != Dead) print("%d:%s upc %lux %s ut %ld st %ld\n", print("%d:%s upc %lux %s ut %ld st %ld %lux\n", p->pid, p->text, p->pc, statename[p->state], p->time[0], p->time[1]); p->time[0], p->time[1], p->qlock); } }
M gnot/screen.c => gnot/screen.c +21 -5
@@ 11,6 11,8 @@ #define MINX 8 extern Font defont0; extern Font defont1; Font *defont; struct{ Point pos; @@ 33,6 35,14 @@ void screeninit(void) { duartinit(); /* * Read HEX switch to set ldepth */ if(*(uchar*)MOUSE & (1<<4)){ screen.ldepth = 1; defont = &defont1; }else defont = &defont0; bitblt(&screen, Pt(0, 0), &screen, screen.r, 0); out.pos.x = MINX; out.pos.y = 0; @@ 68,7 78,7 @@ screenputc(int c) screenputc('\n'); buf[0] = c&0x7F; buf[1] = 0; out.pos = string(&screen, out.pos, &defont0, buf, S); out.pos = string(&screen, out.pos, defont, buf, S); } } @@ 186,7 196,7 @@ duartinit(void) /* * Output port */ duart[0].ipc_acr = 0xBF; /* allow change of state interrupt */ duart[0].ipc_acr = 0xB7; /* allow change of state interrupt */ duart[1].ip_opcr = 0x00; duart[1].scc_ropbc = 0xFF; /* make sure the port is reset first */ duart[1].scc_sopbc = 0x04; /* dtr = 1, pp = 01 */ @@ 275,12 285,18 @@ duartintr(Ureg *ur) if(cause & IM_RRDYB) /* pen input */ c = duart[1].data; /* * Is it 4? * Is it 3? */ if(cause & IM_XRDYB) if(cause & IM_XRDYB){ duart[1].cmnd = DIS_TX; } /* * Is it 3? * Is it 4? */ if(cause & IM_XRDYA) duart[0].cmnd = DIS_TX; /* * Is it 5? */ if(cause & IM_IPC) mousebuttons((~duart[0].ipc_acr) & 7);
M gnot/stream.c => gnot/stream.c +17 -3
@@ 58,7 58,7 @@ Bclass bclass[Nclass]={ { 0 }, { 68 }, { 260 }, { 1024 }, { 4096 }, }; /* @@ 70,17 70,29 @@ dumpqueues(void) Queue *q; int count; Block *bp; Bclass *bcp; print("\n"); for(q = qlist; q < qlist + conf.nqueue; q++, q++){ if(!(q->flag & QINUSE)) continue; for(count = 0, bp = q->first; bp; bp = bp->next) count++; print("%s %ux RD count %d len %d", q->info->name, q, count, q->len); print("%s %ux R c %d l %d f %ux", q->info->name, q, count, q->len, q->flag); for(count = 0, bp = WR(q)->first; bp; bp = bp->next) count++; print(" WR count %d len %d\n", count, WR(q)->len); print(" W c %d l %d f %ux\n", count, WR(q)->len, WR(q)->flag); } print("\n"); for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){ lock(bcp); for(count = 0, bp = bcp->first; bp; count++, bp = bp->next) ; unlock(bcp); print("%d blocks of size %d\n", count, bcp->size); } print("\n"); } /* @@ 180,6 192,8 @@ freeb(Block *bp) Bclass *bcp; int tries; if((bp->flags&S_CLASS) >= Nclass) panic("freeb class"); bcp = &bclass[bp->flags & S_CLASS]; lock(bcp); bp->rptr = bp->wptr = 0;
M gnot/sturp.c => gnot/sturp.c +65 -34
@@ 48,7 48,6 @@ struct Urp { int blocks; /* output */ QLock xmit; /* output lock, only one process at a time */ Queue *wq; /* output queue */ int maxout; /* maximum outstanding unacked blocks */ @@ 60,6 59,7 @@ struct Urp { Block *xb[8]; /* the xmit window buffer */ QLock xl[8]; ulong timer; /* timeout for xmit */ int rexmit; int kstarted; }; @@ 166,15 166,7 @@ isflushed(void *a) Urp *up; up = (Urp *)a; return (up->state&HUNGUP) || (up->unechoed==up->next && up->wq->len==0); } static int isdead(void *a) { Urp *up; up = (Urp *)a; return up->kstarted == 0; return (up->state&HUNGUP) || (up->unechoed==up->nxb && up->wq->len==0); } static void urpclose(Queue *q) @@ 188,28 180,41 @@ urpclose(Queue *q) /* * wait for all outstanding messages to drain, tell kernel * process we're closing. * * if 2 minutes elapse, give it up */ up->state |= CLOSING; sleep(&up->r, isflushed, up); tsleep(&up->r, isflushed, up, 2*60*1000); /* * ack all outstanding messages * kill off the kernel process */ qlock(&up->xmit); up->state |= HUNGUP; wakeup(&up->rq->r); qlock(&up->xmit); /* * ack all outstanding messages */ i = up->next - 1; if(i < 0) i = 7; rcvack(up, ECHO+i); qunlock(&up->xmit); /* * kill off the kernel process * free all staged but unsent messages */ wakeup(&up->rq->r); for(i = 0; i < 7; i++) if(up->xb[i]){ freeb(up->xb[i]); up->xb[i] = 0; } qunlock(&up->xmit); if(up->kstarted == 0) if(up->kstarted == 0){ DPRINT("urpclose %ux\n", up); up->state = 0; } } /* @@ 256,9 261,10 @@ urpciput(Queue *q, Block *bp) /* * take care of any data */ if(BLEN(bp)>0 && !QFULL(q->next)) if(BLEN(bp)>0 && q->next->len<2*Streamhi && q->next->nb<2*Streambhi){ bp->flags |= S_DELIM; PUTNEXT(q, bp); else } else freeb(bp); /* @@ 370,8 376,8 @@ urpiput(Queue *q, Block *bp) * queue the block(s) */ if(BLEN(bp) > 0){ bp->flags &= ~S_DELIM; putq(q, bp); q->last->flags &= ~S_DELIM; if(q->len > 4*1024){ flushinput(up); return; @@ 460,6 466,10 @@ urpiput(Queue *q, Block *bp) urpstat.rjseq++; sendrej(up); break; } else if(q->next->len > (3*Streamhi)/2 || q->next->nb > (3*Streambhi)/2) { flushinput(up); break; } /* @@ 472,7 482,8 @@ urpiput(Queue *q, Block *bp) PUTNEXT(q, bp); } else { bp = allocb(0); bp->flags |= S_DELIM; if(up->trbuf[0] != BOTM) bp->flags |= S_DELIM; PUTNEXT(q, bp); } up->trx = 0; @@ 547,6 558,7 @@ output(Urp *up) ulong now; Queue *q; int n; int i; if(!canqlock(&up->xmit)) return; @@ 595,8 607,7 @@ output(Urp *up) /* * if a retransmit time has elapsed since a transmit, send an ENQ */ if(up->unechoed != up->next && NOW > up->timer){ DPRINT("sENQ\n"); if(up->unechoed!=up->next && NOW>up->timer){ up->timer = NOW + MSrexmit; up->state &= ~REJECTING; sendctl(up, ENQ); @@ 608,11 619,21 @@ output(Urp *up) /* * if there's a window open, push some blocks out */ while(WINDOW(up)>0 && up->xb[up->next]!=0 && canqlock(&up->xl[up->next])){ if(up->xb[up->next]) sendblock(up, up->next); qunlock(&up->xl[up->next]); if(up->rexmit){ up->rexmit = 0; up->next = up->unechoed; } while(WINDOW(up)>0 && up->xb[up->next]!=0){ i = up->next; qlock(&up->xl[i]); if(waserror()){ qunlock(&up->xl[i]); nexterror(); } sendblock(up, i); qunlock(&up->xl[i]); up->next = NEXT(up->next); poperror(); } qunlock(&up->xmit); poperror(); @@ 733,6 754,7 @@ rcvack(Urp *up, int msg) { int seqno; int next; int i; seqno = msg&Nmask; next = NEXT(seqno); @@ 742,11 764,12 @@ rcvack(Urp *up, int msg) */ if(IN(seqno, up->unacked, up->next)){ for(; up->unacked != next; up->unacked = NEXT(up->unacked)){ qlock(&up->xl[up->unacked]); if(up->xb[up->unacked]) freeb(up->xb[up->unacked]); up->xb[up->unacked] = 0; qunlock(&up->xl[up->unacked]); i = up->unacked; qlock(&up->xl[i]); if(up->xb[i]) freeb(up->xb[i]); up->xb[i] = 0; qunlock(&up->xl[i]); } } @@ 774,7 797,7 @@ rcvack(Urp *up, int msg) */ if(up->unechoed==next && !(up->state & REJECTING)){ up->state |= REJECTING; up->next = next; up->rexmit = 1; } break; } @@ 819,6 842,7 @@ initoutput(Urp *up, int window) up->unacked = 1; up->next = 1; up->nxb = 1; up->rexmit = 0; /* * free any outstanding blocks @@ 874,6 898,7 @@ urpkproc(void *arg) up = (Urp *)arg; if(waserror()){ print("urpkproc error %ux\n", up); up->state = 0; up->kstarted = 0; wakeup(&up->r); @@ 886,10 911,16 @@ urpkproc(void *arg) if(up->state & HUNGUP) break; } sendack(up); if(up->state == 0){ DPRINT("urpkproc: %ux->state == 0\n", up); break; } if(!QFULL(up->rq->next)) sendack(up); output(up); tsleep(&up->rq->r, todo, up, MSrexmit/2); } up->state = 0; up->kstarted = 0; DPRINT("urpkproc %ux\n", up); }
M port/devbit.c => port/devbit.c +65 -29
@@ 9,7 9,7 @@ #include "gnot.h" extern Font defont0; /* BUG */ extern Font *defont; /* * Device (#b/bitblt) is exclusive use on open, so no locks are necessary @@ 24,7 24,8 @@ extern Font defont0; /* BUG */ * followed by N blocks. The bitmap pointer is zero if block is free. */ struct{ struct { Ref; Bitmap *map; /* arena */ Bitmap *free; /* free list */ @@ 53,25 54,27 @@ struct{ Rendez r; }mouse; Cursor arrow = { {0, 0}, {0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0, 0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, }, {0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00, 0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0, 0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, } }; struct{ Cursor; Lock; int visible; /* on screen */ Rectangle r; /* location */ }cursor = { {{0, 0}, {0xFFE0, 0xFFE0, 0xFFC0, 0xFF00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xE7F0, 0xE3F8, 0xC1FC, 0x00FE, 0x007F, 0x003E, 0x001C, 0x0008, }, {0x0000, 0x7FC0, 0x7F00, 0x7C00, 0x7E00, 0x7F00, 0x6F80, 0x67C0, 0x43E0, 0x41F0, 0x00F8, 0x007C, 0x003E, 0x001C, 0x0008, 0x0000, }}, }; }cursor; ulong setbits[16]; Bitmap set = @@ 103,7 106,7 @@ Bitmap cursorback = {0, 0, 16, 16} }; void cursortobitmap(void); void Cursortocursor(Cursor*); void cursoron(int); void cursoroff(int); int mousechanged(void*); @@ 140,7 143,7 @@ bitreset(void) bit.words = ialloc(conf.nbitbyte, 0); bit.nwords = conf.nbitbyte/sizeof(ulong); bit.wfree = bit.words; cursortobitmap(); Cursortocursor(&arrow); } void @@ 148,6 151,9 @@ bitinit(void) { lock(&bit); unlock(&bit); if(screen.ldepth > 1) panic("bitinit ldepth>1"); cursorback.ldepth = screen.ldepth; cursoron(1); } @@ 192,6 198,7 @@ bitopen(Chan *c, int omode) bit.lastid = -1; bit.init = 1; bit.ref = 1; Cursortocursor(&arrow); unlock(&bit); }else incref(&bit); @@ 341,6 348,7 @@ bitwrite(Chan *c, void *va, long n) int off; Point pt; Rectangle rect; Cursor curs; Bitmap *bp, *src, *dst; if(c->qid == CHDIR) @@ 368,7 376,7 @@ bitwrite(Chan *c, void *va, long n) if(m < 18) error(0, Ebadblt); v = *(p+1); if(v != 0) /* BUG */ if(v!=0 && v!=1) /* BUG */ error(0, Ebadblt); ws = 1<<(5-v); /* pixels per word */ if(bit.free == 0) @@ 385,9 393,9 @@ bitwrite(Chan *c, void *va, long n) l = (t+rect.max.x+ws-1)/ws; } nw = l*Dy(rect); if(bit.wfree+l+2 > bit.words+bit.nwords){ if(bit.wfree+2+nw > bit.words+bit.nwords){ bitcompact(); if(bit.wfree+l+1 > bit.words+bit.nwords) if(bit.wfree+2+nw > bit.words+bit.nwords) error(0, Enobitstore); } bp = bit.free; @@ 453,6 461,36 @@ bitwrite(Chan *c, void *va, long n) p += 31; break; case 'c': /* * cursorswitch * 'c' 1 * nothing more: return to arrow; else * Point 8 * clr 32 * set 32 */ if(m == 1){ cursoroff(1); Cursortocursor(&arrow); cursoron(1); m -= 1; p += 1; break; } if(m < 73) error(0, Ebadblt); curs.offset.x = GLONG(p+1); curs.offset.y = GLONG(p+5); memcpy(curs.clr, p+9, 2*16); memcpy(curs.set, p+41, 2*16); cursoroff(1); Cursortocursor(&curs); cursoron(1); m -= 73; p += 73; break; case 'f': /* * free @@ 502,7 540,7 @@ bitwrite(Chan *c, void *va, long n) error(0, Ebadblt); if(off) cursoroff(1); string(dst, pt, &defont0/*BUG*/, (char*)p, v); string(dst, pt, defont/*BUG*/, (char*)p, v); if(off) cursoron(1); q++; @@ 622,7 660,7 @@ biterrstr(Error *e, char *buf) void bitfree(Bitmap *bp) { bp->base[1] = 0; bp->base[-1] = 0; bp->ldepth = -1; bp->base = (ulong*)bit.free; bit.free = bp; @@ 633,7 671,6 @@ bitcompact(void) { ulong *p1, *p2; print("bitcompact\n"); p1 = p2 = bit.words; while(p2 < bit.wfree){ if(p2[1] == 0){ @@ 648,18 685,18 @@ print("bitcompact\n"); p1 += 2 + p1[0]; } bit.wfree = p1; print("bitcompact done\n"); } void cursortobitmap(void) Cursortocursor(Cursor *c) { int i; lock(&cursor); memcpy(&cursor, c, sizeof(Cursor)); for(i=0; i<16; i++){ setbits[i] = cursor.set[i]<<16; clrbits[i] = cursor.clr[i]<<16; setbits[i] = (c->set[2*i]<<24) + (c->set[2*i+1]<<16); clrbits[i] = (c->clr[2*i]<<24) + (c->clr[2*i+1]<<16); } unlock(&cursor); } @@ 711,7 748,6 @@ void mouseclock(void) /* called spl6 */ { int x, y; if(mouse.track && canlock(&cursor)){ x = mouse.xy.x + mouse.dx; if(x < screen.r.min.x)
M port/sturp.c => port/sturp.c +3 -2