Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!ginosko!brutus.cs.uiuc.edu!apple!netcom!hue From: hue@netcom.UUCP (Jonathan Hue) Newsgroups: comp.os.mach Subject: Mach context switch time Message-ID: <2895@netcom.UUCP> Date: 12 Oct 89 04:54:03 GMT Organization: NetCom- The Bay Area's Public Access Unix System {408 997-9175 guest} Lines: 94 > Mean real time per context switch, corresponding context switch rate: > > PDP-11/45 EPOS 170 usec 5,882 / sec > DECStation 3100 ULTRIX 2.0 R7 390 2,654 > Sun 4/280 SunOs Sys4-3.2R2 623 1,605 > VAX 8650 BSD 4.3 723 1,383 > NeXt MACH 873 1,145 The following program executes the loop 10000 times in 7.3 seconds on a NeXT. Each time through the loop is 2 context switches, so this works out to 2740 context switches/sec, or 365us per context switch. #include #include #include #include struct mymsg { msg_header_t my_header; msg_type_t my_type; }; main(argc, argv) int argc; char **argv; { register int iterations=1; register kern_return_t error; port_t port, newport; unsigned int num_ports; struct mymsg msg; port_t port_set[10]; port_array_t new_set; if (argc == 2) iterations = atoi(*++argv); if ((error = port_allocate(task_self(), &port)) != KERN_SUCCESS) mach_error("port_allocate", error); if ((error = port_set_backlog(task_self(), port, 10)) != KERN_SUCCESS) mach_error("port_set_backlog", error); port_set[0] = port; mach_ports_register(task_self(), port_set, 1); switch (fork()) { case -1: perror("fork"); exit(1); case 0: mach_ports_lookup(task_self(), &new_set, &num_ports); port = *new_set; msg.my_header.msg_remote_port = port; if ((error = port_allocate(task_self(), &newport)) != KERN_SUCCESS) mach_error("port_allocate", error); msg.my_header.msg_remote_port = port; msg.my_header.msg_local_port = newport; msg.my_header.msg_id = 0xc0ffee; msg.my_header.msg_size = sizeof(msg); msg.my_header.msg_type = MSG_TYPE_NORMAL; msg.my_header.msg_simple = TRUE; msg.my_type.msg_type_name = MSG_TYPE_INTEGER_32; msg.my_type.msg_type_size = 32; msg.my_type.msg_type_number = 0; msg.my_type.msg_type_inline = TRUE; msg.my_type.msg_type_longform = FALSE; msg.my_type.msg_type_deallocate = FALSE; while (--iterations != -1) { if ((error = msg_rpc(&(msg.my_header), SEND_SWITCH, sizeof(msg), 0, 0)) != RPC_SUCCESS) mach_error("msg_send", error); } exit(0); default: msg.my_header.msg_local_port = port; msg.my_header.msg_size = sizeof(msg); while (--iterations != -1) { if ((error = msg_receive(&(msg.my_header), MSG_OPTION_NONE, 0)) != RCV_SUCCESS) mach_error("msg_receive", error); if ((error = msg_send(&(msg.my_header), SEND_SWITCH, 0)) != SEND_SUCCESS) mach_error("msg_receive", error); } break; } wait(0); } -Jonathan