Tạo luồng mô hình

Các phương thức được đánh dấu là oneway sẽ không chặn. Đối với các phương thức không được đánh dấu là oneway, lệnh gọi phương thức của một ứng dụng sẽ chặn cho đến khi máy chủ thực thi xong hoặc đã gọi một lệnh gọi lại đồng bộ (tuỳ vào trường hợp nào xảy ra trước). Quá trình triển khai phương thức máy chủ có thể gọi tối đa một lệnh gọi lại đồng bộ; bổ sung lệnh gọi lại bị loại bỏ và được ghi lại dưới dạng lỗi. Nếu một phương thức cần các giá trị trả về qua lệnh gọi lại và không gọi lệnh gọi lại của nó, việc này được ghi lại dưới dạng một và báo cáo là lỗi truyền tải đến ứng dụng.

Luồng ở chế độ truyền qua

Ở chế độ truyền qua, hầu hết các lệnh gọi đều đồng bộ. Tuy nhiên, để duy trì mà các lệnh gọi oneway không chặn ứng dụng, một luồng sẽ được tạo cho từng quá trình. Để biết chi tiết, hãy xem Tổng quan về HiDL

Các luồng trong HAL liên kết

Để phân phát các lệnh gọi RPC đến (bao gồm cả lệnh gọi lại không đồng bộ từ HAL đến người dùng HAL) và thông báo sự cố, một nhóm luồng được liên kết với mỗi quy trình sử dụng HIDL. Nếu một quy trình triển khai nhiều giao diện HIDL và/hoặc trình xử lý thông báo chết, nhóm luồng của nó được chia sẻ giữa tất cả chúng. Thời gian một quy trình nhận được lệnh gọi phương thức đến từ ứng dụng, hệ thống sẽ chọn một chuỗi miễn phí từ nhóm luồng rồi thực thi lệnh gọi trên luồng đó. Nếu không có chuỗi miễn phí nào có sẵn, sẽ bị chặn cho đến khi có một quy tắc.

Nếu máy chủ chỉ có một luồng, thì các lệnh gọi đến máy chủ đã hoàn tất theo thứ tự. Máy chủ có nhiều luồng có thể hoàn tất các lệnh gọi không đúng thứ tự ngay cả khi máy khách chỉ có một luồng. Tuy nhiên, đối với một đối tượng giao diện nhất định, oneway cuộc gọi được đảm bảo sẽ được sắp xếp (xem Mô hình phân luồng máy chủ). Đối với một máy chủ đa luồng lưu trữ nhiều giao diện, lệnh gọi oneway đến các giao diện khác nhau có thể được xử lý đồng thời với nhau hoặc các lệnh gọi chặn khác.

Nhiều lệnh gọi lồng nhau được gửi trên cùng một luồng hwbinder. Ví dụ: nếu một quy trình (A) thực hiện lệnh gọi đồng bộ từ luồng hwbinder vào quy trình (B), sau đó tiến trình (B) thực hiện lệnh gọi đồng bộ trở lại quy trình (A), lệnh gọi là được thực thi trên luồng hwbinder ban đầu trong (A) bị chặn trên luồng gốc . Tính năng tối ưu hoá này giúp bạn có thể có một máy chủ theo luồng duy nhất có thể xử lý các lệnh gọi lồng nhau, nhưng không mở rộng đến trường hợp các lệnh gọi di chuyển qua một chuỗi lệnh gọi IPC khác. Ví dụ: nếu quá trình (B) đã thực hiện một lệnh gọi liên kết/vndbinder gọi vào một quy trình (C) rồi xử lý (C) các lệnh gọi quay lại (A), không thể phân phát luồng ban đầu trong (A).

Mô hình phân luồng máy chủ

Ngoại trừ chế độ truyền qua, việc triển khai giao diện HIDL trên máy chủ sẽ diễn ra trong một tiến trình khác với ứng dụng khách và cần một hoặc nhiều luồng đang chờ các lệnh gọi phương thức đến. Các luồng này là nhóm luồng của máy chủ; máy chủ có thể quyết định số lượng luồng muốn chạy trong nhóm luồng và có thể sử dụng một kích thước nhóm luồng là một để chuyển đổi tuần tự tất cả các lệnh gọi trên giao diện của nó. Nếu máy chủ có nhiều luồng trong nhóm luồng, luồng này có thể nhận đồng thời các luồng đến trên bất kỳ giao diện nào (trong C++, điều này có nghĩa là dữ liệu được chia sẻ phải được khoá cẩn thận).

Các lệnh gọi một chiều vào cùng một giao diện được chuyển đổi tuần tự. Nếu một đa luồng ứng dụng khách gọi method1method2 trên giao diện IFoomethod3 trên giao diện IBar, method1method2 luôn được chuyển đổi tuần tự nhưng method3 có thể chạy song song với method1method2.

Một luồng thực thi máy khách duy nhất có thể khiến quá trình thực thi đồng thời trên một máy chủ có nhiều luồng theo hai cách:

  • Các cuộc gọi oneway sẽ không bị chặn. Nếu cuộc gọi oneway là được thực thi rồi một miền không phải oneway được gọi, máy chủ có thể thực thi lệnh gọi oneway và lệnh gọi không phải oneway đồng thời.
  • Các phương thức máy chủ truyền dữ liệu trở lại bằng lệnh gọi lại đồng bộ có thể bỏ chặn máy khách ngay khi lệnh gọi lại được gọi từ máy chủ.

