/* Must be called with nklock locked, interrupts off. */ static STATUS semm_give(wind_sem_t *sem) { xnthread_t *cur = xnpod_current_thread(); int resched = 0; check_NOT_ISR_CALLABLE(return ERROR); if (cur != xnsynch_owner(&sem->synchbase)) { wind_errnoset(S_semLib_INVALID_OPERATION); return ERROR; } if (--sem->count > 0) return OK; if (xnsynch_release(&sem->synchbase)) { sem->count = 1; resched = 1; } if (xnsynch_test_flags(&sem->synchbase, WIND_SEM_DEL_SAFE)) if (taskUnsafeInner(cur)) resched = 1; if (resched) xnpod_schedule(); return OK; }
MSG_Q_ID msgQCreate(int nb_msgs, int length, int flags) { static unsigned long msgq_ids; wind_msgq_t *queue; xnflags_t bflags = 0; int i, msg_size; char *msgs_mem; spl_t s; check_NOT_ISR_CALLABLE(return 0); error_check(nb_msgs <= 0, S_msgQLib_INVALID_QUEUE_TYPE, return 0); error_check(flags & ~WIND_MSG_Q_OPTION_MASK, S_msgQLib_INVALID_QUEUE_TYPE, return 0); error_check(length < 0, S_msgQLib_INVALID_MSG_LENGTH, return 0); msgs_mem = xnmalloc(sizeof(wind_msgq_t) + nb_msgs * (sizeof(wind_msg_t) + length)); error_check(msgs_mem == NULL, S_memLib_NOT_ENOUGH_MEMORY, return 0); queue = (wind_msgq_t *)msgs_mem; msgs_mem += sizeof(wind_msgq_t); queue->magic = WIND_MSGQ_MAGIC; queue->msg_length = length; queue->free_list = NULL; initq(&queue->msgq); inith(&queue->rlink); queue->rqueue = &wind_get_rholder()->msgQq; /* init of the synch object : */ if (flags & MSG_Q_PRIORITY) bflags |= XNSYNCH_PRIO; xnsynch_init(&queue->synchbase, bflags, NULL); msg_size = sizeof(wind_msg_t) + length; for (i = 0; i < nb_msgs; ++i, msgs_mem += msg_size) free_msg(queue, (wind_msg_t *)msgs_mem); xnlock_get_irqsave(&nklock, s); appendq(queue->rqueue, &queue->rlink); xnlock_put_irqrestore(&nklock, s); sprintf(queue->name, "mq%lu", msgq_ids++); if (xnregistry_enter(queue->name, queue, &queue->handle, &msgq_pnode)) { wind_errnoset(S_objLib_OBJ_ID_ERROR); msgQDelete((MSG_Q_ID)queue); return 0; } return (MSG_Q_ID)queue; }
/* Must be called with nklock locked, interrupts off. */ static STATUS semb_give(wind_sem_t *sem) { if (xnsynch_wakeup_one_sleeper(&sem->synchbase) != NULL) xnpod_schedule(); else { if (sem->count != 0) { wind_errnoset(S_semLib_INVALID_OPERATION); return ERROR; } sem->count = 1; } return OK; }
static int __wind_errno_taskset(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); int errcode = __xn_reg_arg2(regs); WIND_TCB *pTcb; if (!handle) { wind_errnoset(errcode); return 0; } pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (errnoOfTaskSet((TASK_ID) pTcb, errcode) == ERROR) return wind_errnoget(); return 0; }
SEM_ID semMCreate(int flags) { int bflags = XNSYNCH_OWNER; error_check(flags & ~WIND_SEMM_OPTION_MASK, S_semLib_INVALID_QUEUE_TYPE, return 0); if (flags & SEM_Q_PRIORITY) bflags |= XNSYNCH_PRIO; if (flags & SEM_INVERSION_SAFE) { if (!(flags & SEM_Q_PRIORITY)) { wind_errnoset(S_semLib_INVALID_OPTION); return 0; } bflags |= XNSYNCH_PIP; } if (flags & SEM_DELETE_SAFE) bflags |= WIND_SEM_DEL_SAFE; return sem_create_internal(bflags, &semm_vtbl, 0); }