semaphore sem_post 在 glibc v2.0 v2.1 之比較

前言

在翻 futex man document 的時候,不小心看到 Linux Futex的设计与实现 這篇文章。文章中有提到在執行 sem_post 的時候,雖然沒有與其他 thread 競爭,還是會用到 fuxtex system call。當然文章中有提到原因,不過看了原因,覺得這看起來很明顯的效能問題,應該會被提出來並改進吧?後來翻了一下目前的 source code ,看到這個是 GLIBC_2_0 的版本(那篇文章也很久了,所以能想見當時的版本應該蠻舊的),而現在 GLIBC_2_1 就有把這部分改進,因此就來簡單記錄一下差異在哪裡吧~

Version

glibc 2.29

GLIBC_2_0 version

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int attribute_compat_text_section __old_sem_post (sem_t *sem)
{
  int *futex = (int *) sem;
  atomic_write_barrier ();
  (void) atomic_increment_val (futex);
  int err = lll_futex_wake(futex, 1, LLL_SHARED);
  if (__builtin_expect (err, 0) < 0)
    {
      __set_errno (-err);
      return -1;
    }
  return 0;
}

從 source code 可以看到,在將 sem value + 1 後,就直接使用 lll_futex_wake 呼叫 futex wake system call,其原因在文章內也有提到,是因為當 sem value 加 1 後,當時的機制並無法確認是否有其他 thread 正在 wait。

Read more →

2019/07月份自我學習回顧

前言

時間超快地又到了八月了~七月整個月天氣都蠻悶熱的,加上小套房也不是很通風,想要好好在房間念書就只能一直開冷氣,偶爾再去金山街星巴克當假文青。除了進修之外,還跟公司旅遊補助團去了一趟高雄、台南小旅行,去高雄的那天剛好遇到輕颱大淹水,在開高速公路的時候,風雨交加,旁邊的大遊覽車不斷踩水激起大浪花,整個過程蠻膽戰心驚,深怕一個不注意會發生意外,幸好還是平安回來了。

![study]({{ site.url }}/assets/images/study-2019-07.jpg)

學習部分,七月份其實吸收蠻多內容的,收穫滿滿,可惜因為時間關係,筆記大多很潦草,還不足以登上檯面,就沒有放在 blog 上了。七月份學到最多的就是 Linux kernel 和 network 相關知識,而其中印象讓我深刻的是,我在學習過程中遇到一個不太確定的問題,因此花時間在查閱相關內容並找答案,那時候心中覺得這個答案可能是正確的,但是基於經驗不足的關係,還是去請教了韌體相關的資深同事,結果他給了我一個完全不同方向的答案。這令我蠻訝異的,因為我的確沒想到會不同方向的思考路線,也讓我在後續學習時更加注意各面向的思考。不過會導致這原因,深究起來還是對於 kernel 理論不夠熟悉的緣故,所以在學習中加入了 Linux kernel development 書籍,希望能多加深理論基礎。

七月份接觸蠻多種議題,包含工作上的 Security, network package filter, kernel module 等,在過程中多少會擔心自己是不是會迷失了學習方向。不過幸好在最後實作 side project 時,這些學習都有互相應用,整體來說吸收不錯,八月份也會繼續努力 :D

預定目標回顧

根據七月初紀錄,七月要完成的目標包含:

1. 使用正規做法來實作 File System (super_block, inodetable, bitmap..)並與 FUSE lib 連接。

這個項目完成50%,包含 disk simulator 和 file system structure,過程中參考蠻多 ext4,希望能一併學習到 ext4 的實作理念。不過後來之所以慢下腳步,是因為做到一半需要 synchronization 相關知識,而在 Linux kernel 中 Locks 的種類分比較細,因此後來注意力就轉移到 synchronization 實作原理和應用上了。目前是打算把 Linux kernel development 看完,再回到這個 side project 上繼續實作。

Read more →

2019/06月份自我學習回顧

前言