Với cách thứ hai, bất kỳ mã nào trong hàm máy chủ thực thi sau lệnh gọi lại được gọi có thể thực thi đồng thời, với máy chủ xử lý các cuộc gọi từ máy khách. bao gồm mã trong chức năng máy chủ và mã tự động hàm khởi tạo thực thi ở cuối hàm. Nếu máy chủ có nhiều hơn một luồng trong nhóm luồng, các vấn đề đồng thời phát sinh ngay cả khi có lệnh gọi từ một luồng ứng dụng duy nhất. (Nếu có bất kỳ HAL nào do quy trình cung cấp cần nhiều luồng, tất cả các HAL đều có nhiều luồng vì nhóm luồng là được chia sẻ cho mỗi quy trình).

Ngay khi máy chủ gọi lệnh gọi lại đã cho, công cụ truyền tải có thể gọi triển khai lệnh gọi lại trên ứng dụng và bỏ chặn ứng dụng. Khách hàng tiếp tục song song với bất kỳ điều gì mà máy chủ triển khai thực hiện sau khi gọi hàm lệnh gọi lại (có thể bao gồm các hàm khởi tạo đang chạy). Mã trong hàm máy chủ sau khi lệnh gọi lại không còn chặn ứng dụng (miễn là máy chủ nhóm luồng có đủ luồng để xử lý các lệnh gọi đến) nhưng có thể được thực thi đồng thời với các lệnh gọi trong tương lai từ ứng dụng khách (trừ phi nhóm luồng máy chủ có chỉ một chuỗi).

Ngoài các lệnh gọi lại đồng bộ, oneway còn gọi từ một máy khách đơn luồng có thể được một máy chủ xử lý đồng thời có nhiều các luồng trong nhóm luồng, nhưng chỉ khi các lệnh gọi oneway đó được thực thi trên nhiều giao diện. oneway cuộc gọi cùng một lúc luôn được chuyển đổi tuần tự.

Lưu ý:Các hàm máy chủ nên trả về ngay khi gọi hàm callback.

Ví dụ (trong C++):

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    // At this point, the client's callback is called,
    // and the client resumes execution.
    ...
    return Void(); // is basically a no-op
};

Mô hình phân luồng ứng dụng

Mô hình phân luồng trên máy khách khác nhau giữa các lệnh gọi không chặn (các hàm được đánh dấu bằng từ khoá oneway) và quy tắc chặn lệnh gọi (các hàm không được chỉ định từ khoá oneway).

Chặn cuộc gọi

Đối với việc chặn lệnh gọi, ứng dụng sẽ chặn cho đến khi một trong các điều sau xảy ra:

  • Xảy ra lỗi vận chuyển; đối tượng Return chứa một lỗi trạng thái có thể được truy xuất bằng Return::isOk().
  • Quá trình triển khai máy chủ sẽ gọi lệnh gọi lại (nếu có).
  • Quá trình triển khai máy chủ sẽ trả về một giá trị (nếu không có thông số gọi lại).

Trong trường hợp thành công, hàm callback mà ứng dụng truyền dưới dạng một đối số là luôn được máy chủ gọi trước khi chính hàm trả về. Lệnh gọi lại là được thực thi trên cùng một luồng mà lệnh gọi hàm được thực hiện, vì vậy, trình triển khai phải cẩn thận với việc giữ khoá trong khi gọi hàm (và tránh giữ khoá khi có thể). Một hàm không có câu lệnh generates hoặc từ khoá oneway vẫn đang chặn; ứng dụng chặn cho đến khi máy chủ trả về một đối tượng Return<void>.

Cuộc gọi một chiều

Khi một hàm được đánh dấu là oneway, ứng dụng sẽ trả về ngay lập tức và không đợi máy chủ hoàn tất lệnh gọi hàm. Tại nền tảng (và tổng hợp), điều này có nghĩa là lệnh gọi hàm chiếm một nửa thời gian vì đang thực thi một nửa mã, nhưng khi viết các phương thức triển khai nhạy cảm về hiệu suất, điều này có một số ảnh hưởng đến lịch biểu. Thông thường, sử dụng cuộc gọi một chiều khiến phương thức gọi tiếp tục được lên lịch trong khi khi sử dụng lệnh gọi đồng bộ thông thường khiến bộ lập lịch chuyển ngay lập tức từ phương thức gọi đến quy trình hàm được gọi. Đây là một giải pháp tối ưu hoá hiệu suất trong liên kết. Đối với các dịch vụ mà lệnh gọi một chiều phải được thực thi trong quy trình mục tiêu có mức độ ưu tiên cao, thì chính sách lên lịch của dịch vụ nhận có thể bị đã thay đổi. Trong C++, sử dụng phương thức của libhidltransport setMinSchedulerPolicy với các chính sách và mức độ ưu tiên của trình lập lịch biểu được xác định trong sched.h đảm bảo rằng tất cả các lệnh gọi đến dịch vụ đều chạy tại tối thiểu là với chính sách và mức độ ưu tiên lập lịch đã đặt.