2013-10-21 16 views
8

Tôi đã sử dụng hệ điều hành vào năm ngoái, trong đó tôi đã sử dụng ngữ cảnh người dùng (được định nghĩa trong tiêu đề ucontext.h) để triển khai trình lập lịch trình (trong đó mỗi luồng mô phỏng quy trình) cho dự án. Tôi đang tham gia một bài giảng và sẽ nói về bối cảnh của người dùng, và nó chỉ xảy ra với tôi rằng, mặc dù đã thực hiện dự án này năm ngoái, tôi không thực sự hiểu chính xác cuộc gọi hệ thống getcontext thực sự là gì.Gọi hệ thống getcontext (ucontext.h) thực sự làm gì?

Trang hướng dẫn sử dụng cho getcontext nói rằng nó "khởi tạo cấu trúc được trỏ bởi ucp đến ngữ cảnh hiện đang hoạt động". Nó cũng cho biết, đối số là setcontext, rằng "nếu đối số ucp được tạo bằng getcontext(), thì việc thực hiện chương trình tiếp tục như thể cuộc gọi tương ứng của getcontext() vừa trở về." Được rồi, vì vậy tôi hiểu điều đó.

Vì vậy, đây là những gì tôi đang bối rối. Thông thường, đối với con đường tôi đã học nó, để thực hiện một chuyển đổi bối cảnh, người ta sẽ khởi tạo ucontext_t struct và hoán đổi/thiết lập nó như vậy:

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); 

Nếu tôi bỏ qua getcontext trong các chương trình nhỏ hơn, không có gì thú vị xảy ra. Trong các chương trình hơi lớn hơn, trong đó có nhiều bối cảnh chuyển đổi qua ngữ cảnh người dùng, tôi nhận được lỗi phân đoạn chỉ được giải quyết bằng cách thêm getcontext trở lại.

Chính xác thì getcontext làm gì? Tại sao tôi không thể chỉ định cấu trúc ucontext_t, hãy khởi tạo cấu trúc đó bằng cách khởi tạo các trường uc_stackuc_sigmask và gọi makecontext mà không cần getcontext? Có một số khởi tạo cần thiết rằng getcontext thực hiện rằng makecontext không hoạt động?

Trả lời

4

Tôi đã xem triển khai GNU libc cho ucontext trên kiến ​​trúc x86/linux, do đó, có thể có các triển khai khác nhau mà những điều sau đây không giữ.

Các GNU libc manual bang rằng:

Tham số UCP truyền cho makecontext sẽ được khởi tạo bởi một cuộc gọi đến getContext.

Nếu bạn nhìn vào mcontext_t trong glibc/sysdeps/unix/linux/x86/sys/ucontext.h có một con trỏ đến tình trạng điểm nổi (fpregset_t fpregs) được khởi tạo trong getContext() và dereferenced một lần nữa trong setcontext(). Tuy nhiên, nó không được khởi tạo bằng cách sử dụng makecontext(). Tôi đã làm một thử nghiệm nhanh với GDB và tôi đã nhận một segfault trong setcontext() khi cố gắng dereference con trỏ với bối cảnh dấu chấm động trong một ucontext_t struct không được khởi tạo bởi getContext():

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

+0

Vâng, điều đó giải quyết khá bí ẩn. – kibibyte

Các vấn đề liên quan