六月份安排了一趟北海道旅遊,因此整體唸書時間相較少些。北海道旅遊中,在富良野鄉村地區待了兩日,雖然只有短短時間,但卻讓我體驗到完全不同的生活環境,遼闊無際的花園農田、路上慢步行走的當地居民們、以及寬廣的生活空間,都令人非常嚮往。我很喜歡在都市的緊湊步調,跟公司同事們努力開發以及學習各種新知原理的過程,但有時候也會想過過這種悠閒沒有太多物質壓力的人生,可能是自己從來沒有過如此的生活方式,所以會有種美麗的幻想吧。

學習部分,六月份的專注力明顯好很多,因此整體自學的時數有變多,也覺得自己成長了不少。主要原因是因為這個月花了更多時間在學習 linux 以及看 linux kernel source code,有感覺到自己對於作業系統是有比較多興趣的,會自主投入很多時間在理解原理和實驗上。不過因為在看 linux 會碰到很多數學相關的優化內容,因此數學訓練還是要維持固定的進度。

有時候會覺得,這年紀才覺得自己對 linux kernel 有興趣並且學習,還來得及嗎?看看那些研究所學生,他們早就學習了好幾年相關知識,就算很努力也不能追趕上他們。但是回過頭來想,如果不去試試看,怎麼知道自己能不能成為對 linux kernel 略懂的那群人。雖然可能不能成為這領域的頂尖人才,不過至少自己學習過了,而這些基礎知識也可以用在未來工作上。不能要求時間重來,但至少不要留下遺憾是吧 :)

預定目標回顧

根據六月初紀錄,六月要完成的目標包含:

  • 數學歸納法和數論。這個算是有點意外,因為自己沒注意到線上課程大綱,所以其實是上一系列 Pigeonhole PrincipleCounting 內容。整體來看算是有進度,只是上的內容和預計不同。

  • Linux 核心設計: 朝向硬即時的核心變革(20%)。本來預計要把線上講座再聽一次,但在檔案系統概念花了比預期還多的複習時間,所以講座內容大概只複習 20%。可能的改善方式就是拉長所需的複習時間,因為講座的內容實在太多,投入很多時間是必然的,不需要強迫自己硬要在短時間內看完。

  • FUSE實作(70%)。除了把基本 FUSE API(high level and low level) 使用並且實驗過之外,還有細部看 FUSE 的實現流程與 source code。並且也同時複習 Virtual File System 的架構和實現方式。因此這部分的進度算是比較多,不過只給自己 70%,因為沒有生出一個較完整的 side-project。

    Read more →

Side Project for daily study trello

![study]({{ site.url }}/assets/images/side-project.png)

前言

用 Trello 紀錄自己的每日學習進度也好一陣子了,雖然 Trello board 搭配 plugin Calendar 很好用,但是卻有資訊分散在各張卡的問題。因此為了便於在月末寫當月學習報告,以及整理所有曾經讀過的 article/post link,就開發了一個小工具 trello-transform 來從 trello cards 中擷取資訊。其實這個 side project 寫了有一段時間了,之前曾經立志要寫一個有前後端的小網站,這樣不會寫 code 的人也可以使用,但是後來就有點擱置了 XD 原因是我把這個功能寫成一個小框架,以因應每個人紀錄習慣不同,不過這樣的調整就需要會寫一點 code 並知道如何修改,對於不會寫 code 的人來說,可能便利性就沒這麼高。另外就是寫成網頁反而不利於我寫 blog,基於這個 side project 本來就是希望先滿足自己需求,因此後來目標就改成就先以 cli tool 實作為主。

現在這個 side project 成為我每個月必使用的工具,用來擷取學習日誌和 links,除了寫 blog 之外,後續還可以很方便地回顧之前看過的文章,可以說是目前寫過最實用的 project XD 

Read more →

Tail Recursion in Go

前言

