Q_NODE *qFirst ( Q_HEAD *pQHead ) { return (Q_FIRST (pQHead)); }
STATUS semQFlush( SEM_ID semId ) { STATUS status; int level; INT_LOCK(level); if (OBJ_VERIFY (semId, semClassId) != OK) { INT_UNLOCK (level); status = ERROR; } else { /* Check next object */ if (Q_FIRST(&semId->qHead) == NULL) { INT_UNLOCK(level); status = OK; } else { /* Enter kernel and flush pending queue */ kernelState = TRUE; INT_UNLOCK(level); vmxPendQFlush(&semId->qHead); vmxExit(); status = OK; } } return status; }
void semBGiveDefer(SEM_ID semId) { if(NULL != (semId->semOwner = (RAIN_TCB*)Q_FIRST(&semId->qHead))) { kernelPendQGet(&semId->qHead); } }
STATUS semBGive(SEM_ID semId) { /* RAIN_TCB* pOwner; */ int level = intLock(); if(!IS_CLASS(semId, semClassId)) { intUnlock(level); return (ERROR); } /*pOwner = semId->semOwner;*/ if(NULL == (semId->semOwner = (RAIN_TCB*)Q_FIRST(&semId->qHead))) { intUnlock(level); } else { kernelState = TRUE; intUnlock(level); kernelPendQGet(&semId->qHead); kernelExit(); } return (OK); }
LOCAL void qMsgPendQGet( MSG_Q_ID msgQId, Q_MSG_HEAD *pQHead ) { if (Q_FIRST(&pQHead->pendQ) != NULL) { vmxPendQGet(&pQHead->pendQ); } }
void semQFlushDefer( SEM_ID semId ) { /* Check if flush needed */ if (Q_FIRST(&semId->qHead) != NULL) { vmxPendQFlush(&semId->qHead); } }
static vfs_task_t* vfs_findbypid (pid_t pid) { vfs_task_t *it = (vfs_task_t*)Q_FIRST(vfs_task_q); while (it) { if (it->pid == pid) { break; } it = (vfs_task_t*)Q_NEXT(it); } return (it); }
/*lint --e{78, 527,752 } */ void semQueueGiveDefer ( SEM_ID semId /* semaphore ID to give */ ) { #ifdef _WRS_CONFIG_SMP /* For SMP, we don't know if semId is still valid at this point */ if (OBJ_VERIFY (semId, semClassId) != OK) return; #endif /* _WRS_CONFIG_SMP */ if (Q_FIRST (&semId->qHead) == NULL) /* anyone blocked? */ { /*lint -save -e52*/ semId->semCount++; /* give semaphore */ /*lint -restore +e52*/ /* sem is free, send events if registered */ if (semId->events.taskId != (int)NULL) { /* * We will be here only if semId->events.taskId is non-null (i.e. * the event library has been configured). Hence we can eliminate * the null-check for _func_eventRsrcSend. */ /*lint -save -e119 -e533 */ if ((*_func_eventRsrcSend) (semId->events.taskId, semId->events.registered) != OK) { semId->events.taskId = (int)NULL; return; } /*lint -restore*/ if ((semId->events.options & EVENTS_SEND_ONCE) == EVENTS_SEND_ONCE) semId->events.taskId = (int)NULL; } } else { /*lint -save -e516*/ #ifdef _WRS_CONFIG_SV_INSTRUMENTATION /* system viewer - level 2 event logging */ EVT_TASK_1 (EVENT_OBJ_SEMGIVE, semId); #endif /* _WRS_CONFIG_SV_INSTRUMENTATION */ /*lint -restore +e516*/ windPendQGet (&semId->qHead); /* unblock a task */ } }
LOCAL STATUS semBGive( SEM_ID semId ) { STATUS status; int level; /* Lock interrupts */ INT_LOCK(level); /* Verify class */ if (OBJ_VERIFY(semId, semClassId) != OK) { INT_UNLOCK(level); status = ERROR; } else { /* Get next listening task from queue */ SEM_OWNER_SET(semId, Q_FIRST(&semId->qHead)); /* Check if no more tasks are waiting for this semaphore */ if (SEM_OWNER_GET(semId) == NULL) { INT_UNLOCK(level); status = OK; } else { /* Enter kernel mode */ kernelState = TRUE; INT_UNLOCK(level); /* Unblock next task waiting */ vmxPendQGet(&semId->qHead); /* Exit kernel mode */ vmxExit(); status = OK; } } return status; }
STATUS taskUnsafe( void ) { /* Check if state is chaged */ if ((taskIdCurrent->safeCount > 0) && (--taskIdCurrent->safeCount == 0)) { /* Enter kernel mode */ kernelState = TRUE; if (Q_FIRST(&taskIdCurrent->safetyQ) != NULL) { vmxPendQFlush(&taskIdCurrent->safetyQ); } /* Exit trough kernel */ vmxExit(); } return OK; }
LOCAL void semBGiveDefer( SEM_ID semId ) { TCB_ID pOwner; /* Verify class */ if (OBJ_VERIFY(semId, semClassId) == OK) { /* Get task id */ pOwner = SEM_OWNER_GET(semId); /* Set to next owner */ SEM_OWNER_SET(semId, Q_FIRST(&semId->qHead)); /* Check if it exists */ if (SEM_OWNER_GET(semId) != NULL) { vmxPendQGet(&semId->qHead); } } }
STATUS semQFlush(SEM_ID semId) { int level = intLock(); if(!IS_CLASS(semId, semClassId)) { intUnlock(level); } if(NULL == Q_FIRST(&semId->qHead)) { intUnlock(level); } else { kernelState = TRUE; intUnlock(level); kernelPendQFlush(&semId->qHead); kernelExit(); } return (OK); }
STATUS taskDestroy( int taskId, BOOL freeStack, unsigned timeout, BOOL forceDestroy ) { STATUS status; int i, level; TCB_ID tcbId; if (INT_RESTRICT() != OK) { errnoSet (S_intLib_NOT_ISR_CALLABLE); return ERROR; } /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) return ERROR; /* If task self destruct and excption lib installed */ if (tcbId == taskIdCurrent) { /* Wait for safe to destroy */ while (tcbId->safeCount > 0) taskUnsafe(); /* Kill it */ status = excJobAdd( (VOIDFUNCPTR) taskDestroy, (ARG) tcbId, (ARG) freeStack, (ARG) WAIT_NONE, (ARG) FALSE, (ARG) 0, (ARG) 0 ); /* Block here and suspend */ while(status == OK) taskSuspend(0); } /* End if task self destruct and exception lib installed */ taskDestroyLoop: /* Lock interrupts */ INT_LOCK(level); /* Check id */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } /* Mask all signals */ if (tcbId->pSignalInfo != NULL) tcbId->pSignalInfo->sigt_blocked = 0xffffffff; /* Block here for safe and running locked tasks */ while ( (tcbId->safeCount > 0) || ( (tcbId->status == TASK_READY) && (tcbId->lockCount > 0) ) ) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Check if force deletion, or suicide */ if (forceDestroy || (tcbId == taskIdCurrent)) { /* Remove protections */ tcbId->safeCount = 0; tcbId->lockCount = 0; /* Check if flush of safety queue is needed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); } else { /* Not forced deletion or suicide */ /* Put task on safe queue */ if (vmxPendQPut(&tcbId->safetyQ, timeout) != OK) { /* Exit trough kernel */ vmxExit(); errnoSet (S_taskLib_INVALID_TIMEOUT); return ERROR; } /* Exit trough kernel */ status = vmxExit(); /* Check for restart */ if (status == SIG_RESTART) { timeout = (sigTimeoutRecalc)(timeout); goto taskDestroyLoop; } /* Check if unsuccessful */ if (status == ERROR) { /* timer should have set errno to S_objLib_TIMEOUT */ return ERROR; } } /* End else forced or suicide */ /* Lock interrupts */ INT_LOCK(level); /* Now verify class id again */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } } /* End while blocked by safety */ /* Now only one cadidate is selected for deletion */ /* Make myself safe */ taskSafe(); /* Protet deletion cadidate */ tcbId->safeCount++; /* Check if not suicide */ if (tcbId != taskIdCurrent) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Suspend victim */ vmxSuspend(tcbId); /* Exit trough kernel */ vmxExit(); } else { /* Unlock interrupts */ INT_UNLOCK(level); } /* Run deletion hooks */ for (i = 0; i < MAX_TASK_DELETE_HOOKS; i++) if (taskDeleteHooks[i] != NULL) (*taskDeleteHooks[i])(tcbId); /* Lock task */ taskLock(); /* If dealloc and options dealloc stack */ if ( freeStack && (tcbId->options & TASK_OPTIONS_DEALLOC_STACK) ) { #if (_STACK_DIR == _STACK_GROWS_DOWN) objFree(taskClassId, tcbId->pStackEnd); #else /* _STACK_GROWS_UP */ objFree(taskClassId, tbcId - TASK_EXTRA_BYTES); #endif /* _STACK_DIR */ } /* Lock interrupts */ INT_LOCK(level); /* Invalidate id */ objCoreTerminate(&tcbId->objCore); /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Delete task */ status = vmxDelete(tcbId); /* Check if safe quque needs to be flushed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); /* Unprotect */ taskUnlock(); taskUnsafe(); return OK; }
STATUS qMsgPut( MSG_Q_ID msgQId, Q_MSG_HEAD *pQHead, Q_MSG_NODE *pNode, int key ) { STATUS status; int level; if (key == Q_MSG_PRI_TAIL) { /* Add to tail */ pNode->next = NULL; /* Lock interrupts */ INT_LOCK(level); /* Insert */ if (pQHead->first == NULL) { pQHead->last = pNode; pQHead->first = pNode; } else { pQHead->last->next = pNode; pQHead->last = pNode; } } else { /* Lock interrupts */ INT_LOCK(level); /* Insert at head */ if ((pNode->next = pQHead->first) == NULL) { pQHead->last = pNode; } pQHead->first = pNode; } /* Increase counter */ pQHead->count++; if (kernelState == TRUE) { INT_UNLOCK(level); workQAdd2((FUNCPTR) qMsgPendQGet, msgQId, pQHead); } else { /* Check if anybody is waiting for message */ if (Q_FIRST(&pQHead->pendQ) == NULL) { INT_UNLOCK(level); status = OK; } else { /* Unlock pedning task waiting for message */ kernelState = TRUE; INT_UNLOCK(level); vmxPendQGet(&pQHead->pendQ); vmxExit(); status = OK; } } return status; }
int createtree(struct fh *rootfh, int depth, int d_max, dist_func_t d_cnts, dist_func_t d_weights, int f_max, dist_func_t f_cnts, dist_func_t f_weights, int l_max, dist_func_t l_cnts, dist_func_t l_weights, dist_func_t f_sizes, int scale) { int i, num_dirs_at_root = 1, create_reported = 0, ret=-1; nameset_entry_t rootnse; struct cr_rec *cr; int rexmit_max_preserve = 0; /* * remember the distributions. */ cr_d_cnts = d_cnts; cr_d_weights = d_weights; cr_d_max = d_max; cr_f_cnts = f_cnts; cr_f_weights = f_weights; cr_f_max = f_max; cr_l_cnts = l_cnts; cr_l_weights = l_weights; cr_l_max = l_max; cr_f_sizes = f_sizes; cr_scale = scale; Q_INIT(&cr_worklist); /* * create a root name entry. */ if ((rootnse = nameset_alloc(NULL, NFDIR, 0/*never pick*/)) == NULL) { report_error(FATAL, "nameset_alloc error"); goto out; } nameset_setfh(rootnse, rootfh->data, rootfh->len); /* * set up the file contents data block. */ if ((filedata = malloc(8192)) == NULL) { report_perror(FATAL, "malloc error"); goto out; } memset(filedata, 'x', 8192); rexmit_max_preserve = rexmit_max; rexmit_max = 2; /* rexmit a few times before cancel */ /* * go! */ for (i=0 ; i<num_dirs_at_root ; i++) { cr_newdir(rootnse, depth); } /* * create everything in parallel. */ while ((cr = Q_FIRST(&cr_worklist)) != NULL) { /* * some feedback that things are moving along... */ if (created - create_reported >= 100) { printf("%d ", created); fflush(stdout); create_reported = created; } Q_REMOVE(&cr_worklist, cr, link); switch(cr->nse->type) { case NFDIR: cr_dir(cr); break; case NFREG: cr_file(cr); break; case NFLNK: cr_symlink(cr); break; default: report_error(FATAL, "bad type %d", cr->nse->type); goto out; } /* * wait for replies b/c they register new worklist items. */ if (Q_FIRST(&cr_worklist) == NULL) { op_barrier(0); } } /* * wait for everything to finish. (redundant with above loop.) */ if (op_barrier(0) < 0) { report_error(FATAL, "op_barrier error"); goto out; } ret = 0; out: rexmit_max = rexmit_max_preserve; if (filedata) { free(filedata); filedata = NULL; } return ret; }