static void test_performance(void) { volatile int i; pth_uctx_create((pth_uctx_t *)&uctx[0]); pth_uctx_create((pth_uctx_t *)&uctx[1]); pth_uctx_make(uctx[1], NULL, 32*1024, NULL, dummy, NULL, uctx[0]); fprintf(stderr, "\n"); fprintf(stderr, "Performing %d user-space context switches... " "be patient!\n", DO_SWITCHES); stat_start = time(NULL); stat_switched = 0; for (i = 0; i < DO_SWITCHES; i++) { stat_switched++; pth_uctx_switch(uctx[0], uctx[1]); } stat_end = time(NULL); pth_uctx_destroy(uctx[0]); pth_uctx_destroy(uctx[1]); fprintf(stderr, "We required %d seconds for performing the test, " "so this means we can\n", (int)(stat_end-stat_start)); fprintf(stderr, "perform %d user-space context switches per second " "on this platform.\n", DO_SWITCHES/(int)(stat_end-stat_start)); fprintf(stderr, "\n"); return; }
static void dummy(void *ctx) { while (1) { stat_switched++; pth_uctx_switch(uctx[1], uctx[0]); } return; }
static void worker(void *ctx) { volatile int n = (int)ctx; volatile int i = 0; fprintf(stderr, "worker #%d: enter\n", n); for (i = 0; i < 100; i++) { fprintf(stderr, "worker #%d: working (step %d)\n", n, i); pth_uctx_switch(uctx[n], uctx[0]); } worker_done[n] = TRUE; fprintf(stderr, "worker #%d: exit\n", n); return; }
static void test_working(void) { volatile int i; volatile int todo; fprintf(stderr, "master: startup\n"); fprintf(stderr, "master: create contexts\n"); pth_uctx_create((pth_uctx_t *)&uctx[0]); worker_done[0] = FALSE; for (i = 1; i < 10; i++) { worker_done[i] = FALSE; pth_uctx_create((pth_uctx_t *)&uctx[i]); pth_uctx_make(uctx[i], NULL, 32*1024, NULL, worker, (void *)i, uctx[0]); } do { todo = 0; for (i = 1; i < 10; i++) { if (!worker_done[i]) { fprintf(stderr, "master: switching to worker #%d\n", i); pth_uctx_switch(uctx[0], uctx[i]); fprintf(stderr, "master: came back from worker #%d\n", i); todo = 1; } } } while (todo); fprintf(stderr, "master: destroy contexts\n"); for (i = 1; i < 10; i++) pth_uctx_destroy(uctx[i]); pth_uctx_destroy(uctx[0]); fprintf(stderr, "master: exit\n"); return; }
int CServiceDispatcher::Dispatch(CCmd& oCmd) { m_oCurCmdObj = oCmd; //printf("++org serno :%d\n",oCmd.iSvcSerialNo); //printf("--new serno :%d\n",m_oCurCmdObj.iSvcSerialNo); int iRet = 0; int iStateFulContinue = 0; IService* pSvcHandler = NULL; if (m_oCurCmdObj.iType == RESPONSE) { //if (oCmd.iSvcSerialNo) { map<int,IService*>::iterator it = m_mapStatefulSvcQueue.begin(); //printf("stateful-size-%d\n",m_mapStatefulSvcQueue.size()); for (;it != m_mapStatefulSvcQueue.end(); ++it) { printf("stateful-find-%d\n",it->first); if (m_oCurCmdObj.iSvcSerialNo == it->first) { iStateFulContinue = 1; pSvcHandler = it->second; printf("++stateful service find:%d\n",pSvcHandler->m_iIndex); assert(pth_uctx_switch(m_uctx, pSvcHandler->GetUCTX())); //iRet = pSvcHandler->Execute(oCmd); //m_mapStatefulSvcQueue.erase(it); //m_mapStatelessSvcQueue[oCmd.iSvcSerialNo] = pSvcHandler; //return iRet; } } if (!iStateFulContinue) { printf("can't find stateful %d in this process %d, stateful queue size:%d\n",m_oCurCmdObj.iSvcSerialNo,getpid(),m_mapStatefulSvcQueue.size()); } assert(iStateFulContinue); } else { if (m_mapStatelessSvcQueue.size() == 0 && iStateFulContinue == 0) { return NO_FREE_SVC_HANDLER; } else { map<int,IService*>::iterator it = m_mapStatelessSvcQueue.begin(); pSvcHandler = it->second; //m_oCurCmdObj.iSvcSerialNo = it->first; m_mapStatelessSvcQueue.erase(it); printf("--stateless service find:%d\n",pSvcHandler->m_iIndex); //printf("--stateless service find:%d\n",pSvcHandler->m_iIndex); m_mapStatefulSvcQueue[pSvcHandler->m_iIndex] = pSvcHandler; assert(pth_uctx_switch(m_uctx, pSvcHandler->GetUCTX())); } } printf("****back to main process******,data:%s\n",m_oCurCmdObj.ToString().c_str()); //int pth_uctx_switch(pth_uctx_t uctx_from, pth_uctx_t uctx_to); //iRet = pSvcHandler->Execute(oCmd); if (m_oCurCmdObj.iRet != UNFINISH_TASK_RET_FLAG) { if (pSvcHandler) { map<int,IService*>::iterator it = m_mapStatefulSvcQueue.find(pSvcHandler->m_iIndex); if (it != m_mapStatefulSvcQueue.end()) { m_mapStatefulSvcQueue.erase(it); } pSvcHandler->ResetUCTX();//每次ucontext使用完后,因为栈指针等没有复位,必须重新调用pth_uctx_make重置上下文信息,否则可能遭遇SIGSEGV错误 printf("--statful back stateless service :%d\n",pSvcHandler->m_iIndex); m_mapStatelessSvcQueue[pSvcHandler->m_iIndex] = pSvcHandler; } } oCmd = m_oCurCmdObj; return oCmd.iRet; //return iRet; }