最近在實驗效能分析時,有使用到 Tail Recursion 寫法,因此也好奇在 Go 中是否有跟 C 一樣進行 Tail Recursion optimization 優化。在文章中,首先會用 C asm 來說明 tail call optimization,接著 dump Go asm code 來觀察結果。

Tail Call

在說明 Tail Recursion Optimization 之前,先來說說 Tail Call。 Tail Call 概念很簡單,就是在 function 的最後語句執行另一個 function call。

1
2
3
4
int search(int data)
{
  return advanced_search(data);
}

要注意的是, Tail Call 意指最後的行為只允許使用 function call,所以以下的寫法就不是 Tail Call,因為它需要先進行 2 * 1 + funcB(a-1) 的運算,才能返回。

Read more →

2019/05月份自我學習回顧

![study]({{ site.url }}/assets/images/study-201906.png)

前言

五月的時候,團隊來了一位經驗豐富的瑞典人,而剛好有這個機會跟他合作,除了跟他練練英文口說能力之外,順便學習一下他的程式經驗。瑞典人是一位懂很多層面的工程師,從韌體到 Web Front-end 都有實務經驗,而且為人也不錯,會很認真地看每個 Pull Request,並給予架構上或是程式寫法上的回饋,能有這樣的同事真的很開心,即使在當個碼農趕專案,也會覺得從中學習到不少。

五月份確實蠻忙的,因此在中旬的時候,一度對於下班學習覺得有點力不從心,但靜下心來思考後,發現其實只是因為自己上班全程精神專注,導致下了班會不想去進修,進而逐漸拉長滑手機和躺在床上發呆的時間。於是,在察覺到自己有這個狀況之後,就開始明確訂出每日學習目標,之前都是很隨興地安排,不會強迫自己要唸到怎樣的進度,不過如果開始怠惰的話,明確的進度才會讓自己不會偷懶,甚至知道哪邊有出現進度落後,而需要做改善。

在經過這樣小調整之後,學習的動力又回來了,因此在五月下旬時候又恢復到每天都有進度,而不是像中旬一樣,讀個三四天就想休息一天。

學習回顧

五月份學習以離散數學Linux 為主,離散數學除了看韓永楷教授的線上課程之外,還有買一本離散數學課本來練習習題。至於 Linux 目前是以 Jserv 教授的系統核心設計課程為主,不過 Jserv 每次線上課程的內容都蠻多的,所以之後還是需要反覆地看以及實驗,才能夠真正地理解,不然只光看直播其實不太能吸收這麼多資訊。

離散數學

目前離散數學課程聽到 13 peg solitaire,進度蠻慢的,不過因為有邊搭配習題練習,所以這個速度也還是能接受。這次學習花比較多時間在實際證明上,因為在學的時候對於證明題總是輕忽,想說考試不太會考,但是現在自主學習沒有考試壓力,再加上理解這些內容,感覺更能讓自己去思考背後原理,每次練習完都蠻有收穫的。

Linux 核心設計

本月份有兩次直播課程,包含 Linux 核心設計: 朝向硬即時的核心變革Linux 核心設計: 檔案系統概念及實作手法,線上講座內容都很多而且也比較偏理論說明,所以上完後一定要再花時間去實作和實驗,才能"大略略"了解這個功能在 Linux Kernel 的作用。不過因為要看的東西太多了,所以先從檔案系統開始實驗, Real-Time 部分預計在六月會再重新複習一次。

Read more →

2019/04月份自我學習回顧

![study]({{ site.url }}/assets/images/golang.jpg)

前言

不知不覺又過了一個月了,本來想說一週要產出一篇文章,結果發現技術文章真的蠻容易難產的,主要原因是我希望能盡可能地從根本去探討這些技術背後運作模式和原理,因此會花費大量時間在整理內容和實驗上。不過部分原因也可能是因為資歷不夠,所以這些內容要思考很久,才會下筆去寫,希望之後慢慢熟稔之後可以加快產出速度。

