Print this page
OS-???? [lx] SIGEV_THREAD_ID emulation needed
*** 988,997 ****
--- 988,1048 ----
}
return (0);
}
+ case B_SIGEV_THREAD_ID: {
+ /*
+ * Emulate Linux's timer_create(2) SIGEV_THREAD_ID
+ * notification method. This mechanism is only meant
+ * for userland threading libraries such as glibc and
+ * is documented as such. Therefore, assume this is
+ * only ever invoked for the purpose of alerting a
+ * Linux threading library. Assume that the tid is a
+ * member of the caller's process and the signal
+ * number is valid. See lx_sigev_thread_id() for the
+ * userland side of this emulation.
+ *
+ * arg1 -- Linux tid
+ * arg2 -- signal number
+ * arg3 -- union sigval
+ */
+
+ proc_t *pp, *cp = curproc;
+ int native_sig = ltos_signo[(int)arg2];
+ pid_t native_pid;
+ int native_tid;
+ sigqueue_t *sqp;
+
+ lx_lpid_to_spair((pid_t)arg1, &native_pid, &native_tid);
+
+ mutex_enter(&pidlock);
+ if (((pp = prfind(native_pid)) == NULL) || (pp->p_stat == SIDL)) {
+ mutex_exit(&pidlock);
+ return (ESRCH);
+ }
+ mutex_enter(&pp->p_lock);
+ mutex_exit(&pidlock);
+
+ if ((t = idtot(pp, native_tid)) == NULL) {
+ mutex_exit(&pp->p_lock);
+ return (ESRCH);
+ }
+
+ sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
+ sqp->sq_info.si_signo = native_sig;
+ sqp->sq_info.si_code = SI_TIMER;
+ sqp->sq_info.si_pid = cp->p_pid;
+ sqp->sq_info.si_zoneid = getzoneid();
+ sqp->sq_info.si_uid = crgetruid(CRED());
+ sqp->sq_info.si_value = (union sigval)((void *)arg3);
+ sigaddqa(pp, t, sqp);
+
+ mutex_exit(&pp->p_lock);
+ return (0);
+ }
+
case B_SET_AFFINITY_MASK:
case B_GET_AFFINITY_MASK:
/*
* Retrieve or store the CPU affinity mask for the
* requested linux pid.