YSRESULT YsThreadController::RunParallel(int nTask,YsThreadTask *task[]) { if(0>=nTask) { return YSOK; } int i; for(i=0; i<nTask; i++) { task[i]->taskId=i; task[i]->sta=YSTHREADTASKSTATE_IDLE; } if(1==nTask) { task[0]->EntryPoint(); return YSOK; } YsArray <pthread_t,16> hThread; hThread.Set(nTask,0); for(i=0; i<nTask; i++) { pthread_create(&hThread[i],NULL,YsPthreadLaunch,(void *)task[i]); } for(i=0; i<nTask; i++) { pthread_join(hThread[i],NULL); } // Do I have to clean threads? Does pthread_destory exist? return YSOK; }
int YsString::Printf(const char *fom,...) { const int trialBufSize=256; char buf[trialBufSize]; va_list arg_ptr; va_start(arg_ptr,fom); const int n=vsnprintf(buf,trialBufSize,fom,arg_ptr); va_end(arg_ptr); if(n<0) { // This compiler s**ks! It's not C99 compliant! (I'm talking about Visual C++ 2008) int bufSize=trialBufSize*2; YsArray <char> buf; for(;;) { buf.Set(bufSize,NULL); va_start(arg_ptr,fom); const int n=vsnprintf(buf,bufSize,fom,arg_ptr); va_end(arg_ptr); if(0<=n && n<bufSize) { YsArray <char,16>::Set(n+1,buf); return n; } bufSize*=2; } } else if(n<trialBufSize) { YsArray <char,16>::Set(n+1,buf); return n; } else { // Good compiler! It is C99 Compliant. char *buf=new char [n+1]; va_start(arg_ptr,fom); vsnprintf(buf,n+1,fom,arg_ptr); va_end(arg_ptr); YsArray <char,16>::Set(n+1,buf); delete [] buf; return n; } }
YSRESULT FsGuiCopyStringFromClipBoard(YsString &str) { const int bufLen=FsGuiGetStringLengthInClipBoardC(); if(0<bufLen) { YsArray <char> copyBuf; copyBuf.Set(bufLen+1,NULL); FsGuiCopyStringFromClipBoardC(copyBuf); str.Set(copyBuf); } else { str.Set(""); } return YSOK; }
YSRESULT YsThreadController::RunParallel(int nTask,YsThreadTask *task[]) { if(0>=nTask) { return YSOK; } int i; for(i=0; i<nTask; i++) { task[i]->taskId=i; task[i]->sta=YSTHREADTASKSTATE_IDLE; } if(1==nTask) { task[0]->EntryPoint(); return YSOK; } if(nTask-1<=threadCache.GetN()) { YsArray <HANDLE,16> hMutex; int nRunCached=nTask-1; while(1) // This loop makes sure cached threads are free from the previously-assigned tasks. { int nHot=0; for(i=0; i<nRunCached; i++) { if(YSTRUE==threadCache[i]->hot) { nHot++; break; } } if(0==nHot) { break; } } hMutex.Set(nRunCached,NULL); for(i=0; i<nRunCached; i++) { hMutex[i]=threadCache[i]->taskWaitMutex; threadCache[i]->task=task[i]; WaitForSingleObject(threadCache[i]->endWaitMutex,INFINITE); ReleaseMutex(threadCache[i]->taskWaitMutex); // Controlling thread releases ownership of taskWaitMutex. } task[nTask-1]->EntryPoint(); while(1) // This loop makes sure the child threads acquire taskWaitMutex. { int nCold=0; for(i=0; i<nRunCached; i++) { if(YSTRUE!=threadCache[i]->hot) { nCold++; break; } } if(0==nCold) { break; } } WaitForMultipleObjects(nRunCached,hMutex,TRUE,INFINITE); // Controlling thread re-acquire ownership of taskWaitMutex. for(i=0; i<nRunCached; i++) { ReleaseMutex(threadCache[i]->endWaitMutex); } } else { YsArray <HANDLE,16> hThread; hThread.Set(nTask-1,0); for(i=0; i<nTask-1; i++) { hThread[i]=CreateThread(NULL,32768,YsWin32ThreadLaunch,task[i],0,NULL); } task[nTask-1]->EntryPoint(); WaitForMultipleObjects(nTask-1,hThread,TRUE,INFINITE); for(i=0; i<nTask-1; i++) { CloseHandle(hThread[i]); } } return YSOK; }
void YsArguments2(YsArray <YsString,16> &args,const char vv[],YSSIZE_T l,const char *blank,const char *comma) { YsString empty; args.Set(0,NULL); YSSIZE_T i=0; while(YSTRUE==CharIsOneOf(vv[i],blank)) { i++; } YSSIZE_T head=i; while(i<l) { if(vv[head]=='\"') { head++; i++; while(i<l && vv[i]!='\"') { if(vv[i]&0x80) // 1st letter of Kanji character? { i++; } else if(isprint(vv[i])==0) { break; } i++; } args.Append(empty); args[args.GetN()-1].Set(i-head,vv+head); if(vv[i]=='\"') { i++; } } else { while(i<l && (CharIsOneOf(vv[i],blank)!=YSTRUE && CharIsOneOf(vv[i],comma)!=YSTRUE)) { if(vv[i]&0x80) // 1st letter of Kanji character? { i++; } else if(isprint(vv[i])==0) { break; } i++; } if(head<i) // <- This condition is added on 2005/03/03 { args.Append(empty); args[args.GetN()-1].Set(i-head,vv+head); } else if(head==i && YSTRUE==CharIsOneOf(vv[i],comma)) // < This condition is added (I thought there was, did I accidentally delet?) on 2012/01/26 { args.Increment(); args.GetEnd().Set(""); } } while(i<l && isprint(vv[i])==0) { i++; } while(i<l && CharIsOneOf(vv[i],blank)==YSTRUE) // Skip blank separator { i++; } if(CharIsOneOf(vv[i],comma)==YSTRUE) // Skip one comma separator { i++; while(i<l && CharIsOneOf(vv[i],blank)==YSTRUE) // Skip blank separator after a comma separator { i++; } if(i==l) { args.Append(empty); } } head=i; } }
YSRESULT YsShell::MergeDat(const char fn[]) { FILE *fp; YsArray <YsShellVertexHandle> vtHdList; fp=fopen(fn,"r"); if(fp!=NULL) { char buf[4096]; YsArray <YsShellVertexHandle,64> plVtHd; while(fgets(buf,4095,fp)!=NULL) { int ac; char *av[1024]; if(YsArguments(&ac,av,1024,buf)==YSOK && ac>0) { if(av[0][0]=='v' || av[0][0]=='V') { if(ac>=4) { YsShellVertexHandle vtHd; YsVec3 pos; double x,y,z; x=atof(av[1]); y=atof(av[2]); z=atof(av[3]); pos.Set(x,y,z); vtHd=AddVertexH(pos); vtHdList.Append(vtHd); } else { goto ERREND; } } else if(av[0][0]=='f' || av[0][0]=='F') // D:Delta=Triangle { if(ac>=4) { int i; YsShellPolygonHandle plHd; plVtHd.Set(ac-1,NULL); for(i=0; i<ac-1; i++) { plVtHd[i]=vtHdList[atoi(av[i+1])]; } plHd=AddPolygonH(ac-1,vtHdList); SetColorOfPolygon(plHd,YsBlue()); } else { goto ERREND; } } } } fclose(fp); return YSOK; } ERREND: if(fp!=NULL) { fclose(fp); } return YSERR; }