上個月曾經提到,我會開始複習大學 CS 基礎課程,因為工作後會隨著時間漸漸地把這些基礎原理忘掉,所以這個月就從離散數學開始看起。說到數學,我覺得現在的我把數學當作一種訓練自己思考邏輯的方式,雖然他對我來說真的有點挑戰性,但是在了解這些數學是如何解出最終解的過程中,其實蠻有樂趣,會讓我很訝異原來可以透過這樣子的方式去找答案。當然我在大學時期也很討厭上課,之所有會有這樣體悟,真的是要等待我出社會累積經歷後,才會認知到這樣邏輯訓練很有助於工作效率。

除了念書之外,4月份我也去擔任志工協助 Golang Taipei 的擺攤宣傳。在參加活動上我是超級菜逼八,不過真的蠻有意思,可以認識到不同社群的人,能夠互相交流。雖然目前因為工作關係定居在新竹,但還是希望自己能夠多多參與這樣的活動,看看別人如何推廣技術社群也是一種學習!

學習回顧

本月份學習其實蠻雜的,包含 C、Linux、離散數學、還有一些 Go。之所以會這麼雜,是因為我四月份的上班時間都是在寫 Go 和研讀相關文章,我希望在下班時間可以學一點理論知識,會讓我覺得不這麼像碼農。有些人會來信問我,學習這麼發散,那不就等於什麼都不會?但我認為不是這樣子的,每個技術其實背後原理都是互相關聯,而且最重要的是必須讓自己在腦內建立起關鍵字,讓自己在需要這類知識時,可以快速反應到該如何去找相關知識,以及可以聯想到關聯的應用技術,這樣在解決問題時就會快上許多。

還有另一個原因是,因為專案上使用到 Cgo ,就很自然地想要看一下 C 語言 XD

學習日誌

4月份有 5 天沒有唸書,因為去參加活動,還有氣管過敏有點變嚴重,不知道是不是換季關係 (?)

  • 2019/4/2 - cgo - how it works
  • 2019/4/2 - 你所不知道的 C 語言:指標篇 (3)
  • 2019/4/3 - 你所不知道的 C 語言:指標篇上 - (4)
  • 2019/4/4 - 你所不知道的 C 語言:指標篇 (下) -1
  • 2019/4/4 - gRPC - The process of Dial()
  • 2019/4/5 - gRPC - Name Resolver & Load-Balancer
  • 2019/4/6 - New Post - gRPC Client 與 Server 連線流程
  • 2019/4/7 - 你所不知道的 C 語言:指標篇 (下) - 2
  • 2019/4/8 - 你所不知道的 C 語言:指標篇 (下) -3
  • 2019/4/9 - Discrete mathematics - Logical operators_review
  • 2019/4/10 - Discrete mathematics - Logical operators, Tautology and contradiction & Logical equivalence
  • 2019/4/11 - Linux 核心設計: 記憶體管理 (直播)
  • 2019/4/12 - Discrete mathematics - Implication
  • 2019/4/14 - Linux 核心設計: 記憶體管理 (2)
  • 2019/4/14 - Golang Weekly Study
  • 2019/4/15 - Article: Golang Race Detection、The Go Memory Model
  • 2019/4/15 - Discrete mathematics - Puzzle
  • 2019/4/16 - 惡血,矽谷獨角獸的醫療騙局
  • 2019/4/19 - Golang Weekly Study (Advanced Test)
  • 2019/4/19 - Discrete mathematics - Predicate
  • 2019/4/20 - cgo compile problems solved (include header, dynamic libs, and uint test with .so)
  • 2019/4/21 - Discrete mathematics - Quantifiers, propositional function
  • 2019/4/22 - 你所不知道的C語言: Stream I/O, EOF 和例外處理
  • 2019/4/25 - Discrete mathematics - functional examples
  • 2019/4/26 - Golang project refactor (enhance concurrency part)
  • 2019/4/27 - Dig into Cgo process and overhead
  • 2019/4/28 - dotGo 2019 video
  • 2019/4/28 - Cgo dump pre-compile files
  • 2019/4/29 - GopherChina - Go concurrency in practice
  • 2019/4/30 - Discrete mathematics - Mathematical arguments and functional proposition with De Morgen’s Law

