#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_count, *f, *b; I64 len, best = 0, my_size = (size + mp_count - 1) / mp_count; 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_count - 1; for (i = 0; i < mp_count; i++) JobQueue(&MPPalindrome, NULL, i); while (mp_not_done_flags) Yield; Free(buf); "Time:%9.5f\n", tS - t0; } Palindrome(BIBLE_FILENAME);