#define BORDER_CHARS 1 U8 *buf; I64 size,mp_not_done_flags; CDoc *doc; U0 PDNormalize() { U8 *r=MAlloc(size+2*BORDER_CHARS), *src=buf,*dst=r; I64 ch; *dst++='['; //Border while (size--) { ch=*src++; if ('a'<=ch<='z') //lower is most common so do first *dst++=ch; else if ('A'<=ch<='Z') *dst++=ch+'a'-'A'; //Convert to lower } *dst++=']'; //Border Free(buf); buf=r; size=dst-r-2*BORDER_CHARS; } U0 PDAnswer(U8 *a,I64 len) { DocLock(doc); a-=(len-1)/2; DocPrint(doc,"CPU%02X Len:%2d ",Gs->num,len); while (len--) DocPrint(doc,"%C",*a++); //%C is toupper char DocPrint(doc,"\n"); DocUnlock(doc); } U0 MPPalindrome(I64 dummy=0) { no_warn dummy; U8 *src=buf+BORDER_CHARS+size*Gs->num/mp_cnt, *f,*b; I64 len,best=0, my_size=(size+mp_cnt-1)/mp_cnt; while (my_size--) { //Odd f=src+1; b=src-1; while (*f==*b) { f++; b--; } len=f-b+1-2; if (len>best) { best=len; PDAnswer(src,len); } //Even f=src+1; b=src; while (*f==*b) { f++; b--; } len=f-b+1-2; if (len>best) { best=len; PDAnswer(src,len); } src++; } LBtr(&mp_not_done_flags,Gs->num); } U0 Palindrome(U8 *filename) { I64 i; F64 t0=tS; buf=FileRead(filename,&size); PDNormalize; doc=DocPut; mp_not_done_flags=1<<mp_cnt-1; for (i=0; i<mp_cnt; i++) JobQue(&MPPalindrome,NULL,i); while (mp_not_done_flags) Yield; Free(buf); "Time:%9.5f\n" ,tS-t0; } Palindrome(BIBLE_FILENAME);