1 | Tasks |
---|
2 | |
---|
3 | Headers: |
---|
4 | Typedefs |
---|
5 | |
---|
6 | Prototypes (per-interface, per-operation, per-type). |
---|
7 | |
---|
8 | Common: |
---|
9 | Allocation & freeing (per-type). |
---|
10 | |
---|
11 | Stubs: |
---|
12 | Stubs (per-operation) |
---|
13 | Short-circuiting |
---|
14 | Setup |
---|
15 | Marshalling |
---|
16 | Exception & location_forward handling |
---|
17 | Sending |
---|
18 | Receiving |
---|
19 | Freeing/allocating values |
---|
20 | Demarshalling |
---|
21 | Return |
---|
22 | |
---|
23 | Skeletons: |
---|
24 | Skeletons (per-operation) |
---|
25 | Allocating values |
---|
26 | Demarshalling |
---|
27 | Call |
---|
28 | Setup for reply |
---|
29 | Exception handling |
---|
30 | Marshalling |
---|
31 | Sending |
---|
32 | Freeing values |
---|
33 | Return |
---|
34 | |
---|
35 | |
---|
36 | (de)marshalling tasks |
---|
37 | |
---|
38 | All (de)marshalling tasks can be represented using the following type of data |
---|
39 | structure (PIDL): |
---|
40 | union MarshalNode switch(NodeType) { |
---|
41 | case VALUE: { |
---|
42 | string variable_name; |
---|
43 | short value_length; |
---|
44 | } |
---|
45 | case CONSTANT: { |
---|
46 | long value; |
---|
47 | } |
---|
48 | case ARRAY: { |
---|
49 | string pointer_name; |
---|
50 | MarshalNode num_entries; |
---|
51 | } |
---|
52 | |
---|
53 | IDL_tree corresponding_idl_node; |
---|
54 | }; |
---|
55 | |
---|
56 | Need to make a data structure that better represents "what we need to do" |
---|
57 | rather than "what we are working on". Something that can say "(de)marshal |
---|
58 | value|increment a pointer|loop back"... Optimization on this will be somewhat |
---|
59 | easier. |
---|
60 | |
---|
61 | /* In skels: If not sending a reply back, don't get a send_buffer |
---|
62 | unless we need to raise an exception. */ Incorrect - for any given op |
---|
63 | you either always need to send something back, or never. |
---|
64 | |
---|
65 | Pieces of a stub (prerequisite steps are in []'s): |
---|
66 | Pre: If ev == NULL, bomb out. |
---|
67 | 1. Sanity check params (and handle exceptions). |
---|
68 | 2. Check for & handle local call. [1] |
---|
69 | 3. Get connection (and handle exceptions). [1] |
---|
70 | 4. Get send buffer (is it possible for any exceptions to be raised here?). |
---|
71 | 5. Marshal params. [1, 4] |
---|
72 | 6. Write send buffer (and handle exceptions). [5] |
---|
73 | 7. Unuse send buffer. [6] |
---|
74 | 8. Receive reply (and handle exceptions). [6] |
---|
75 | 9. Do any necessary location forwarding & exception handling. [8] |
---|
76 | 10. Allocate any needed memory for retvals. |
---|
77 | 11. Demarshal retvals (with versions for endianness) (and handle exceptions). [9, 10] |
---|
78 | 12. Unuse receive buffer. [11] |
---|
79 | 13. Return. [11] |
---|
80 | |
---|
81 | Could swap 2 & 3, or 7 & 8. 11 & 12 can't be swapped due to 12's flow |
---|
82 | changing effects :-). Don't want to swap 2 & 3 - don't do remote stuff |
---|
83 | it is local. 7 & 8 just maybe could be swapped, but not sure it makes much sense. |
---|
84 | |
---|
85 | Pieces of a skeleton (prerequisite steps are in []'s): |
---|
86 | 0. Allocate any needed memory for params. |
---|
87 | 1. Demarshal (with versions for endianness) (and handle exceptions). [0] |
---|
88 | 2. Call impl. [1] |
---|
89 | 3. Get send reply buffer (can this raise any exceptions?). [2] |
---|
90 | 4. If no exceptions raised: |
---|
91 | Marshal retvals. [3] |
---|
92 | else marshal exceptions. [3] |
---|
93 | 5. Write send buffer (and handle exceptions). [4] |
---|
94 | 6. Unuse send buffer. |
---|
95 | |
---|
96 | No pipelining possible in skeletons. |
---|
97 | |
---|
98 | Actually, should integrate memory allocation with demarshalling - it'd |
---|
99 | be cleaner to do (if not a little more space wasting when it comes to |
---|
100 | dual versions for endianness). |
---|
101 | |
---|
102 | You can marshal multi-element pieces of structs. |
---|
103 | |
---|
104 | In skels: If not sending a reply back, don't get a send_buffer unless |
---|
105 | we need to raise an exception. |
---|
106 | |
---|
107 | When demarshalling, maintain a local 'cur' pointer rather than modifying |
---|
108 | the one inside the receive buffer. Will need to update the one inside the |
---|
109 | rbuf if we call a complex demarshaller thing. |
---|
110 | |
---|
111 | Reduce amount of code in stubs by having send_buffer_use() return the |
---|
112 | request_id as part of its operation, instead of having to get a new |
---|
113 | request_id as part of the stub. |
---|
114 | |
---|
115 | Use function pointers instead of a series of if's to speed things up. |
---|
116 | |
---|
117 | Pre-computation of alignment for stuff that can be pre-computed (like |
---|
118 | operation name vecs, etc.) |
---|
119 | |
---|
120 | For multithreading speedups, don't lock the connection until we actually need to send. |
---|