bloggerads

2016年12月2日 星期五

gcc : Built-in functions for atomic memory access

這一篇是研究Memory barrier的心得。研究的原因是因為在UEFI環境下使用multi-processor protocol 來驗證CPU design,過程用到了相關的gcc Atomic函式。Atomic 提供同步機制,使得在Multi-Processor/Multi-Thread的系統下操作同一塊memory, 各個Core的Cache都能確保和Memory同步。

這邊只是以軟體thread寫個應用程式作範例來解釋Memory barrier, 如果不使用Built-in functions for atomic memory access而將__sync_fetch_and_add(&count,1);改成count++, 則count結果會不正確。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

static int count = 0;

void *MyTest(void *arg)
{
        for (int i=0; i<20000; ++i)         
            __sync_fetch_and_add(&count, 1);
        return NULL;
}

int main(int argc, const char *argv[])
{
        pthread_t Thread_Id[10];
        int i;

        for (i=0;i<10;++i)
                pthread_create(&Thread_Id[i], NULL, MyTest, NULL);
       
                // Wait until all threads have finished.
        for (i=0;i<10;++i)
                pthread_join(Thread_Id[i], NULL);
       
        printf("%d\n",count);
        return 0;
}


另外,__sync_synchronize (): This built-in function issues a full memory barrier.呼叫這個函式讓每個Core上的cache和memory同步。

<note> UEFI kernel提供EFI_MP_SERVICES_PROTOCOL,透過這個protocol,可以指定呼叫某個/或多個CORE (AP)分別執行特定的function,達到Multi-processing的效果。

-------------------------------------------------------------------------------------------------------------------------
Ps. windows下測試,需要自行加入pthread這個library
如果你用Dev-C++ 5.11, Project->Parameters->Add library or object 加入
"../../Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib/libpthread.a"



順便解釋一下我認知的procces/thread:

process: 在系統中被註冊要執行的程式,其擁有CPU的使用權和獨立的位址空間。
thread: 系統處理工作的基本單位,一個CPU核心在同一時間只能提供一個thread來執行process
Multi-Thread: 將多個thread同時assign給一個process
Multi-Process: 每個process都分到thread來處理

2016年12月1日 星期四

UEFI : 在Linux(Ubuntu)下build UEFI Bios module

為什麼要在Linux(Ubuntu)底下build Bios module呢?
因為接手了大陸同事的UEFI Shell code,而他使用了 gcc 的library "Atomic Memory Access",這個library在平常我們慣用的Visual Studio compiler下無法直接使用。

所以這兩天,花了點時間研究一下如何在Ubuntu下建構可以編譯的環境。
由於網路上比較少有這樣的文章分享, 因此特地新增一篇網誌做說明以及紀錄

基本上我是參考以下這兩篇Using EDK II with Native GCCUDK2014 How to Build
,這邊解釋一下必要的流程

#取得EDK2 code base 請參考 https://github.com/tianocore/edk2

#安裝所需要的編譯工具
bash$:   sudo apt-get install build-essential subversion uuid-dev iasl

#取得nasm組譯器
bash$:   sudo apt-get install nasm