Print this page
OS-4514 [lx] SIGEV_THREAD_ID emulation needed
@@ -988,10 +988,65 @@
}
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.
+ *
+ * The return code from this function is not checked
+ * by the caller since it executes in an asynchronous
+ * context and there is nothing much to be done. If
+ * this function does fail then it will manifest as
+ * Linux threads waiting for a signal they will never
+ * receive.
+ *
+ * arg1 -- Linux tid
+ * arg2 -- Linux signal number
+ * arg3 -- union sigval
+ */
+
+ int native_sig = lx_ltos_signo((int)arg2, 0);
+ pid_t native_pid;
+ int native_tid;
+ sigqueue_t *sqp;
+
+ if (native_sig == 0)
+ return (EINVAL);
+
+ lx_lpid_to_spair((pid_t)arg1, &native_pid, &native_tid);
+ sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
+ mutex_enter(&curproc->p_lock);
+
+ if ((t = idtot(curproc, native_tid)) == NULL) {
+ mutex_exit(&curproc->p_lock);
+ kmem_free(sqp, sizeof (sigqueue_t));
+ return (ESRCH);
+ }
+
+ sqp->sq_info.si_signo = native_sig;
+ sqp->sq_info.si_code = SI_TIMER;
+ sqp->sq_info.si_pid = curproc->p_pid;
+ sqp->sq_info.si_zoneid = getzoneid();
+ sqp->sq_info.si_uid = crgetruid(CRED());
+ sqp->sq_info.si_value.sival_ptr = (void *)arg3;
+ sigaddqa(curproc, t, sqp);
+
+ mutex_exit(&curproc->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.