xenomai鍐呮牳瑙f瀽涔嬩俊鍙穝ignal(浜?---xenomai淇″彿澶勭悊鏈哄埗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xenomai鍐呮牳瑙f瀽涔嬩俊鍙穝ignal(浜?---xenomai淇″彿澶勭悊鏈哄埗相关的知识,希望对你有一定的参考价值。
鏍囩锛?a href='http://www.mamicode.com/so/1/ctr' title='ctr'>ctr
灏变細 conf 妯″紡 澶辫触 sigwait type errno rmi xenomai淇″彿
涓婄瘒鏂囩珷璁蹭簡linux鐨勪俊鍙峰湪鍐呮牳鐨勫彂閫佷笌澶勭悊娴佺▼锛岀幇鍦ㄥ姞鍏ヤ簡cobalt鏍革紝Cobalt鍐呮牳涓簒enomai绾跨▼鎻愪緵浜嗕俊鍙锋満鍒躲€備笅闈竴涓€瑙f瀽xenomai鍐呮牳鐨勪俊鍙峰鐞嗘満鍒躲€?/p>
1 鍙屾牳涓嬬殑淇″彿鍒嗙被
鎴戜滑宸茬粡鐭ラ亾锛屾瘡涓敤鎴风┖闂寸殑xenomai绾跨▼鍦ㄥ唴鏍哥┖闂撮兘鏈変袱涓皟搴﹀疄浣擄紝涓€鏄湪linux鍐呮牳涓殑task_struct锛屽彟涓€涓槸绉颁负linux绌洪棿鐨勪竴涓奖瀛?shadow)鐨剎nthread銆傚畠浠〃绀虹殑鏄悓涓€涓嚎绋嬶紝linux璋冨害鐨勬槸task_struct锛屽疄鏃舵牳cobalt璋冨害鐨勬槸xnthread銆傚彲閫氳繃鍦ㄤ袱涓皟搴﹀櫒闂磋縼绉荤殑鏂瑰紡鏉ヨxenomai绾跨▼鍦╨inux鏍稿拰Cobalt鏍镐笂杩愯銆?/p>
linux杩涚▼涓庣嚎绋嬬殑淇″彿灏辫浜哄ご鐤肩殑浜嗭紝鍐嶆潵涓€涓獂enomai淇″彿宀備笉鏇村鏉傦紵鍏跺疄涓嶅鏉傦紝鍙渶瑕佸垎娓呬笁绉嶄俊鍙峰強鍏朵綔鐢ㄥ煙灏監K锛屽鍥炬墍绀猴紝杩涚▼A鍐呮湁涓や釜瀹炴椂绾跨▼鍜屼竴涓櫘閫氱嚎绋嬶紝杩涚▼B鍐呮湁涓€涓疄鏃剁嚎绋嬪拰涓€涓櫘閫氱嚎绋嬶紝瀹冧滑涔嬮棿鐨勪俊鍙峰垎涓轰袱绫伙細
- 浣跨敤linux淇″彿鏈哄埗锛?/strong>杩涚▼闂翠俊鍙枫€乴inux绾跨▼闂翠俊鍙凤紱
- 浣跨敤xenomai淇″彿鏈哄埗:鍙瓨鍦ㄤ簬xenomai绾跨▼闂达紝xenomai鍐呯殑浠讳綍淇″彿閮戒笉浼氫紶鎾埌linux杩涚▼绌洪棿锛屼篃涓嶄細瀵艰嚧杩涚▼閫€鍑?/strong>锛?/li>
鐢变簬涓€涓獂enomai绾跨▼瀹冩棦鏄痩inux浠诲姟涔熸槸cobalt浠诲姟锛屼笉鍚岀殑淇″彿浜х敓鍜屽鐞嗗湪涓嶅悓鐨勫唴鏍镐腑銆傚浜巐inux淇″彿锛岀敱linux璋冨害鍣紙linux鍐呮牳锛夊彂閫佸拰鎺ユ敹澶勭悊锛泋enomai淇″彿鐢眡enomai绾跨▼閫氳繃cobalt鍐呮牳鎺ュ彛鍙戦€佹垨鎺ユ敹锛屽彲鐢ㄤ簬鍚屾浜掓枼锛堝彲涓庝俊鍙烽噺semaphore瀵规瘮锛夛紝瀵逛簬涓€涓獂enomai搴旂敤涓殑linux淇″彿锛?/p>
- xenomai绾跨▼閫氳繃
__STD(kill/pthread_kill)
閫氳繃linux鍙戦€佺殑淇″彿锛岃皟鐢ㄦ椂浼氳嚜鍔ㄨ縼绉诲埌linux鍐呮牳(root鍩?鍐嶅彂閫侊紱(__STD()
瀹忚〃绀烘樉寮忚皟鐢↙inux鏍囧噯搴撳嚱鏁帮級
- xenomai绾跨▼鎺ユ敹linux淇″彿澶勭悊鏃朵篃鏄竴鏍凤紝蹇呴』杩佺Щ鍒發inux鍐呮牳鎵嶈兘澶勭悊;
瀵逛簬linux鍚憍enomai鍙戦€佷俊鍙?/strong>锛屼緥濡傛垜浠粓绔腑鍚姩涓€涓獂enomai浠诲姟鍚庯紝閫氳繃閿叆ctrl+c缁撴潫xenomai浠诲姟鐨勬搷浣滐紝linux鍦ㄦ煡鎵惧鐞嗚淇″彿鐨勪换鍔℃椂锛屽鏋滈渶瑕佸鐞嗕俊鍙风殑鏄竴涓疄鏃朵换鍔★紝浼氭妸xenomai浠诲姟杩佺Щ鍒發inux鏍镐笂锛屽啀鎸塴inux鐨勫鐞嗛偅濂楁祦绋嬪幓澶勭悊灏辫銆?/strong>涓嬮潰浠湅瀹冩槸鎬庝箞澶勭悊鐨勶紝涓庝笂涓€绡囨枃绔爈inux涓嬬殑淇″彿澶勭悊娴佺▼瀵规瘮锛屽叾涓叾涓笉涓€鏍风殑姝ラ濡備笅,鍏朵綑鐨勪笌linux澶勭悊鏂瑰紡涓€鑷淬€?/p>
- linux杩涚▼鎴栬€?shell 鍙戦€佷竴涓俊鍙风粰xenomai绾跨▼A锛屽彲浠ヨ皟鐢?kill锛宼kill锛宼gkill锛宺t_sigqueueinfo
- 鍥涗釜鍙戦€佷俊鍙风殑鍑芥暟锛屽湪鍐呮牳涓渶缁堥兘鏄皟鐢?do_send_sig_info
do_send_sig_info
璋冪敤 send_signal
缁檟enomai浠诲姟A 鍙戦€佷竴涓俊鍙凤紝鍏跺疄灏辨槸鎵惧埌 A 鐨?code>task_struct
锛屼笉鍙潬淇″彿鍔犲叆淇″彿闆嗗悎锛屽彲闈犱俊鍙?鍔犲叆淇″彿閾捐〃銆傜劧鍚庤皟鐢?code>complete_signal()
澶勭悊淇″彿銆?/li>
complete_signal()
璋冪敤 signal_wake_up()->signal_wake_up_state()
鍞ら啋A銆?/li>
鍙屾牳涓嬶紝xenomai鍦╯ignal_wake_up_state鍑芥暟涓彃鍏ヤ簡妫€娴嬩唬鐮佸涓嬨€?/p>
void signal_wake_up_state(struct task_struct *t, unsigned int state)
{
set_tsk_thread_flag(t, TIF_SIGPENDING);
/* TIF_SIGPENDING must be prior to reporting.TIF_SIGPENDING */
__ipipe_report_sigwake(t);
if (!wake_up_state(t, state | TASK_INTERRUPTIBLE))
kick_process(t);
}
鎻掑叆浠g爜__ipipe_report_sigwake(t)
,__ipipe_report_sigwake()
璋冪敤__ipipe_notify_kevent()
鍙戝嚭涓€涓唴鏍搁棿淇″彿浜嬩欢IPIPE_KEVT_SIGWAKE
锛?code>__ipipe_notify_kevent
璋冪敤Cobalt鍐呮牳鐨刬pipe_kevent_hook鏉ユ帴鏀惰繖浜涗簨浠躲€?/p>
int ipipe_kevent_hook(int kevent, void *data)
{
int ret;
switch (kevent) {
case IPIPE_KEVT_SCHEDULE:
ret = handle_schedule_event(data);/**/
break;
case IPIPE_KEVT_SIGWAKE:
ret = handle_sigwake_event(data);///IPIPE_KEVT_SIGWAKE
break;
......
default:
ret = KEVENT_PROPAGATE;
}
return ret;
}
ipipe_kevent_hook涓牴鎹簨浠剁被鍨嬫墽琛宧andle_sigwake_event銆?/p>
static int handle_sigwake_event(struct task_struct *p)
{
struct xnthread *thread;
sigset_t pending;
spl_t s;
thread = xnthread_from_task(p);
......
xnlock_get_irqsave(&nklock, s);
......
if (xnthread_test_state(thread, XNRELAX)) {
xnlock_put_irqrestore(&nklock, s);
return KEVENT_PROPAGATE;
}
......
if (p->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE))
cobalt_set_task_state(p, p->state | TASK_NOWAKEUP);
__xnthread_kick(thread);
xnsched_run();
xnlock_put_irqrestore(&nklock, s);
return KEVENT_PROPAGATE;
}
handle_sigwake_event()
涓殑閫昏緫寰堢畝鍗曪紝鍏堢湅A鏄繍琛屽湪root鍩熻繕鏄痟aed鍩燂紝濡傛灉鏈潵灏卞湪root鍩燂紙澶勪簬XNRELAX鐘舵€侊級锛屽嵆鍦╨inux鏍镐笂璋冨害锛岄偅涔堜笉鐢ㄥ仛浠€涔堟搷浣滐紝鍙洿鎺ュ鐞嗕俊鍙凤紱濡傛灉A鐜板湪鏄痟ead鍩熻皟搴︼紝鍏堢湅鐪嬪畠鏄笉鏄彲涓柇鐫$湢鐘舵€侊紙TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE锛夛紝鐒跺悗璋冪敤__xnthread_kick()
灏嗕换鍔韪㈠嚭haed鍩熴€傛渶鍚庤皟鐢?code>xnsched_run
灏咰PU璁╃粰linux璋冨害鍣ㄤ互灏藉揩鍞ら啋浠诲姟A杩涜淇″彿澶勭悊銆傚悗闈㈢殑澶勭悊涓巐inux涓€鑷淬€?/p>
瀵逛簬xenomai鍚憀inux鍙戦€佷俊鍙?/strong>锛岄渶瑕佸湪xenomai浠诲姟浠g爜鍐呮樉鎬ц皟鐢ㄥ嚱鏁?code>kill()鎴杙thread_kill()
鍙戦€併€備笖蹇呴』閫氳繃__STD()
淇グkill()
鍑芥暟锛岀紪璇戞椂鎵嶄細鐩存帴浣跨敤glibc鐨刱ill鍑芥暟,瀵筽thread_kill涔熸槸涓€鏍枫€備笉鍔犱慨楗扮殑kill()鎴杙thread_kill()鍑芥暟浼氬湪缂栬瘧鏃堕粯璁ら摼鎺ュ埌libcobalt瀹氫箟鐨勫嚱鏁般€?/p>
COBALT_IMPL(int, kill, (pid_t pid, int sig))
{
int ret;
if (pid <= 0)
return __STD(kill(pid, sig));
ret = XENOMAI_SYSCALL2(sc_cobalt_kill, pid, sig);
if (ret) {
if (ret == -ESRCH)
return __STD(kill(pid, sig));
....
}
return 0;
}
COBALT_IMPL(int, pthread_kill, (pthread_t thread, int sig))
{
int ret;
ret = -XENOMAI_SYSCALL2(sc_cobalt_thread_kill, thread, sig);
if (ret == ESRCH)
return __STD(pthread_kill(thread, sig));
return ret;
}
涓や釜鍑芥暟閮芥槸鍏堝皾璇曡xenomai鍐呮牳澶勭悊锛屽湪xenomai鍐呮牳鏈€缁堥兘浼氳皟鐢?code>__cobalt_kill()
;濡傛灉璇id涓嶆槸xenomai绾跨▼锛屾墠浼氳浆鑰岃皟鐢╣libc鐨刱ill鍑芥暟锛岄€氳繃linux鍐呮牳澶勭悊銆?/p>
鎬讳箣锛屼娇鐢╨inux淇″彿鐨勬搷浣滐紝涓嶇鏄疄鏃惰繕鏄潪瀹炴椂閮藉繀椤诲湪linux璋冨害鍣ㄤ笂杩愯鎵嶈兘瀹屾垚鎿嶄綔銆?/p>
2 xenomai淇″彿
xenomai绾跨▼闂寸殑淇″彿澶勭悊鏈哄埗鐢眡enomai鍐呮牳瀹炵幇锛屼笌linux绾跨▼淇″彿绫讳技锛屼絾娌℃湁linux绾跨▼淇″彿閭d箞澶嶆潅,瀹冦€?/p>
鏃㈢劧鏄痻enomai绾跨▼闂寸殑锛岄偅灏辫绫讳技鐨勫儚linux閭f牱瀹炵幇xenomai鍐呮牳鐨勪竴濂椾俊鍙风鐞嗘満鍒躲€傞鍏堟槸姣忎釜xenomai绾跨▼鐨勫唴鏍哥鐞嗙粨鏋刢obalt_thread閲岄潰鍏充簬淇″彿澶勭悊鐨勫瓧娈点€?/p>
struct cobalt_process {
......
struct list_head sigwaiters;
......
};
struct cobalt_thread {
......
struct xnthread threadbase;
struct cobalt_process *process;
......
/** Signal management. */
sigset_t sigpending;
struct list_head sigqueues[_NSIG]; /* in cobalt_sigpending */
struct xnsynch sigwait;
struct list_head signext;
......
};
sigpending
琛ㄧず鍝簺淇″彿灏氱瓑寰呭鐞嗭紙鏈喅锛夛紝杩欓噷鍙槸琛ㄧず鏌愪釜淇″彿寰呭鐞嗭紝璇ヤ俊鍙峰叿浣撴湁澶氬皯涓渶瑕佺湅sigqueues[]
锛?code>sigqueues[]
淇″彿闃熷垪锛屽畠鐨勫ぇ灏忔槸_NSIG锛屼篃灏辨槸璇存瘡涓俊鍙烽兘鏈変釜闃熷垪銆?code>sigwait
涓€涓祫婧愬悓姝ュ璞?xnsynch)琛ㄧず锛屾垜浠湪13.2 璧勬簮鍚屾瀵硅薄鈥攛nsynch灏忚妭瑙f瀽浜唜nsynch鏄共浠€涔堢敤鐨勶紝淇″彿涔熸槸涓€绉嶈祫婧愶紝鎵€浠ヨ繖閲岀敤鏉ョ瓑寰呬竴涓俊鍙疯祫婧?褰撶敤鎴疯皟鐢╯igwait绯荤粺璋冪敤绛夊緟涓€涓俊鍙风殑鏃跺€欙紝灏变細鍦?code>sigwait
涓婄潯鐪犵瓑寰呬俊鍙枫€?code>signext
鍦╯igwait鏃剁敤鏉ュ姞鍏obalt_process涓殑sigwaiters閾捐〃銆?/p>
xenomai鐨勪俊鍙蜂笌linux涓€鑷达紝1-31鍙蜂俊鍙蜂笉鏀寔鎺掗槦锛?1-64鍙蜂俊鍙锋敮鎸佹帓闃熴€?/p>
闇€瑕佹敞鎰忕殑鏄痻enomai鍐呯殑淇″彿闄や笌linux涓€鑷村杩樻湁鍑犱釜鐗规湁鐨勪俊鍙凤紝杩欎簺淇″彿鏄笉鍏紑鐨勶紝浠呭瓨鍦ㄤ簬xenomai鍐呮牳涓巐ibcobalt鍐呴儴锛涜繖浜涗俊鍙锋棤娉曞睆钄斤紝涓嶈兘杩涜鎺掗槦锛屼篃鏃犳硶灏嗗畠浠缃负淇″彿闆嗐€?/p>
/*archx86includeuapiasmsignal.h*/
#define SIGRTMIN 32
#define SIGRTMAX _NSIG
/*includexenomaicobaltuapisignal.h*/
#define SIGSUSP (SIGRTMAX + 1)
#define SIGRESM (SIGRTMAX + 2)
#define SIGRELS (SIGRTMAX + 3)
#define SIGKICK (SIGRTMAX + 4)
#define SIGDEMT (SIGRTMAX + 5)
SIGSUSP
瀵规寚瀹氱嚎绋媠uspend鎿嶄綔锛?code>SIGRESM 瀵规寚瀹氱嚎绋媟esume鎿嶄綔锛?code>SIGRELS 瀵规寚瀹氱嚎绋嬭В闃诲;SIGKICK
杩娇鎸囧畾绾跨▼閫€鍑轰富妯″紡;SIGDEMT
灏嗘寚瀹氱嚎绋嬮檷绾т负闈炲疄鏃剁嚎绋嬶紝璇ュ奖瀛愮嚎绋嬩粛鍙闂甔enomai璧勬簮锛屼絾涓嶅啀绔炰簤瀹炴椂璋冨害銆?/p>
xenomai淇″彿鐩稿叧鎺ュ彛锛岀敱libcobalt瀹炵幇銆傚涓?/p>
int sigwaitinfo(const sigset_t *set, siginfo_t *si);
int sigwait(const sigset_t *set, int *sig);
int sigtimedwait (const sigset_t *set, siginfo_t *si,
const struct timespec *timeout);
int sigpending(sigset_t *set);
int kill(pid_t pid, int sig);
int sigqueue(pid_t pid, int sig, const union sigval value);
int pthread_kill(pthread_t thread, int sig);
/*libcobaltsignal.c*/ COBALT_IMPL(int, kill, (pid_t pid, int sig)) { int ret; if (pid <= 0) return __STD(kill(pid, sig)); ret = XENOMAI_SYSCALL2(sc_cobalt_kill, pid, sig); if (ret) { if (ret == -ESRCH) return __STD(kill(pid, sig)); .... } return 0; } /*libcobalt hread.c*/ COBALT_IMPL(int, pthread_kill, (pthread_t thread, int sig)) { int ret; ret = -XENOMAI_SYSCALL2(sc_cobalt_thread_kill, thread, sig); if (ret == ESRCH) return __STD(pthread_kill(thread, sig)); return ret; }
鍏堥€氳繃绯荤粺璋冪敤璁﹛enomai鍐呮牳澶勭悊锛屾瘡涓敤鎴风嚎绋嬪湪鍐呮牳閮芥槸涓€涓换鍔★紝閮藉叿鏈塸id锛屼笉绠℃槸pid杩樻槸pthread_t锛屾渶缁堥兘浼氳浆鎹负xenomai绾跨▼鍐呮牳缁撴瀯cobalt_thread锛屽啀瀵筩obalt_thread杩涜淇″彿鐩稿叧鎿嶄綔銆傚鏋滀笉鑳借浆鎹㈣鏄庤pid鎴杙thread_t琛ㄧず鐨勭嚎绋嬩笉鏄竴涓獂enomai绾跨▼锛屽氨浼氳繑鍥濫SRCH銆傝浆鑰岃皟鐢╣libc鐨刾thread_kill銆乲ill鍑芥暟杩涜€岃linux鍘诲鐞嗐€?/p>
/*kernelxenomaiposix hread.c*/
COBALT_SYSCALL(thread_kill, conforming,
(unsigned long pth, int sig))
{
struct cobalt_local_hkey hkey;
struct cobalt_thread *thread;
int ret;
spl_t s;
......
hkey.u_pth = pth;
hkey.mm = current->mm;
thread = thread_lookup(&hkey);
if (thread == NULL)
ret = -ESRCH;
else
ret = __cobalt_kill(thread, sig, 0);
.....
return ret;
}
/*kernelxenomaiposixsignal.c*/
COBALT_SYSCALL(kill, conforming, (pid_t pid, int sig))
{
struct cobalt_thread *thread;
int ret;
spl_t s;
thread = cobalt_thread_find(pid);/*鎵惧埌绾跨▼*/
if (thread == NULL)
ret = -ESRCH;
else
ret = __cobalt_kill(thread, sig, 1);
return ret;
}
sc_cobalt_kill
绯荤粺璋冪敤,鍒欐槸閫氳繃pid鏉ユ壘鍒板搴旂殑cobalt_thread,鐒跺悗璋冪敤__cobalt_kill()
銆?code>sc_cobalt_thread_kill绯荤粺璋冪敤鍐咃紝灏唒thread_t浣滀负hashkey锛屾壘鍒拌绾跨▼鐨刢obalt_thread锛屾渶缁堣皟鐢?code>__cobalt_kill()銆?/p>
涓嶅悓鐨勬槸璋冪敤__cobalt_kill
鐨勭涓変釜鍙傛暟銆?code>sc_cobalt_kill绯荤粺璋冪敤浼犲叆鐨勬槸1锛岃〃绀虹粰绾跨▼缁勫彂閫佷俊鍙凤紝褰搕hread鎸囧悜鐨勯偅涓嚎绋嬫病鏈夌瓑寰呬换浣曚俊鍙锋椂浼氬皾璇曞彂閫佺粰鍚屼竴绾跨▼缁勫叾浠栫瓑寰呰淇″彿鐨勭嚎绋嬶紱sc_cobalt_thread_kill
绯荤粺璋冪敤鍐呬紶鍏ョ殑鏄?.褰搕hread鎸囧悜鐨勯偅涓嚎绋嬫病鏈夌瓑寰呬换浣曚俊鍙锋椂灏变笉鍋氫换浣曟搷浣滅洿鎺ヨ繑鍥炪€?/p>
int __cobalt_kill(struct cobalt_thread *thread, int sig, int group) /* nklocked, IRQs off */
{
struct cobalt_sigpending *sigp;
int ret = 0;
switch(sig) {
case 0:
/* Check for existence only. */
break;
case SIGSUSP:
xnthread_suspend(&thread->threadbase, XNSUSP,
XN_INFINITE, XN_RELATIVE, NULL);
if (&thread->threadbase == xnthread_current() &&
xnthread_test_info(&thread->threadbase, XNBREAK))
ret = -EINTR;
break;
case SIGRESM:
xnthread_resume(&thread->threadbase, XNSUSP);
goto resched;
case SIGRELS:
xnthread_unblock(&thread->threadbase);
goto resched;
case SIGKICK:
xnthread_kick(&thread->threadbase);
goto resched;
case SIGDEMT:
xnthread_demote(&thread->threadbase);
goto resched;
case 1 ... _NSIG:
sigp = cobalt_signal_alloc(); /*鍒嗛厤涓€涓俊鍙风粨鏋勪綋*/
if (sigp) {
sigp->si.si_signo = sig;
sigp->si.si_errno = 0;
sigp->si.si_code = SI_USER;
sigp->si.si_pid = task_pid_nr(current);
sigp->si.si_uid = get_current_uuid();
if (cobalt_signal_send(thread, sigp, group) <= 0)
cobalt_signal_free(sigp);
}
resched:
xnsched_run();
break;
default:
ret = -EINVAL;
}
return ret;
}
xenomai鍐呮牳涓璓OSIX淇″彿鏀寔鎺掗槦锛屽厛鍒嗛厤涓€涓猚obalt_sigpending銆傜洿鎺ュ垎閰嶇粨鏋勪綋澶у皬鐨勫唴瀛樻槸涓嶅彲鍙栫殑锛岃繖浼氬奖鍝嶅疄鏃舵€э紝xenomai閲囧彇鐨勫姙娉曟槸鍜寈nobject绫讳技锛屼笉閫氳繃鍔ㄦ€佸唴瀛樺垎閰嶏紝鍐呮牳鍒濆鍖栫殑鏃跺€欏氨鐢宠濂?code>_NSIG + (SIGRTMAX - SIGRTMIN) * 2涓猚obalt_sigpending鐨勫唴瀛榮igpending_mem锛岀劧鍚庡皢杩欎竴涓釜cobalt_sigpending绌垮埌閾捐〃sigpending_pool銆俢obalt_signal_alloc()灏辨槸鐩存帴浠庨摼琛╯igpending_pool涓婂彇涓€涓氨鍙互锛宑obalt_signal_free閲婃斁鏃跺啀鍔犲叆閾捐〃sigpending_pool銆?/p>
__SIGPOOL_SIZE
澶у皬,涓哄湪kernelxenomaiposixsignal.c
瀹氫箟濡備笅锛?/p>
#define __SIGPOOL_SIZE (sizeof(struct cobalt_sigpending) * (_NSIG + (SIGRTMAX - SIGRTMIN) * 2))
娉ㄦ剰锛氳繖璇存槑鏁翠釜xenomai绯荤粺鍐呭彧鏈?4涓猚obalt_sigpending锛岃繖鎰忓懗濡傛灉婊ョ敤xenomai淇″彿锛屾垨闅忔剰鍚戝叾浠杧enomai绾跨▼鍙戦€?gt;31鍙风殑淇″彿锛岃€岃繖涓嚎绋嬫病鏈夎皟鐢╯igwait鐨勬搷浣滐紝閭d箞杩欎簺cobalt_sigpending浼氳姘歌繙鐨勬帓闃熷湪杩欎釜绾跨▼涓婏紝鐩村埌绾跨▼A閫€鍑烘墠浼氳閲婃斁銆傝繖浼氬鑷碿obalt_sigpending鏋锛岃繘鑰屽奖鍝嶅叾浠栦娇鐢ㄤ俊鍙风殑绋嬪簭鏃犳硶姝e父宸ヤ綔銆?/strong>
涓婇潰鐨刢obalt_signal_alloc()鏄笉鏄疊UG锛熸病鏈塩obalt_signal_alloc()鍒嗛厤澶辫触鐨勫鐞嗛€昏緫銆傝繖鏍峰簲鐢ㄦ棤娉曠煡閬撴槸鍚﹀彂閫佹垚鍔熶簡銆?/mark>璁剧疆cobalt_sigpending鐨勪俊鍙风紪鍙穝i.si_signo锛屼俊鍙风被鍨媠i.si_code锛屽彂閫佽€呮槸璋乻i.si_pid锛屽彂閫佽€呯殑uid澶氬皯si.si_uid銆備娇鐢╟obalt_signal_send杩涜鍙戦€併€?/p>
涓嬮潰鐪嬪彂閫佸嚱鏁癱obalt_signal_send銆?/p>
鎴戜滑鍙戦€佷俊鍙风粰鐨勮繖涓嚎绋嬶紝鏈夊彲鑳芥鍦ㄩ樆濉炵瓑寰呬俊鍙凤紝鍏堣皟鐢╟obalt_signal_deliver鐪嬪畠鏄笉鏄湪绛夊緟锛屾槸鐨勮瘽鐩存帴灏遍€掗€?deliver)浜? 濡傛灉涓嶈兘鍙婃椂閫掗€?鍐嶅皢杩欎釜淇″彿鎸傝捣锛屼互涓嬩袱绫讳俊鍙蜂笉鏀寔鎺掗槦锛?.瀵逛簬灏忎簬SIGRTMIN(32)鐨勪俊鍙凤紝涓嶆敮鎸佹帓闃燂紝鍙寕璧蜂竴娆°€?.濡傛灉鍙戦€佹潵鐨剆igp鏄涓猄I_TIMER淇″彿锛堝畾鏃跺櫒鍒版湡淇″彿锛夛紝涔熷彧鎺掗槦涓€娆★紙涓巐inux澶勭悊鏂瑰紡涓€鑷达紝搴旇鏄痯osix鏍囧噯锛夈€傛帓闃熷氨鏄皢杩欎釜cobalt_sigpending鎻掑叆thread->sigqueues[signo-1]閾捐〃灏俱€?/p>
鎺掗槦鐨勪俊鍙锋槸涓嶄細琚唴鏍稿鐞嗙殑锛岀洿鍒扮敤璋冪敤sigwaitinfo銆乻igwait銆乻igtimedwait鏉ユ秷鑰椾粬浠€?/p>
绾跨▼璋冪敤 鍙戣捣绯荤粺璋冪敤杩涘叆xenomai鍐呮牳鍚庢渶缁堥兘鏄墽琛宻ignal_wait()銆?/p>
涓ょ淇″彿锛歺enomai淇″彿鍜宭inux淇″彿銆?/p>
鐞嗘竻鍙屾牳涓嬬殑淇″彿闇€瑕佸垎娓咃細Linux杩涚▼涓庣嚎绋嬨€亁enomai绾跨▼涓夎€呬箣闂寸殑鍏崇郴鍙婁綔鐢ㄥ煙銆?/p>
linux鐨勮繘绋嬩笌绾跨▼閮芥湁淇″彿灞忚斀闆嗭紝xenomai淇″彿鍒欐病鏈夈€?/p>
鍙屾牳搴旂敤浠g爜涓娇鐢ㄥ嚱鏁板彂閫乴inux淇″彿鏃讹紝鏈€濂戒娇鐢?code>__STD()淇グ淇″彿鐩稿叧鍑芥暟銆?/p>
濡傛灉涓嶆樉寮忚皟鐢ㄦ帴鍙?code>sigwaitinfo()銆?code>sigtimedwait()鍜?code>sigwait()鏉ユ帴鏀朵俊鍙峰鐞唜enomai淇″彿锛岄偅涔堟案杩滀笉浼氬緱鍒板鐞嗐€傛墍浠ヤ笉鑳芥互鐢▁enomai淇″彿锛屽洜涓轰俊鍙锋湁闄愩€?/p>
xenomai鍐呮牳灏嗕俊鍙蜂綔涓轰竴绉嶅悓姝ヨ祫婧愶紙xnsynch锛夋潵绠$悊锛岀煡閬撹繖涓€鐐癸紝骞剁悊瑙d簡13.2 璧勬簮鍚屾瀵硅薄鈥攛nsynch宸ヤ綔鍘熺悊锛屽氨鐭ラ亾xenomai淇″彿濡備綍宸ヤ綔銆?/p>
鏈枃涓烘湰鏂囦负鍗氫富鍘熷垱鏂囩珷锛岃浆杞借娉ㄦ槑鍑哄銆傚鏈夐敊璇紝娆㈣繋鎸囨銆傚崥瀹㈠湴鍧€锛?a href="https://www.cnblogs.com/wsg1100/">https://www.cnblogs.com/wsg1100/int cobalt_signal_send(struct cobalt_thread *thread,
struct cobalt_sigpending *sigp,
int group)
{ /* nklocked, IRQs off */
struct list_head *sigq;
int sig, ret;
/* Can we deliver this signal immediately?*/
ret = cobalt_signal_deliver(thread, sigp, group);
if (ret)
return ret; /* Yep, done. */
......
sig = sigp->si.si_signo;
sigq = thread->sigqueues + sig - 1;
if (!list_empty(sigq)) {
/* Queue non-rt signals only once. */
if (sig < SIGRTMIN)
return 0;
/* Queue rt signal source only once (SI_TIMER). */
if (!list_empty(&sigp->next))
return 0;
}
sigaddset(&thread->sigpending, sig);
list_add_tail(&sigp->next, sigq);
return 1;
}
static int cobalt_signal_deliver(struct cobalt_thread *thread,
struct cobalt_sigpending *sigp,
int group)
{ /* nklocked, IRQs off */
struct cobalt_sigwait_context *swc;
struct xnthread_wait_context *wc;
int sig, ret;
sig = sigp->si.si_signo;
XENO_BUG_ON(COBALT, sig < 1 || sig > _NSIG);
if (xnsynch_pended_p(&thread->sigwait)) {
wc = xnthread_get_wait_context(&thread->threadbase);
swc = container_of(wc, struct cobalt_sigwait_context, wc);
if (sigismember(swc->set, sig))
goto deliver;
}
/*
* If that does not work out and we are sending to a thread
* group, try to deliver to any thread from the same process
* waiting for that signal.
*/
if (!group || list_empty(&thread->process->sigwaiters))
return 0;
list_for_each_entry(thread, &thread->process->sigwaiters, signext) {
wc = xnthread_get_wait_context(&thread->threadbase);
swc = container_of(wc, struct cobalt_sigwait_context, wc);
if (sigismember(swc->set, sig))
goto deliver;
}
return 0;
deliver:
cobalt_copy_siginfo(sigp->si.si_code, swc->si, &sigp->si);
.....
xnthread_complete_wait(&swc->wc);
xnsynch_wakeup_one_sleeper(&thread->sigwait); /*鍞ら啋绾跨▼*/
list_del(&thread->signext);
cobalt_signal_free(sigp);
return 1;
}
2.2 xenomai鎺ユ敹澶勭悊淇″彿
sigwaitinfo()
銆?code>sigtimedwait()鍜?code>sigwait()鏉ユ帴鏀朵俊鍙凤紝閮芥槸posix鏍囧噯锛屼綔鐢ㄤ笌linux绾跨▼涓€鑷淬€傚悓鏍凤紝缂栬瘧鏃朵細閾炬帴鍒發ibcobalt锛屽啀鐢眑ibcobalt鍙戣捣绯荤粺璋冪敤銆?/p>
COBALT_IMPL(int, sigwait, (const sigset_t *set, int *sig))
{
int ret, oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
ret = -XENOMAI_SYSCALL2(sc_cobalt_sigwait, set, sig);
pthread_setcanceltype(oldtype, NULL);
return ret;
}
COBALT_IMPL(int, sigwaitinfo, (const sigset_t *set, siginfo_t *si))
{
int ret, oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
ret = XENOMAI_SYSCALL2(sc_cobalt_sigwaitinfo, set, si);
.....
pthread_setcanceltype(oldtype, NULL);
return ret;
}
COBALT_IMPL(int, sigtimedwait, (const sigset_t *set, siginfo_t *si,
const struct timespec *timeout))
{
int ret, oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
ret = XENOMAI_SYSCALL3(sc_cobalt_sigtimedwait, set, si, timeout);
......
pthread_setcanceltype(oldtype, NULL);
return ret;
}
static int signal_wait(sigset_t *set, xnticks_t timeout,
void __user *u_si,
int (*put_siginfo)(void __user *u_si,
const struct siginfo *si,
int overrun))
{
struct cobalt_sigpending *sigp = NULL;
struct cobalt_sigwait_context swc;
struct cobalt_thread *curr;
int ret, sig, n, overrun;
unsigned long *p, *t, m;
struct siginfo si, *sip;
struct list_head *sigq;
spl_t s;
curr = cobalt_current_thread();
check:
if (sigisemptyset(&curr->sigpending))
goto wait;
p = curr->sigpending.sig; /* pending */
t = set->sig; /* tested */
for (n = 0, sig = 0; n < _NSIG_WORDS; ++n) {
m = *p++ & *t++;
if (m == 0)
continue;
sig = ffz(~m) + n *_NSIG_BPW + 1;
break;
}
if (sig) {
sigq = curr->sigqueues + sig - 1;
......
sigp = list_get_entry(sigq, struct cobalt_sigpending, next);
INIT_LIST_HEAD(&sigp->next); /* Mark sigp as unlinked. */
if (list_empty(sigq))
sigdelset(&curr->sigpending, sig);
sip = &sigp->si;
ret = 0;
goto done;
}
wait:
if (timeout == XN_NONBLOCK) {
ret = -EAGAIN;
goto fail;
}
swc.set = set;
swc.si = &si;
xnthread_prepare_wait(&swc.wc);
list_add_tail(&curr->signext, &curr->process->sigwaiters);
ret = xnsynch_sleep_on(&curr->sigwait, timeout, XN_RELATIVE);
.......
sig = si.si_signo;
sip = &si;
done:
switch (sip->si_code) {
case SI_TIMER:
overrun = cobalt_timer_deliver(sip->si_tid);
break;
case SI_USER:
case SI_MESGQ:
case SI_QUEUE:
overrun = 0;
break;
default:
overrun = sip->si_overrun;
if (overrun)
sip->si_overrun = 0;
}
if (u_si == NULL)
goto out; /* Return signo only. */
ret = put_siginfo(u_si, sip, overrun);// signal_put_siginfo
if (ret)
goto out;
......
out:
.....
if (sigp &&
(void *)sigp >= sigpending_mem &&
(void *)sigp < sigpending_mem + __SIGPOOL_SIZE) {
xnlock_get_irqsave(&nklock, s);
list_add_tail(&sigp->next, &sigpending_pool);
xnlock_put_irqrestore(&nklock, s);
/* no more ref. to sigp beyond this point. */
}
return ret ?: sig;
fail:
return ret;
}
3 鍙屾牳淇″彿鎬荤粨
以上是关于xenomai鍐呮牳瑙f瀽涔嬩俊鍙穝ignal(浜?---xenomai淇″彿澶勭悊鏈哄埗的主要内容,如果未能解决你的问题,请参考以下文章