Articles

Read more →

grpc-go source code trace - gRPC client 與 server 建立連線過程

前言

其實一開始的目的是想要研究 gRPC 的 retry 機制,不過在了解 retry 之前勢必要先說明整個 gRPC client 與 server 建立連線的過程,因此就先用 source code trace 的方式簡單說明在呼叫 grpc.Dial 後所執行的連線流程,包含 gRPC 實現 load-balancing 的機制。

packages

grpc-go v1.19.1

grpc.Dial 的背後

以下是 client 向 server 連線的基本方式。

1
2
3
4
5
conn, err := grpc.Dial(serverIpAddress, grpc.WithInsecure())

func Dial(target string, opts ...DialOption) (*ClientConn, error) {
  return DialContext(context.Background(), target, opts...)
}

首先, Client 需要透過 Name Resolver 解析 Dial 中的 target string 來取得 Server 正確的 IP Addresses 和 port,以利後續建立 connection。例如使用 DNS Name Resolver,就可以透過 conn, err := grpc.Dial("dns:///your.target.name:8888") 這種 Domain name 的方式來發送 RPCs。

Read more →

2019/03月份自我學習回顧

![study]({{ site.url }}/assets/images/golang-meetup.jpeg)

前言

最近這一個月工作慢慢步上軌道,心情有比較踏實些。剛開始來的時候,實在不太確定自己能幫上什麼忙,不過這個月漸漸地有任務可以做,並且也和其他組員一起合作開發,感覺在團隊中可以發揮自己的價值:) 另外,這個月比較大的轉變是完全負責 back-end ,之前還想說可能會接觸到 React ,所以花了一些時間在看 React 原理,不過目前確定會都以 Go 和 Device application 開發為主,因此後續就會把學習重心放在 Back-end。話雖如此,自己還是有加入公司的 front-end 學習群,跟著裡面的大神們一起念 React Core ,畢竟過去一年蠻大比例是使用 JavaScript 開發,要放棄也是蠻可惜的。

學習回顧

Go

這次很難得地可以參加Go Taipei 社群,分享使用 Go 的開發經驗,過程中花蠻多時間在整理簡報,除了擷取 Practical Go 中實際碰過的案例,也找了些其他跟專案維護相關的文章一並分享。原本以為應該不會太難的,沒想到實際整理起來卻花了快一個禮拜的時間,自己也從各種 references 中發掘更多討論相關議題的文章,收穫良多。在實際分享過後,反而會更積極地參加活動,因為這些分享都是工程師利用私下時間來整理的,如果能踴躍支持,就是給予他們最大的鼓勵吧XD

另外,由於專案中使用到 gRPC ,所以也花了時間在這部分的 source code 研究,特別是在 client retry 部分,想了解在不使用 iinterceptor 的情況下,能不能滿足目前需要 retry 的場景。此外還有 Http 這些標準 package 的複習等,尤其是公司蠻重視 test 這塊,所以也花時間在看 Httptest 和 Httptrace 等。

Read more →

Golang - Request test using net/http/httptrace

前言

在撰寫 HTTP request test 測試程式時,除了測試 response 結果是否如預期之外,我們還需要知道過程中需要耗費多少時間(request latency)。市面上有一些 libraries (e.g opencensus) 能提供相關的 HTTP 事件 trace,不過仔細看會發現他們大多也是整合 golang 本身提供的 httptrace 來實現追蹤功能,因此我們就直接來了解 httptrace 的運作原理和應用方式,再結合 http/httptest,讓 handler test 更完整。

Request 處理流程

在說明 httptrace 之前,由於 request test 中是藉由 http package 來發起的 ,所以先來了解一下 golang 中,透過 http package 的 client 處理 http request 的流程。

Read more →