| 1 | == セルタイプコードでのアロケータ == |
| 2 | |
| 3 | シグニチャの関数の引数の基本指定子として send または receive を指定すると、引数としてアロケータによりアロケートされたメモリ領域のアドレスが渡されます。 |
| 4 | 渡されたメモリ領域は、受け取った側で解放します。 |
| 5 | |
| 6 | send 指定された引数の場合、呼び元でアロケートし、呼び先でデアロケートします。 |
| 7 | receive 指定された引数の場合、呼び先でアロケートし、呼び元でデアロケートします。 |
| 8 | アロケート、デアロケート操作は、アロケータ呼び口を通して行います。 |
| 9 | |
| 10 | === アロケータ呼び口 === |
| 11 | |
| 12 | TECS では、メモリアロケータをセルとして実装しますが、アロケータセルの受け口に結合する呼び口が必要となります。 |
| 13 | この呼び口のことをアロケータ呼び口と呼びます。 |
| 14 | アロケータ呼び口は TECS CDL に明示的に記述しません。TECS ジェネレータにより生成されます。 |
| 15 | |
| 16 | アロケータ呼び口には、以下の名前が与えられます。 |
| 17 | |
| 18 | {{{ |
| 19 | (アロケータ呼び口名) = (呼び口名または受け口名) + '_' + (関数名) + '_' + (引数名) |
| 20 | }}} |
| 21 | |
| 22 | === アロケータ使用の具体例 === |
| 23 | |
| 24 | 以下に、アロケータを使用する例を示します。 |
| 25 | |
| 26 | TECS CDL のコード例には、呼び先のセルタイプおよびセル、呼び元のセルタイプおよびセルが実装されているとします。 |
| 27 | ジェネレータによって呼び先および呼び元の双方に、アロケータ呼び口およびその結合が自動的に挿入されます。 |
| 28 | |
| 29 | 【TECS CDL 記述例】 |
| 30 | {{{ |
| 31 | signature sSendRecv { |
| 32 | /* この関数名に send, receive を使ってしまうと allocator 指定できない */ |
| 33 | ER snd( [send(sAlloc),size_is(sz)]int8 *buf, [in]int32 sz ); |
| 34 | ER rcv( [receive(sAllocTMO),size_is(*sz)]int8 **buf, [out]int32 *sz ); |
| 35 | }; |
| 36 | |
| 37 | celltype tTestComponent { |
| 38 | entry sSendRecv eS; |
| 39 | }; |
| 40 | |
| 41 | // 受け口側で、send/receive 指定された引数ごとにアロケータを指定 |
| 42 | [allocator(eS.snd.buf=alloc.eA,eS.rcv.buf=alloc.eA)] |
| 43 | cell tTestComponent comp{ |
| 44 | }; |
| 45 | |
| 46 | celltype tTestClient { |
| 47 | call sSendRecv cS; |
| 48 | }; |
| 49 | |
| 50 | // 呼び口側では、アロケータを指定しない |
| 51 | cell tTestClient cl { |
| 52 | cS = comp.eS; |
| 53 | }; |
| 54 | }}} |
| 55 | |
| 56 | 【アロケータ呼び口が挿入されたコード(TECS ジェネレータにより内部生成された状態)】 |
| 57 | |
| 58 | 以下のコードは、内部状態を説明するためのものであって、以下のような TECS CDL コードを記述するものではありません。 |
| 59 | |
| 60 | {{{ |
| 61 | celltype tTestComponent { |
| 62 | entry sSendRecv eS; |
| 63 | |
| 64 | /* 自動生成されたアロケータ呼び口 */ |
| 65 | call sAlloc cS_snd_buf; <<< 自動生成された呼び口 |
| 66 | call sAlloc cS_rcv_buf; <<< 自動生成された呼び口 |
| 67 | }; |
| 68 | |
| 69 | [allocator(eS.snd.buf=alloc.eA,eS.rcv.buf=alloc.eA)] |
| 70 | cell tTestComponent comp{ |
| 71 | |
| 72 | /* 自動生成されたアロケータ呼び口の結合 */ |
| 73 | eS_snd_buf = alloc.eA; <<< 自動生成された結合 |
| 74 | eS_rcv_buf = alloc.eA; <<< 自動生成された結合 |
| 75 | }; |
| 76 | |
| 77 | celltype tTestClient { |
| 78 | call sSendRecv cS; |
| 79 | |
| 80 | /* 自動生成されたアロケータ呼び口 */ |
| 81 | call sAlloc cS_snd_buf; <<< 自動生成された呼び口 |
| 82 | call sAlloc cS_rcv_buf; <<< 自動生成された呼び口 |
| 83 | }; |
| 84 | |
| 85 | cell tTestClient cl { |
| 86 | cS = comp.eS; |
| 87 | |
| 88 | /* 自動生成されたアロケータ呼び口の結合 */ |
| 89 | cS_snd_buf = alloc.eA; <<< 自動生成された結合 |
| 90 | cS_rcv_buf = alloc.eA; <<< 自動生成された結合 |
| 91 | }; |
| 92 | }}} |
| 93 | |
| 94 | セルタイプ tTestClient の呼び口 cS の関数の send, receive 指定された引数に対して、以下のようなアロケータ呼び口関数が、生成されます。 |
| 95 | アロケート関数、デアロケート関数の両方が使用できますが、send 指定された引数の場合、通常、呼び元で使用する必要があるのは、アロケート関数です。 |
| 96 | rceive 指定された引数の場合は、デアロケート関数です。 |
| 97 | |
| 98 | {{{ |
| 99 | // allocator port for call port: cS func: send param: buf |
| 100 | ER cS_snd_buf_alloc( int32_t size, void** p ); |
| 101 | ER cS_snd_buf_dealloc( const void* p ); |
| 102 | // allocator port for call port: cS func: receive param: buf |
| 103 | ER cS_rcv_buf_alloc( int32_t size, void** p ); |
| 104 | ER cS_rcv_buf_dealloc( const void* p ); |
| 105 | // allocator port for call port: cA func: send param: buf |
| 106 | ER cA_snd_buf_alloc( subscript, int32_t size, void** p ); |
| 107 | ER cA_snd_buf_dealloc( subscript, const void* p ); |
| 108 | // allocator port for call port: cA func: receive param: buf |
| 109 | ER cA_rcv_buf_alloc( subscript, int32_t size, void** p ); |
| 110 | ER cA_rcv_buf_dealloc( subscript, const void* p ); |
| 111 | }}} |
| 112 | |
| 113 | セルタイプ tTestComponent の受け口 eS の関数の send, receive 指定された引数に対しても、同様なアロケータ呼び口関数が、生成されます。 |
| 114 | |
| 115 | 【未決定事項】アロケータを一々使い分けるのは、誤りのもとである。まとめる手段が必要。 |
| 116 | |
| 117 | === アロケータの例 === |
| 118 | |
| 119 | アロケータセルの例を以下に示します。 |
| 120 | |
| 121 | 【TECS CDL 記述例】 |
| 122 | {{{ |
| 123 | signature sAlloc { |
| 124 | ER alloc( [in]size_t len, [out]void *p ); |
| 125 | ER dealloc( [in]void *p ); |
| 126 | }; |
| 127 | |
| 128 | celltype tAlloc { |
| 129 | entry sAlloc eA; |
| 130 | }; |
| 131 | |
| 132 | cell alloc { |
| 133 | }; |
| 134 | }}} |
| 135 | |
| 136 | === リレーアロケータ === |
| 137 | |
| 138 | リレーアロケータの TECS CDL 記述例を示します。 |
| 139 | |
| 140 | 【TECS CDL 記述例】 |
| 141 | {{{ |
| 142 | signature sSendRecv { |
| 143 | /* この関数名に send, receive を使ってしまうと allocator 指定できない */ |
| 144 | ER snd( [send(sAlloc),size_is(sz)]int8_t *buf, [in]int32_t sz ); |
| 145 | ER rcv( [receive(sAlloc),size_is(*sz)]int8_t **buf, [out]int32_t *sz ); |
| 146 | }; |
| 147 | |
| 148 | celltype tThroughComponent { |
| 149 | [allocator( /* 受け口から呼び口へリレー */ |
| 150 | snd.buf <= cSR.snd.buf, /* cSR:前方参照可能 */ |
| 151 | rcv.buf <= cSR.rcv.buf |
| 152 | )] |
| 153 | entry sSendRecv eS; |
| 154 | call sSendRecv cSR; |
| 155 | }; |
| 156 | |
| 157 | /* セルの定義で、受け口の send/receive 指定された引数のアロケータ指定不要 */ |
| 158 | cell tThroughComponent comp{ |
| 159 | cSR = TargetCell.eS; /* TargetCell で allocator 指定が必要 */ |
| 160 | }; |
| 161 | }}} |
| 162 | |
| 163 | リレーアロケータの場合も、上述のアロケータの例と同様に、アロケータ呼び口と結合が生成されます。 |
| 164 | tThroughComponent のセルタイプコードでは、以下のアロケータ呼び口関数が生成されます。 |
| 165 | ただし、受け取ったものをそのまま渡すため、これらの呼び口関数は、実際には使用する必要はありません。 |
| 166 | もし、受け取ったものをそのまま渡すのではなく、再アロケート(reallc) するような場合には、これらの呼び口を用いることになります。 |
| 167 | (この例では realloc は含まれません) |
| 168 | |
| 169 | {{{ |
| 170 | // allocator port for call port: eA func: snd param: buf |
| 171 | ER eA_snd_buf_alloc( subscript, int32_t size, void** p ); |
| 172 | ER eA_snd_buf_dealloc( subscript, const void* p ); |
| 173 | // allocator port for call port: eA func: rcv param: buf |
| 174 | ER eA_rcv_buf_alloc( subscript, int32_t size, void** p ); |
| 175 | ER eA_rcv_buf_dealloc( subscript, const void* p ); |
| 176 | // allocator port for call port: eS func: snd param: buf |
| 177 | ER eS_snd_buf_alloc( int32_t size, void** p ); |
| 178 | ER eS_snd_buf_dealloc( const void* p ); |
| 179 | // allocator port for call port: eS func: rcv param: buf |
| 180 | ER eS_rcv_buf_alloc( int32_t size, void** p ); |
| 181 | ER eS_rcv_buf_dealloc( const void* p ); |
| 182 | // allocator port for call port: cSR func: snd param: buf |
| 183 | ER cSR_snd_buf_alloc( int32_t size, void** p ); |
| 184 | ER cSR_snd_buf_dealloc( const void* p ); |
| 185 | // allocator port for call port: cSR func: rcv param: buf |
| 186 | ER cSR_rcv_buf_alloc( int32_t size, void** p ); |
| 187 | ER cSR_rcv_buf_dealloc( const void* p ); |
| 188 | }}} |
| 189 | |
| 190 | ------------ |
| 191 | [TECS リファレンスマニュアル [wiki: トップ]] |
| 192 | [TECS コンポーネント実装リファレンスマニュアル [wiki:IMPref トップ]・[wiki:IMPref_index 目次]]] |