(pat) This is the main service loop for the entire GPRS subsystem. It processes in time increments of one radio block time unit (4 or 5 GSM frames), about 18 ms. We only use one thread, so no additional locks needed in the entire GPRS code beyond those in the i/o queues. It is attached to the L1 layer below via thread-safe queues in the L1Encoder/L2Decoder classes attached to each PCH (packet phys
| 2388 | // and feed multiple channels simultaneously. |
| 2389 | // |
| 2390 | void L2MAC::macServiceLoop() |
| 2391 | { |
| 2392 | double starttime = 0; // useless initialization to shut up gcc. |
| 2393 | GPRSLOG(16) << "macServiceLoop:" << LOGVAR(gBSNNext); |
| 2394 | |
| 2395 | if (GPRSDebug) { starttime = timef(); } |
| 2396 | mac_debug(); |
| 2397 | |
| 2398 | // Step: Each incoming RACH will need a single block assignment. |
| 2399 | // We do this first because if no channels are assigned to GPRS, |
| 2400 | // this will allocate the first GPRS channel as a side effect. |
| 2401 | macServiceRachQ(); |
| 2402 | GPRSLOG(16) << "macServiceLoop: after serviceRachQ"; |
| 2403 | |
| 2404 | // Step: Maybe add or free some radio channels. |
| 2405 | macCheckChannels(); |
| 2406 | |
| 2407 | // Step: Process uplink RadioBlocks from the last timeslot. |
| 2408 | // Do this first because it may change TBF states so that they have |
| 2409 | // downlink messages to send. |
| 2410 | PDCHL1FEC *pdch; |
| 2411 | RN_MAC_FOR_ALL_PDCH(pdch) { // for all channels assigned to GPRS. |
| 2412 | pdch->debug_test(); |
| 2413 | while (RLCRawBlock *src = pdch->uplink()->mchUplinkData.readNoBlock()) { |
| 2414 | processUplinkBlock(pdch,src); |
| 2415 | delete src; |
| 2416 | } |
| 2417 | } |
| 2418 | |
| 2419 | GPRSLOG(16) << "macServiceLoop: after uplink service"; |
| 2420 | |
| 2421 | // Step: Service unattached TBFs. (An attached TBF has resources |
| 2422 | // assigned to its MS. Attached TBFs are handled by dlService().) |
| 2423 | // This could have been combined in servicing the MS, |
| 2424 | // but efficiency is not an issue and this seems more clear. |
| 2425 | // Be a little careful since we are deleting from the list we are iterating. |
| 2426 | { |
| 2427 | TBF *tbf; |
| 2428 | RN_MAC_FOR_ALL_TBF(tbf) { |
| 2429 | // This call may remove the tbf from the list being iterated: |
| 2430 | tbf->mtServiceUnattached(); |
| 2431 | } |
| 2432 | } |
| 2433 | |
| 2434 | // Step: Service the MSs; they may want to start new TBFs. |
| 2435 | MSInfo *ms; |
| 2436 | RN_MAC_FOR_ALL_MS(ms) { |
| 2437 | ms->msService(); |
| 2438 | } |
| 2439 | GPRSLOG(16) << "macServiceLoop: after ms service"; |
| 2440 | |
| 2441 | // Step: Feed each downlink PDCH with RadioBlocks. |
| 2442 | // As a side effect, this services all the [connected] TBFs in round robin order. |
| 2443 | extDyn.edReset(); |
| 2444 | RN_MAC_FOR_ALL_PDCH(pdch) { // for all channels assigned to GPRS. |
| 2445 | extDyn.edSetCn(pdch->CN()); |
| 2446 | pdch->downlink()->dlService(); |
| 2447 | } |
no test coverage detected