# 2019q1 第 11 週測驗題 (上)
:::info
目的: 檢驗學員對 mmap 系統呼叫及對應記憶體管理的認知
:::
---
### 測驗 `1`
考慮到 [cirbuf](https://github.com/sysprog21/cirbuf) 這個 [circular buffer](https://en.wikipedia.org/wiki/Circular_buffer) 實作,嘗試透過 mmap 系統來化簡緩衝區邊界處理的議題。對照 [cirbuf.h](https://github.com/sysprog21/cirbuf/blob/master/cirbuf.h) 和 [test-cirbuf.c](https://github.com/sysprog21/cirbuf/blob/master/tests/test-cirbuf.c) 以得知具體用法,請補完以下程式碼:
```cpp
static inline int cirbuf_offer(cirbuf_t *cb,
const unsigned char *data,
const int size)
{
/* prevent buffer from getting completely full or over commited */
if (cirbuf_unusedspace(cb) <= size)
return 0;
int written = cirbuf_unusedspace(cb);
written = size < written ? size : written;
memcpy(cb->data + cb->tail, data, written);
cb->tail += written;
MM1
return written;
}
static inline unsigned char *cirbuf_peek(const cirbuf_t *cb)
{
if (cirbuf_is_empty(cb))
return NULL;
MM2
}
```
==作答區==
MM1 = ?
* `(a)` if (cb->size > cb->tail) cb->tail = 0;
* `(b)` if (cb->size < cb->tail) cb->tail = 0;
* `(c)` if (cb->size < cb->tail) cb->tail -= cb->size;
* `(d)` if (cb->size < cb->tail) cb->tail %= cb->size;
* `(e)` if (cb->size < cb->tail) cb->tail++;
* `(f)` if (cb->size < cb->tail) cb->size = 0;
MM2 = ?
* `(a)` return cb->data;
* `(b)` returb cb->head;
* `(c)` returb cb->data + cb->head;
* `(d)` return NULL;
:::success
延伸問題:
1. 解析 test suite 運作原理,嘗試強化現有 cirbuf 的例外處理機制,並且實作於 unit test 內部;
2. 儘管已有 12 個 test case,但涵蓋層面仍不夠廣泛,請指出現有實作的缺陷並著手改善; (提示: 數值範圍及多個 PAGE_SIZE 的空間)
3. 學習 [Using black magic to make a fast circular buffer](https://lo.calho.st/quick-hacks/employing-black-magic-in-the-linux-page-table/),指出 fast circular buffer 實作的技巧,並分析 cirbuf 的效能,並逐步量化及改善效率;
4. 向 OP-TEE 的 [Benchmark framework](https://optee.readthedocs.io/debug/benchmark.html) 取鏡,學習效能評比框架的開發;
:::
---