的mmap
系統調用的文件說,如果該函數將失敗:用戶進程的有效地址空間是什麼? (OS X和Linux)
MAP_FIXED被指定和地址 說法是不對齊的頁面,或部分所需的地址空間的 駐留 在 用戶進程的有效地址空間之外。
我找不到任何地方的文檔說什麼將是一個有效的地址映射。 (我有興趣在OS X和Linux上執行此操作,理想情況下,相同的地址對於這兩種操作都是有效的)。
的mmap
系統調用的文件說,如果該函數將失敗:用戶進程的有效地址空間是什麼? (OS X和Linux)
MAP_FIXED被指定和地址 說法是不對齊的頁面,或部分所需的地址空間的 駐留 在 用戶進程的有效地址空間之外。
我找不到任何地方的文檔說什麼將是一個有效的地址映射。 (我有興趣在OS X和Linux上執行此操作,理想情況下,相同的地址對於這兩種操作都是有效的)。
Linux內核爲自己保留了虛擬地址空間的一部分,以便用戶空間具有(幾乎)無法訪問並且無法映射任何內容。你正在尋找所謂的「用戶空間/內核空間拆分」。
在i386拱默認是3G/1G一個 - 用戶空間變低3 GB的虛擬地址空間,核上得到1 GB,另外有2G/2G和1G/3G分裂:
config PAGE_OFFSET
hex
default 0xB0000000 if VMSPLIT_3G_OPT
default 0x80000000 if VMSPLIT_2G
default 0x78000000 if VMSPLIT_2G_OPT
default 0x40000000 if VMSPLIT_1G
default 0xC0000000
depends on X86_32
在x86_64,用戶空間住在的虛擬地址空間(目前)48位的下半部分:
/*
* User space process size. 47bits minus one guard page.
*/
#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
這變化的基礎上多種因素,其中有許多是不是你的控制之下。正如Adobriyan所說,根據操作系統的不同,您有各種固定的上限,超出這些上限是內核代碼和數據所在。在32位操作系統上,通常這個上限是至少 2GB;一些操作系統提供額外的地址空間。 64位操作系統通常提供由CPU支持的虛擬地址位數(通常至少爲40位地址空間)控制的上限。但也有另一些因素超出你的控制:
/proc/sys/vm/mmap_min_addr
配置的地址將被拒絕。malloc
可以自行,其放置在一定程度上任意位置這樣執行mmaps,沒有辦法絕對是機制保障將MAP_FIXED
成功,所以它通常應避免。
我見過的唯一地方MAP_FIXED
需要的是在酒的啓動代碼,其儲量(使用MAP_FIXED
)2G以上的所有地址,以避免混淆窗口代碼不承擔任何映射都不會顯示出來了否定地址。當然,這是對旗幟的高度專業化使用。
如果你想這樣做是爲了避免處理共享內存中的偏移量,其中一個方案是包的指針在一個類來自動處理偏移:
template<typename T>
class offset_pointer {
private:
ptrdiff_t offset;
public:
typedef T value_type, *ptr_type;
typedef const T const_type, *const_ptr_type;
offset_ptr(T *p) { set(p); }
offset_ptr() { set(NULL); }
void set(T *p) {
if (p == NULL)
offset = 1;
else
offset = (char *)p - (char *)this;
}
T *get() {
if (offset == 1) return NULL;
return (T*)((char *)this + offset);
}
const T *get() const { return const_cast<offset_pointer>(this)->get(); }
T &operator*() { return *get(); }
const T &operator*() const { return *get(); }
T *operator->() { return get(); }
const T *operator->() const { return get(); }
operator T*() { return get(); }
operator const T*() const { return get(); }
offset_pointer operator=(T *p) { set(p); return *this; }
offset_pointer operator=(const offset_pointer &other) {
offset = other.offset;
return *this;
}
};
注:此是未經測試的代碼,但應該給你基本的想法。
謝謝!我應該補充一點,我只對64位系統感興趣,這就是爲什麼固定映射甚至是一個考慮因素,因爲它似乎必須有足夠的空間來避免衝突不應該太困難。 – James 2011-03-05 17:50:57
這是Linux的一個很好的答案。任何人都可以獲得64位OSX的相同信息? – Quuxplusone 2012-10-10 19:10:54
回覆我自己的評論:在OSX上,它似乎大致爲'0x1_00000000'(從我的測試用例中運行到運行不等)直到'0x7fff_ffffffff';即內核保留低4GB的虛擬地址空間,並且虛擬地址被限制在與x86-64上的物理地址相同的48位範圍內。 – Quuxplusone 2012-10-10 19:34:27