2013-10-21 19 views
8

Geçen yıl işletim sistemlerini aldım, bu sırada bir proje için bir iş parçacığı (her iş parçacığının bir işlemi simüle ettiği) uygulamak için kullanıcı bağlamlarını (ucontext.h başlığında tanımladım) kullandım. Bir konferansta yer alıyorum ve kullanıcı bağlamları hakkında konuşacağım, ve bana öyle geliyor ki, geçen sene bu projeyi yapmamıza rağmen, aslında tam olarak ne olduğunu tam olarak anlamıyorum getcontext sistem çağrısı.Getcontext sistem çağrısı (ucontext.h) gerçekten ne yapar?

getcontext için adam sayfaları, "şu anda etkin olan içeriğe uçtan uca işaretlenen yapıyı başlatır." Aynı zamanda, setcontext argümanı için, "ucp argümanı getcontext() ile oluşturulmuşsa, program çalışması, getcontext() 'nin karşılık gelen çağrısı yeni gelmiş gibi devam eder." Tamam, bunu anlıyorum.

İşte burada kafam karıştı. Tipik olarak, yol için bir bağlam anahtarı gerçekleştirmek için, bunu öğrenmiş, böyle bir olarak ayarlamak/ucontext_t yapı ve takas başlatmak olacaktır:

ucontext_t ucp; 
ucontext_t oucp; 
getcontext(&ucp); 

// Initialize the stack_t struct in the ucontext_t struct 
ucp.uc_stack.ss_sp = malloc(STACK_SIZE); 
ucp.uc_stack.ss_size = STACK_SIZE; 
ucp.uc_stack.ss_flags = 0; 

ucp.uc_link = /* some other context, or just NULL */; 

// Don't block any signals in this context 
sigemptyset(&ucp.uc_sigmask); 
// Assume that fn is a function that takes 0 arguments and returns void 
makecontext(&ucp, fn, 0); 

// Perform the context switch. Function 'fn' will be active now 
swapcontext(&oucp, &ucp); 
// alternatively: setcontext(&ucp); 

Ben küçük programlarda getcontext atlarsanız, ilginç bir şey olmaz. Kullanıcı bağlamları üzerinden daha fazla bağlam değiştirmenin olduğu daha büyük programlarda, yalnızca getcontext eklendiğinde çözülen bir bölümleme hatası alıyorum.

getcontext tam olarak ne yapar? Neden sadece ucontext_t yapısını ayıramıyor, uc_stack ve uc_sigmask alanlarını başlatarak ve getcontext olmadan makecontext'u arayarak başlatamıyorum? getcontext'un makecontext'un gerçekleştirmediği bazı gerekli başlatma var mı?

cevap

4

x86/linux mimarileri üzerinde ucontext için GNU libc uygulamasına baktım, bu nedenle, aşağıdakilerin beklemediği farklı uygulamalar olabilir. makecontext geçirilen

UCP parametresi GetContext bir çağrı ile başlatıldı edilir: bu

GNU libc manual belirtmektedir.

Eğer glibc'de mcontext_t bakarsak/sysdeps/Unix/Linux/x86/sys/ucontext.h GetContext başlatılmış() ve yine duruma gelmiş kayan nokta durumuna işaretçi (fpregset_t fpregs) bulunmaktadır setcontext() içinde. Ancak, makecontext() kullanılarak başlatılmaz. Ben GDB ile hızlı bir test yaptım ve ben bir ucontext_t içinde kayan nokta bağlama pointer KQUEUE çalışırken GetContext tarafından başlatılmadı yapı setcontext bir segfault()() var:

=> 0x00007ffff784308c < 44 >: fldenv (% rcx)

+0

Bu oldukça gizemi çözüyor. – kibibyte