250 likes | 265 Views
Implementing Remote Procedure Calls. Andrew Birrell and Bruce Nelson. Presented by Phil Howard. Why?. Consider. #include <stdio.h> int main() { printf("hello world!<br>"); return 0; }. What Happens. main. main. printf glibc. kernel IO kernel. update_window X
E N D
Implementing Remote Procedure Calls Andrew Birrell and Bruce Nelson Presented by Phil Howard
Consider #include <stdio.h> int main() { printf("hello world!\n"); return 0; }
What Happens main main printf glibc kernel IO kernel update_window X update_display kernel IO kernel
But what if Laptop Linux Box X Client X Server Console Window main
What Happens Laptop Linux Box main main X Client printf glibc update_display X kernel IO kernel kernel IO kernel update_window X update_display
How do you do this? • Fork/Join • SendMessage/AwaitReply • Remote Procedure Call
What's Involved in RPC • Remote Procedure Call should look and feel like local call • Remote Procedure Call should be independent of where it executes • Remote Procedure Call should be "efficient"
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Finding the Callee(Binding) • Where • Server has known static address • Client broadcasts request • Central database of interfaces • What • Servers export named interfaces • Clients request a particular interface • Need Globally Unique Identifiers for interfaces
Passing Data • Can't use the stack • Can't use shared memory • Generally use message passing
Passing Data #include <stdio.h> int main() { union { unsigned long stuff1; unsigned char stuff2[4]; } my_var; my_var.stuff1 = 0x12345678; printf("%X %X %X %X\n", my_var.stuff2[0], my_var.stuff2[1], my_var.stuff2[2], my_var.stuff2[3]); return 0; }
Passing Data What's the output? • 12 34 56 78 • or • 78 56 34 12
Passing data Build a message that includes: • Who and what's being called • Identity of the caller • Data values in known byte order
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Implementation foo(a,&b) foo(int a, int *b) return;
Implementation • foo(int a; int *b) • { • build_msg(a,b); • send_msg(); • wait_for_reply(); • get_from_msg(&b); • } • do_foo(msg_t msg) • { • int a,b; • get_from_msg(&a,&b); • foo(a,&b); • build_msg(b); • send_reply(); • }
Implementation • Function prototype is (almost) all that's needed to build the client stub • Also need binding information • Function prototype is (almost) all that's needed to build server stuf • Also need method to wait for message
Implementation • Clients • Threaded • Servers • Event Driven
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
ExceptionsWhat can happen in "normal" procedures? • Procedure generates an exception • Procedure infinite loops • Procedure generates wrong results
ExceptionsWhat can happen in "remote" procedures? • Client stub generates exception • Transmission failure • knowable failure • unknowable failure • Remote procedure generates an exception • Remote procedure infinite loops • Remote procedure generates wrong results
Optimizations • Servers maintain no state on clients • No penalty for a large number of clients • Messages must be ack'd • for short calls, result serves as ack • for frequent calls, next call ack's last result • for long requests, only last request msg gets ack'd • for long results, only last result msg gets ack'd • Bound to "closest" server • Minimum transmission delay
Conclusion • Remote Procedure Call should look and feel like local call • Remote Procedure Call should be independent of where it executes • Remote Procedure Call should be "efficient"