void * thread_func (void *arg) { int i = (int) (long) arg; do { // 좌우 두개 젓가락 모두 사용가능 할 때만 젖가락을 집는다. while(1) { if(tsem_try_wait(chopstick[i]) != 0) { continue; } if(tsem_try_wait(chopstick[(i + 1) % 5]) == 0) { break; } // 왼쪽 젖가락을 사용 할 수 없으면 오른쪽 젖가락을 내려 놓는다. tsem_signal (chopstick[i]); } update_status (i, 1); tsem_signal (chopstick[i]); // 포크 하나를 내려놓고 다른 철학자가 포크를 하나 집을때 까지 기다린다. while(tsem_try_wait(chopstick[i]) == 0) { tsem_signal (chopstick[i]); } tsem_signal (chopstick[(i + 1) % 5]); update_status (i, 0); } while (1); return NULL; }
static void update_status (int i, int eating) { static int status[5] = { 0, }; int idx; status[i] = eating; tsem_wait (printing); int sum = 0; for (idx = 0; idx < 5; idx++) { fprintf (stdout, "%3s ", status[idx] ? "EAT" : "..."); sum += status[idx]; } fprintf (stdout, "\n"); assert(sum > 0); // 항상 한명 이상이 식사중인지 체크 tsem_signal (printing); }
/** @brief Releases buffers under processing. * This function must be implemented in the derived classes, for the * specific processing */ OMX_ERRORTYPE clocksrc_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) { omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private; OMX_BUFFERHEADERTYPE* pBuffer; int errQue; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate; pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); openmaxStandPort->bIsPortFlushed=OMX_TRUE; /*Signal the buffer management thread of port flush,if it is waiting for buffers*/ if(omx_clocksrc_component_Private->bMgmtSem->semval==0) { tsem_up(omx_clocksrc_component_Private->bMgmtSem); } tsem_up(omx_clocksrc_component_Private->clockEventSem); tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem); if(omx_clocksrc_component_Private->state==OMX_StatePause ) { /*Waiting at paused state*/ tsem_signal(omx_clocksrc_component_Private->bStateSem); } DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex); /* Wait until flush is completed */ pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); tsem_down(omx_clocksrc_component_Private->flush_all_condition); tsem_reset(omx_clocksrc_component_Private->bMgmtSem); tsem_reset(omx_clocksrc_component_Private->clockEventSem); /* Flush all the buffers not under processing */ while (openmaxStandPort->pBufferSem->semval > 0) { DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n", __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex, (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem); tsem_down(openmaxStandPort->pBufferSem); pBuffer = dequeue(openmaxStandPort->pBufferQueue); if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n", __func__,omx_clocksrc_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); } else { ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); } } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { errQue = queue(openmaxStandPort->pBufferQueue,pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } } else { (*(openmaxStandPort->BufferProcessedCallback))( openmaxStandPort->standCompContainer, omx_clocksrc_component_Private->callbackData, pBuffer); } } /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/ if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){ tsem_down(openmaxStandPort->pBufferSem); DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem); } tsem_reset(openmaxStandPort->pBufferSem); } pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); openmaxStandPort->bIsPortFlushed=OMX_FALSE; pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); tsem_up(omx_clocksrc_component_Private->flush_condition); DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__, (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_clocksrc_component_Private->name); DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__, (int)openmaxStandPort->nTunnelFlags, (int)openmaxStandPort->pBufferQueue->nelem, (int)openmaxStandPort->pBufferSem->semval, (int)omx_clocksrc_component_Private->bMgmtSem->semval, omx_clocksrc_component_Private->name); DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex); return OMX_ErrorNone; }