Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/mty-makai/mty.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 146 by notanpe, Mon Apr 23 09:42:43 2007 UTC revision 148 by notanpe, Mon Apr 23 14:02:47 2007 UTC
# Line 11  Line 11 
11  #include <assert.h>  #include <assert.h>
12  #include <ctype.h>  #include <ctype.h>
13  #include <errno.h>  #include <errno.h>
 #include <malloc.h>  
14  #include <limits.h>  #include <limits.h>
15  #include <stdarg.h>  #include <stdarg.h>
16  #include <stddef.h>  #include <stddef.h>
# Line 19  Line 18 
18  #include <stdlib.h>  #include <stdlib.h>
19  #include <string.h>  #include <string.h>
20  #include <time.h>  #include <time.h>
21    #include <sys/types.h>
22    
23  #if defined(WIN32)  #if defined(WIN32)
24    
25  #include <windows.h>  #include <windows.h>
26    #include <process.h>
27  #include <sys/timeb.h>  #include <sys/timeb.h>
28    
29  #elif defined(__GNUC__)  #elif defined(__GNUC__)
# Line 40  Line 41 
41  #include "synth.h"  #include "synth.h"
42  #include "tr64.h"  #include "tr64.h"
43  #include "translate.h"  #include "translate.h"
44    #include "util.h"
45  #include "wdict.h"  #include "wdict.h"
46    
47  #if USE_DT  #if USE_DT
48  #include "dt4.h"  #include "dt4.h"
49  #endif  #endif
50    
 /* 鍵文字列 */  
 unsigned char key[8 + 8];  
 unsigned char okey[8 + 8];  
   
51  /* 鍵クラス */  /* 鍵クラス */
52  static  static
53  struct  struct
54  {  {
55    unsigned cls;    unsigned short map[256];
   unsigned map[256];  
56  } kcls[8 + 8];  } kcls[8 + 8];
57    
58    
# Line 74  struct DT *dtidx[0x100 + 1]; Line 71  struct DT *dtidx[0x100 + 1];
71    
72  /* 指定されたクラスと入っているキーから、classify を行う */  /* 指定されたクラスと入っているキーから、classify を行う */
73  void  void
74  key_make_map(int n)  key_make_map(uint8_t *key, int n)
75  {  {
76    int i, j;    int i, j;
77    unsigned c = kcls[n].map[key[n]];    unsigned c = kcls[n].map[key[n]];
# Line 373  key_set64(struct KEY *key64, Line 370  key_set64(struct KEY *key64,
370  /* 指定されたクラスの開始値にリセット  /* 指定されたクラスの開始値にリセット
371     直前の文字のクラスに縛られる */     直前の文字のクラスに縛られる */
372  int  int
373  key_reset(int n)  key_reset(uint8_t *key, int n)
374  {  {
375    if (n >= 8)    if (n >= 8)
376          return 1;          return 1;
# Line 385  key_reset(int n) Line 382  key_reset(int n)
382    
383    /* 0-2 文字目はランダムに決める    /* 0-2 文字目はランダムに決める
384           3 文字目以降は初期値に */           3 文字目以降は初期値に */
385    if (n >= 3)    if (n >= KEY_SHUFFLE_POS)
386          key[n] = key_set(n, 0);          key[n] = key_set(n, 0);
387    else    else
388          key[n] = key_set(n, rand());          key[n] = key_set(n, rand());
# Line 395  key_reset(int n) Line 392  key_reset(int n)
392  #endif  #endif
393    
394    /* セットされた文字を元に、次キャラの文字クラスを決める */    /* セットされた文字を元に、次キャラの文字クラスを決める */
395    key_make_map(n);    key_make_map(key, n);
396    
397    return key_reset(n + 1);    return key_reset(key, n + 1);
398  }  }
399    
400  /* 指定された鍵空間の中で、キーをひとつ進める  /* 指定された鍵空間の中で、キーをひとつ進める
401     安全にインクリメントできた場合 true を返す */     安全にインクリメントできた場合 true を返す */
402  static  static
403  int  int
404  key_inc(int n)  key_inc(uint8_t *key, int n)
405  {  {
406    if (n >= 8)    if (n >= 8)
407          return 0;          return 0;
408    else if (n == 7)    else if (n == 7)
409          {          {
410            /* 最後のバイト */            /* 最後のバイト */
411            key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;            uint8_t o_k = (key[7] + (1 << N_STRIDE)) & 0x7F;
412            if (key[7]) return 1;            if (!o_k)
413            else return 0;                  return 0;       /* インクリメントできなかったときは次へ進めず待つ */
414    
415              /* 進める */
416              key[7] = o_k;
417              return 1;
418          }          }
419    else if (key_inc(n + 1)    else if (key_inc(key, n + 1)
420                     /*                     /*
421                          && key_inc(n + 1)                          && key_inc(n + 1)
422                     && key_inc(n + 1)                     && key_inc(n + 1)
# Line 537  key_inc(int n) Line 538  key_inc(int n)
538                  {                  {
539                    key[n] = (key[n] & 0x7F) + 1;                    key[n] = (key[n] & 0x7F) + 1;
540                    if (key[n] >= 0x80)                    if (key[n] >= 0x80)
541                          return 0;                          {
542                              key[n] = 0xFF;        /* 次に突入させないため */
543                              return 0;
544                            }
545                  }                  }
546    
547            if (kcls[n].map[key[n]])            if (kcls[n].map[key[n]])
548                  {                  {
549                    key_make_map(n);                    key_make_map(key, n);
550                    key_reset(n + 1);                    key_reset(key, n + 1);
551                    return 1;                    return 1;
552                  }                  }
553          }          }
   while (++key[n] < 0x80)  
         {  
           if (kcls[n].map[key[n]])  
                 {  
                   key_make_map(n);  
                   key_reset(n + 1);  
                   return 1;  
                 }  
         }  
   return 0;  
554  }  }
555    
556  /* 鍵を完全にリセットする  /* 鍵を完全にリセットする
557     Saltもセットし直す */     Saltもセットし直す */
558  static  static
559  void  void
560  key_init()  key_init(uint8_t *key)
561  {  {
562    int i, j;    int i, j;
563    
# Line 622  key_init() Line 616  key_init()
616                  kcls[0].map[i - 128] |= kcls[0].map[i];                  kcls[0].map[i - 128] |= kcls[0].map[i];
617          }          }
618    
619    key_reset(0);    key_reset(key, 0);
620  }  }
621    
622  /***************************************************************  /***************************************************************
# Line 678  key_init_sk(struct KEY *key) Line 672  key_init_sk(struct KEY *key)
672   */   */
673    
674  #if N_STRIDE == 6  #if N_STRIDE == 6
675  #define C(c,i,j,o) (*(int8_t  *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))  #define C(c,i,j,o) (*(int8_t  *)((c) + (loo - crypt64_pro) + los[6 * (i) + (j) + (o)]))
676  #elif N_STRIDE == 7  #elif N_STRIDE == 7
677  #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))  #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_pro) + los[6 * (i) + (j) + (o)]))
678  #endif  #endif
679    
680  void  void
681  set_salt(signed char *code,  set_salt(CODE_T *code,
682                   unsigned char const *k)                   uint8_t const *k)
683  {  {
684    int i, j;    int i, j;
685    
# Line 739  set_salt(signed char *code, Line 733  set_salt(signed char *code,
733    
734  static  static
735  uint32_t  uint32_t
736  usec()  usec(void)
737  {  {
738    static uint32_t epoch = 0;    static uint32_t epoch = 0;
739    uint32_t sec, msec;    uint32_t sec, msec;
# Line 781  log_printf(FILE *ofp, char const *fmt, . Line 775  log_printf(FILE *ofp, char const *fmt, .
775    
776  /***************************************************************  /***************************************************************
777   *   *
778   *      メインループとか   *      バッチ処理用パケット
779   *   *
780   */   */
781    
782  ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);  struct PACKET_CRYPT64
783  ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);  {
784      union
785      {
786            uint8_t         key[8];         /* 最後にセットしたキー */
787            SLICE           pad;
788      } uk;
789      struct KEY    key64;
790      struct PARAM  param64;        /* 最後尾の要素では、PARAM::hit[]が可変長 */
791    };
792    
793    static
794    struct PACKET_CRYPT64 *
795    packet_create(int n,    /* パケット数 */
796                              int tn,       /* 末尾要素にて必要なワーク数 */
797                              uint8_t const *ini_key)
798    {
799      int i;
800      int siz;
801      void *p;
802      struct PACKET_CRYPT64 *pkts;
803      assert(IS_POWER2(sizeof(struct PACKET_CRYPT64)));
804      assert(n >= 1);
805    
806      siz = (sizeof(WS_T) - 1
807                     + (n - 1) * sizeof(struct PACKET_CRYPT64)
808                     + offsetof(struct PACKET_CRYPT64, param64.hit[tn]));
809      p = calloc(siz, 1);
810      /* バンダリあわせ */
811      pkts = (struct PACKET_CRYPT64 *)(((intptr_t)p
812                                                                            + sizeof(WS_T) - 1)
813                                                                       & -sizeof(WS_T));
814    #if DEBUG>=1
815      fprintf(stderr,
816                      "packet(n=%d,tn=%d) %d allocated; %p aligned to %p\n",
817                      n, tn,
818                      siz, p, pkts);
819    #endif
820    
821      /* 内部の初期化
822             コピーして回るのは、厳密には
823             最終要素のケツを破ってしまうことになるので
824             どうせ速度も要求されないしベタコード */
825      for (i = 0; i < n; i++)
826            {
827              int j;
828    
829              /* t[16] は、内部演算で使用する、all 1 が入っている */
830              memset(&pkts[i].param64.t[T_INV], -1, sizeof(SLICE));
831    
832              /* 固定キーの生成 */
833              key_init_sk(&pkts[i].key64);
834    
835              /* キースケジュールをここに押し込めておく
836                     従来は crypt64.S 内で完結するように引いていた */
837              for (j = 0; j < 28; j++)
838                    pkts[i].key64.ks[j].a[0] = sizeof(WS_T) * ks_ls[j];
839    
840              /* 念のため、鍵をここで落ち着けておく(不要?) */
841              for (j = 0; j < 8; j++)
842                    key_set64(&pkts[i].key64, j, pkts[i].uk.key[j] = ini_key[j], 0, 0x7F);
843            }
844    
845      return pkts;
846    }
847    
848    /***************************************************************
849     *
850     *      thread
851     *
852     */
853    
854    #define NQ_CRYPT        64
855    #define NQ_CMP          32
856    
857    #if defined(__GNUC__)
858    
859    typedef int32_t ATOMWORD_T;
860    
861    #define LOCK_INC(p)     \
862    asm volatile ("lock incl %0"    \
863                              : "=m"(*(p))  \
864                              : /*nil*/             \
865                              : "memory")
866    
867    #define LOCK_DEC(p)     \
868    asm volatile ("lock decl %0"    \
869                              : "=m"(*(p))  \
870                              : /*nil*/             \
871                              : "memory")
872    
873    #define LOCK_CAS(pd,s,r)        \
874    ({      ATOMWORD_T a;                                                   \
875            asm volatile ("lock cmpxchg %2,%1"              \
876                                      : "=a"(a)                                     \
877                                      : "m"(*(pd)), "r"(s), "0"(r)  \
878                                      : "memory");a;})
879    
880    #define LOCK_CASP(pd,s,r)       \
881    ({      void *a;                                                                \
882            asm volatile ("lock cmpxchg %2,%1"              \
883                                      : "=a"(a)                                     \
884                                      : "m"(*(pd)), "r"(s), "0"(r)  \
885                                      : "memory");a;})
886    
887    
888    #elif defined(WIN32)
889    
890    typedef LONG ATOMWORD_T;
891    
892    #define LOCK_INC(p) InterlockedIncrement((LONG *)(p))
893    #define LOCK_DEC(p) InterlockedDecrement((LONG *)(p))
894    #define LOCK_CAS(pd,s,r) InterlockedCompareExchange((LONG *)(pd), s, r)
895    #define LOCK_CASP(pd,s,r) InterlockedCompareExchangePointer((PVOID *)(pd), (PVOID)(s), (PVOID)r)
896    
897    #else
898    #error "configuration not implemented"
899    #endif
900    
901    #if defined(WIN32)
902    
903    typedef DWORD THREAD_TIMEOUT_T;
904    
905    #define THREAD_INFINITE INFINITE
906    
907    typedef HANDLE THREAD_TH_T;
908    typedef HANDLE THREAD_EV_T;
909    
910    #define thread_sleep(n) Sleep(n)
911    #define thread_create(th, proc, arg) {(th) = (HANDLE)_beginthread(proc, 8192, arg);}
912    #define thread_create_event(ev, f) {(ev) = CreateEvent(NULL, TRUE, f, NULL);}
913    #define thread_signal_event(ev) SetEvent(ev)
914    #define thread_clear_event(ev) ResetEvent(ev)
915    #define thread_get_tid()        GetCurrentThread()
916    #define thread_set_priority(tid,n)      SetThreadPriority(tid, n)
917    #define thread_set_affinity(tid,m)      SetThreadAffinityMask(tid, (DWORD_PTR)1 << (m))
918    
919    static
920    int
921    thread_wait_event(THREAD_EV_T ev, DWORD tmo)
922    {
923      DWORD r = WaitForSingleObject(ev, tmo);
924      return (r < 0
925                      ? r
926                      : (r == WAIT_TIMEOUT
927                             ? -1
928                             : r));
929    }
930    
931    #elif defined(_POSIX_SOURCE) || defined(FREEBSD) || defined(SOLARIS)
932    
933    #include <pthread.h>
934    #include <unistd.h>
935    
936    typedef int THREAD_TIMEOUT_T;
937    
938    #define THREAD_INFINITE INT_MAX
939    
940    #if defined(THREAD_PRIORITY_BELOW_NOROMAL) || defined(THREAD_PRIORITY_IDLE)
941    #error "unsupported implementation"
942    #endif
943    
944    #define THREAD_PRIORITY_NORMAL  14
945    #define THREAD_PRIORITY_BELOW_NORMAL    15
946    #define THREAD_PRIORITY_IDLE    16
947    
948    typedef pthread_t THREAD_TH_T;
949    typedef struct
950    {
951      pthread_mutex_t       m;
952      pthread_cond_t        c;
953      int volatile          f;
954    } THREAD_EV_T;
955    
956    #define thread_sleep(n) (usleep(1000 * (n)) != EINVAL || sleep((n) / 1000))
957    #define thread_create(th, proc, arg) thread_create_p(&(th), proc, arg)
958    #define thread_create_event(ev, f) thread_create_event_p(&(ev), f)
959    #define thread_signal_event(ev) thread_set_event_p(&(ev), 1)
960    #define thread_clear_event(ev) thread_set_event_p(&(ev), 0)
961    #define thread_wait_event(ev,tmo) thread_wait_event_p(&(ev), tmo)
962    
963    static
964    void
965    thread_create_p(pthread_t *th, NORETURN (*proc)(void *), void *param)
966    {
967      pthread_create(th, NULL, (void *(*)(void *))proc, param);
968    }
969    
970    static
971    void
972    thread_create_event_p(THREAD_EV_T *ev, int f)
973    {
974      ev->f = f;
975      pthread_cond_init(&ev->c, NULL);
976      pthread_mutex_init(&ev->m, NULL);
977    }
978    
979    static
980    void
981    thread_set_event_p(THREAD_EV_T *ev, int f)
982    {
983      pthread_mutex_lock(&ev->m);
984      if (ev->f != f)
985            {
986              ev->f = f;
987              pthread_cond_broadcast(&ev->c);
988            }
989      pthread_mutex_unlock(&ev->m);
990    }
991    
992    static
993    int
994    thread_wait_event_p(THREAD_EV_T *ev, int a_tmo)
995    {
996      int timeout = a_tmo;
997      struct timeval now;
998      struct timespec tmo;
999      int r;
1000    
1001      pthread_mutex_lock(&ev->m);
1002    
1003      /* 現在時刻からタイムアウト時刻を求める
1004             めんどくせー */
1005      gettimeofday(&now, NULL);
1006      tmo.tv_sec = now.tv_sec + (timeout / 1000);
1007      timeout %= 1000;
1008      timeout *= 1000;
1009      if (now.tv_usec >= 1000000 - timeout)
1010            {
1011              timeout -= 1000000;
1012              tmo.tv_sec++;
1013            }
1014      tmo.tv_nsec = 1000 * (now.tv_usec + timeout);
1015      r = 0;
1016      while (!ev->f)
1017            {
1018              r = pthread_cond_timedwait(&ev->c, &ev->m, &tmo);
1019              if (r == ETIMEDOUT
1020                      && a_tmo < THREAD_INFINITE)
1021                    break;
1022            }
1023    
1024      pthread_mutex_unlock(&ev->m);
1025    
1026      return (r == ETIMEDOUT
1027                      ? (ETIMEDOUT < 0 ? ETIMEDOUT : -1)
1028                      : 0);
1029    }
1030    
1031    #if defined(__linux__)
1032    
1033    /* デフォルトスケジューリングポリシーでは
1034       優先度設定したりアイドルスレッド起こしても
1035       おもしろくないので、そのへんは今後の研究課題。 */
1036    
1037    #include <linux/unistd.h>
1038    _syscall0(pid_t,gettid)
1039    
1040    #define thread_get_tid() gettid()
1041    
1042    static
1043    int thread_set_affinity(pid_t tid, int i)
1044    {
1045      cpu_set_t m;
1046      CPU_ZERO(&m);
1047      CPU_SET(i, &m);
1048      return sched_setaffinity(tid, sizeof(m), &m);
1049    }
1050    
1051    #else
1052    
1053    /* POSIX では、スレッド単位のスケジューリングに介入できない。 */
1054    
1055    #endif
1056    
1057    #else
1058    #error "configuration not supported"
1059    #endif
1060    
1061    struct THREAD_PARAM
1062    {
1063      /* 以下は共通情報のコピー */
1064      CODE_T *code;
1065      THREAD_EV_T event_ks_activated;
1066      ATOMWORD_T volatile *p_nidle;         /* 待ちに入ったら増加 */
1067    
1068      /* 以下はスレッド固有 */
1069    #ifdef thread_set_priority
1070      THREAD_TH_T th;
1071      int pri;
1072    #endif
1073    };
1074    
1075    static
1076    volatile ATOMWORD_T wp_crypt, rp_crypt;
1077    static
1078    struct PACKET_CRYPT64 *volatile q_crypt[NQ_CRYPT];
1079    
1080    static
1081    volatile ATOMWORD_T wp_cmp, rp_cmp;
1082    static
1083    struct PACKET_CRYPT64 *volatile q_cmp[NQ_CMP];
1084    
1085    static
1086    uint64_t
1087    thread_avail(void)
1088    {
1089    #if !USE_MT
1090    
1091      return 0x1U;
1092    
1093    #elif defined(WIN32)    /* Win32 API */
1094      DWORD_PTR mask, mask_s;
1095      if (!GetProcessAffinityMask(GetCurrentProcess(),
1096                                                              &mask,
1097                                                              &mask_s)
1098              || !mask
1099              || !mask_s)
1100            return 0x1U;
1101    #if DEBUG>=1
1102      fprintf(stderr,
1103                      "m=%08X s=%08X\n",
1104                     (unsigned)mask,
1105                     (unsigned)mask_s);
1106    #endif
1107      if (popcnt64(mask_s) == 1)
1108            /* 何も言うまい */;
1109      else if (mask == mask_s)
1110            fprintf(stderr,
1111                            "通常の%d倍とはよく言ったものです。\n",
1112                            popcnt64(mask));
1113      else
1114            fprintf(stderr,
1115                            "最高速力の%g倍の力でてきとうにがんばるよ。\n",
1116                            (double)popcnt64(mask) / popcnt64(mask_s));
1117      return mask;
1118    
1119    #elif defined(__linux__)        /* sched.h 拡張 */
1120    
1121      int i;
1122      uint64_t m = 0;
1123      cpu_set_t am;
1124      if (sched_getaffinity(getpid(), sizeof(am), &am) < 0)
1125            return 0x1U;
1126    
1127      for (i = 0; i < 64 && i < CPU_SETSIZE; i++)
1128            if (CPU_ISSET(i, &am))
1129              m |= 1ULL << i;
1130    
1131      return m;
1132    
1133    #elif defined( FREEBSD )
1134    
1135    #include <sys/sysctl.h>
1136    
1137      int   i;
1138      uint64_t m;
1139      int nCPU;
1140      int mib[2];
1141      size_t len;
1142    
1143      mib[0] = CTL_HW;
1144      mib[1] = HW_NCPU;
1145      len = sizeof( nCPU );
1146      sysctl( mib, 2, &nCPU, &len, NULL, 0 );
1147      m = (1ULL << nCPU) - 1;
1148    
1149      return m;
1150    
1151    #elif defined( SOLARIS )
1152    
1153    #include <sys/unistd.h>
1154    #include <sys/processor.h>
1155    
1156      uint64_t m;
1157      processorid_t i, cpuid_max;
1158    
1159      m = 0;
1160      cpuid_max = sysconf( _SC_CPUID_MAX );
1161      for ( i = 0; i <= cpuid_max; i++ ) {
1162       if ( p_online( i, P_STATUS ) == P_ONLINE ) {
1163        m |= 1ULL << i;
1164       }
1165      }
1166    
1167      return m;
1168    
1169    #else
1170    
1171      /* XXX プロセッサ数を調べ上げてください */
1172      return 0x01U;
1173    
1174    #endif
1175    }
1176    
1177    static
1178    NORETURN
1179    thread_crypt64(void *a_param)
1180    {
1181      struct THREAD_PARAM *param = a_param;
1182      CODE_T *code = param->code;
1183      struct PACKET_CRYPT64 *pkt;
1184    #ifdef thread_set_priority
1185      THREAD_TH_T th = thread_get_tid();
1186      thread_set_priority(th, param->pri);
1187    #endif
1188    
1189      for(;;)
1190            {
1191              ATOMWORD_T rp;
1192              ATOMWORD_T wp;
1193    
1194              /* キューから要求を取り出す */
1195              for (;;)
1196                    {
1197                      while ((rp = rp_crypt,
1198                                      WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT)
1199                                      /*|| q_crypt[WRAP(rp, NQ_CRYPT)] == NULL*/))
1200                            {
1201                              THREAD_TIMEOUT_T tmo = (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT)
1202                                                                              ? THREAD_INFINITE
1203                                                                              : 1);
1204                              int r;
1205    
1206                              /* 寝た; auto reset */
1207                              if (tmo == THREAD_INFINITE)
1208                                    {
1209                                      LOCK_INC(param->p_nidle);
1210                                    }
1211    
1212                              /* 要求待ち */
1213                              r = thread_wait_event(param->event_ks_activated, tmo);
1214    
1215                              if (tmo == THREAD_INFINITE)
1216                                    {
1217                                      /* 起こされた */
1218                                      LOCK_DEC(param->p_nidle);
1219                                    }
1220                              else if (r >= 0)
1221                                    {
1222                                      /* もうちょっと寝てみる */
1223                                      thread_sleep(tmo);
1224                                    }
1225    
1226                              /* 自らの優先度を戻す
1227                                     (外からブーストされてるかも) */
1228    #ifdef thread_set_priority
1229                              if (r >= 0)
1230                                    thread_set_priority(th, param->pri);
1231    #endif
1232                            }
1233    
1234                      if (LOCK_CAS(&rp_crypt, rp + 1, rp) != rp)
1235                            continue;
1236                      rp = WRAP(rp, NQ_CRYPT);
1237                      break;
1238                    }
1239    
1240              pkt = q_crypt[rp];
1241              assert(pkt != NULL);
1242              pkt = LOCK_CASP(&q_crypt[rp], NULL, pkt);
1243              assert(pkt != NULL);
1244    
1245              /* 実行してみる */
1246              CALL_CRYPT64(code, &pkt->key64, &pkt->param64);
1247    
1248              /* 結果をキューにたたき込む */
1249              for (;;)
1250                    {
1251                      while ((wp = wp_cmp,
1252                                      WRAP(rp_cmp - 1, NQ_CMP) == WRAP(wp, NQ_CMP))
1253                                     || q_cmp[WRAP(wp, NQ_CMP)] != NULL)
1254                            {
1255    #if DEBUG>=1
1256                              fprintf(stderr,
1257                                              "q_cmp stalled(%d,%d) %p\n",
1258                                              (unsigned)WRAP(wp, NQ_CMP),
1259                                              (unsigned)WRAP(rp_cmp - 1, NQ_CMP),
1260                                              q_cmp[WRAP(wp, NQ_CMP)]);
1261    #endif
1262                              thread_sleep(1);
1263                            }
1264    
1265                      if (LOCK_CAS(&wp_cmp, wp + 1, wp) != wp)
1266                            continue;
1267                      wp = WRAP(wp, NQ_CMP);
1268                      break;
1269                    }
1270    
1271              pkt = LOCK_CASP(&q_cmp[wp], pkt, NULL);
1272              assert(pkt == NULL);
1273            }
1274    }
1275    
1276    /***************************************************************
1277     *
1278     *      メインループとか
1279     *
1280     */
1281    
1282  int  int
1283  main(int argc, char *argv[])  main(int argc, char *argv[])
# Line 795  main(int argc, char *argv[]) Line 1286  main(int argc, char *argv[])
1286    int mincnt;    int mincnt;
1287    int nblk_hit, nblk_total;    int nblk_hit, nblk_total;
1288    int nap_hit, nap_total;    int nap_hit, nap_total;
1289    signed char *code = NULL;    CODE_T *code = NULL;
1290      off_t code_cmp;
1291    FILE *ofp;    FILE *ofp;
1292    FILE *sfp;    /* scoreboard */    FILE *sfp;    /* scoreboard */
1293    struct ITREE *root_expr;    struct ITREE *root_expr;
1294      uint64_t proc_mask;
1295      int ks_activated;
1296      THREAD_EV_T event_ks_activated;
1297      static ATOMWORD_T volatile nidle;
1298      struct THREAD_PARAM *threads = NULL;
1299      int nthreads;
1300      int npkts;
1301      struct PACKET_CRYPT64 *pkts, *pkt_hit;
1302      uint64_t pkts_vacant;
1303      int tn;
1304    int cr;    int cr;
1305  #ifdef KEYCHECK  #ifdef KEYCHECK
1306    unsigned int  ok, ng;    unsigned int  ok, ng;
1307  #endif  #endif
1308    
1309      /* 鍵文字列 */
1310      uint8_t key[8 + 8];
1311    
1312    int xhash_loaded;    int xhash_loaded;
1313    
1314  #define LOOP_FACTOR 128000      /* こんなもんでいいか */  #define LOOP_FACTOR 128000      /* こんなもんでいいか */
# Line 840  main(int argc, char *argv[]) Line 1345  main(int argc, char *argv[])
1345    
1346    assert((1 << N_STRIDE) == N_ALU * ALU_BITS);    assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
1347    
   /* t[16] は、内部演算で使用する、all 1 が入っている */  
   for (i = 0; i < N_ALU; i++)  
         param64.t[T_INV].a[i] = -1;  
   
   /* 固定キーの生成 */  
   key_init_sk(&key64);  
   
   /* キースケジュールをここに押し込めておく  
          従来は crypt64.S 内で完結するように引いていた */  
   for (i = 0; i < 28; i++)  
         key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];  
   
1348    /* タゲ読み込み */    /* タゲ読み込み */
1349    root_expr = expr_parse("target.txt");    root_expr = expr_parse("target.txt");
1350    
1351    /* コードを生成・展開 */    /* コードを生成・展開
1352             起動予定スレッド数に応じて
1353             生成するコードを変える */
1354    sfp = scoreboard_open();    sfp = scoreboard_open();
1355    fwrite(crypt64_sta, 1, crypt64_end - crypt64_sta, sfp);       /* prologue */    fwrite(crypt64_pro, 1, crypt64_cmp_pro - crypt64_pro, sfp);   /* prologue & コアループ */
1356    synth_synthesize(sfp, root_expr);    proc_mask = thread_avail();
1357    fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp);      /* epilogue */    if (proc_mask == 1U)
1358            {
1359              /* single */
1360              npkts = 1;
1361              pkts_vacant = 1;
1362              code_cmp = 0;
1363            }
1364      else
1365            {
1366              /* multi */
1367              fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp);      /* epilogue */
1368    
1369              /* 比較器のみを生成(前半) */
1370              code_cmp = ftell(sfp);
1371              fseek(sfp, (-code_cmp) & 63, SEEK_CUR);
1372              code_cmp = ftell(sfp);
1373              fwrite(crypt64_pro, 1, crypt64_crypt - crypt64_pro, sfp);     /* prologue */
1374              npkts = 64;
1375              pkts_vacant = (uint64_t)-1;   /* (1 << 64) - 1 を計算したくない */
1376            }
1377    
1378      /* 比較部を生成 */
1379      fwrite(crypt64_cmp_pro, 1, crypt64_cmp_ep - crypt64_cmp_pro, sfp);    /* 比較器準備 */
1380      tn = synth_synthesize(sfp, root_expr);
1381      fwrite(crypt64_cmp_ep, 1, crypt64_ep_end - crypt64_cmp_ep, sfp);      /* epilogue */
1382    
1383    /* コードをメモリに貼り付ける */    /* コードをメモリに貼り付ける */
1384    code = scoreboard_map(sfp);    code = scoreboard_map(sfp);
1385    
1386    /* キーの初期化 */    /* キーの初期化 */
1387    srand(time(NULL));    srand(time(NULL));
1388    key_init();    key_init(key);
1389    set_salt(code, key);    set_salt(code, key);
   for (i = 0; i < 8; i++)  
         key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);  
1390    
1391  #if DEBUG>=1    /* 演算パケットを作成 */
1392    printf("key=%p param=%p\n", &key64, &param64);    pkts = packet_create(npkts, tn, key);
1393      pkt_hit = &pkts[npkts - 1];
1394    
1395      /* 働くおじさんを量産 */
1396      thread_create_event(event_ks_activated, 1);
1397      ks_activated = 1;
1398      nthreads = 0;
1399      if (code_cmp)
1400            {
1401              THREAD_TH_T h;
1402              int ots = -1;
1403              threads = calloc(2 * popcnt64(proc_mask), sizeof(*threads));
1404              for (i = 0; proc_mask; i++, proc_mask >>= 1)
1405                    if (proc_mask & 1)
1406                      {
1407                            if (ots < 0)
1408                              {
1409                                    /* 自分自身のスケジューリング
1410                                       こーゆー系のアプリは低めに設定するのが吉(かも) */
1411    #ifdef WIN32
1412                                    h = GetCurrentProcess();
1413                                    SetPriorityClass(h, BELOW_NORMAL_PRIORITY_CLASS);
1414    #endif
1415    #if defined(thread_set_priority)
1416                                    /* 心の隙間お埋めします */
1417                                    threads[nthreads].code = code;
1418                                    threads[nthreads].event_ks_activated = event_ks_activated;
1419                                    threads[nthreads].p_nidle = &nidle;
1420                                    threads[nthreads].pri = THREAD_PRIORITY_IDLE;
1421                                    thread_create(h, thread_crypt64, &threads[nthreads]);
1422                                    threads[nthreads].th = h;
1423                                    nthreads++;
1424    #endif
1425                                    if (!code_cmp)
1426                                      break;
1427    
1428                                    /* 自分自身の残りの設定を、あとでやる */
1429                                    ots = i;
1430                              }
1431                            else
1432                              {
1433                                    /* 他スレッドは、やや低めの優先度で。 */
1434                                    threads[nthreads].code = code;
1435                                    threads[nthreads].event_ks_activated = event_ks_activated;
1436                                    threads[nthreads].p_nidle = &nidle;
1437    #ifdef thread_set_priority
1438                                    threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL;
1439    #endif
1440                                    thread_create(h, thread_crypt64, &threads[nthreads]);
1441    #ifdef thread_set_priority
1442                                    threads[nthreads].th = h;
1443  #endif  #endif
1444    assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));  #ifdef thread_get_tid
1445    assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));                                  thread_set_affinity(h, i);
1446    #endif
1447                                    nthreads++;
1448                              }
1449                      }
1450    #ifdef thread_get_tid
1451              if (ots)
1452                    thread_set_affinity(thread_get_tid(), ots);
1453    #endif
1454            }
1455    
1456    if ((ofp = fopen("log.txt", "at")) == NULL)    if ((ofp = fopen("log.txt", "at")) == NULL)
1457          {          {
# Line 897  main(int argc, char *argv[]) Line 1473  main(int argc, char *argv[])
1473    /* 探索ループだぞっと */    /* 探索ループだぞっと */
1474    for (;;)    for (;;)
1475          {          {
1476              struct PACKET_CRYPT64 *pkt_c;
1477            uint64_t cnt;            uint64_t cnt;
1478            int cnt1, cnt2;            int cnt1, cnt2;
1479            int k, kk;            int k, kk;
1480    
1481            /* 鍵のセット */            /* 比較器候補(may be NULL)
1482            for (i = 0; i < 8; i++)                   先にキューから取り出す */
1483              pkt_c = q_cmp[WRAP(rp_cmp, NQ_CMP)];
1484              if (pkt_c != NULL)
1485                    {
1486                      pkt_c = LOCK_CASP(&q_cmp[WRAP(rp_cmp, NQ_CMP)], NULL, pkt_c);
1487                      assert(pkt_c != NULL);
1488                      LOCK_INC(&rp_cmp);
1489    
1490                      /* パケットを vacant に回しておく */
1491                      pkts_vacant |= 1ULL << (pkt_c - pkts);
1492                    }
1493    
1494              /* Saltチェンジ待ち */
1495              if (!ks_activated)
1496                    {
1497                      int tmo = (pkt_c != NULL
1498                                             ? 0                    /* poll */
1499                                             : 1);
1500                      thread_sleep(tmo);
1501                      if (nidle == nthreads)
1502                            {
1503                              assert(WRAP(rp_crypt, NQ_CRYPT) == WRAP(wp_crypt, NQ_CRYPT));
1504                              /* Salt チェンジが可能 */
1505                              set_salt(code, key);
1506                              if (code_cmp)
1507                                    thread_signal_event(event_ks_activated);
1508                              ks_activated = 1;
1509                            }
1510                    }
1511    
1512              /* 鍵をキューにたたき込みまくる */
1513              if (!ks_activated)
1514                  {                  {
1515                    key_set64(&key64, i, key[i], key[i] ^ okey[i], 0);                    /* 鍵を登録しない */
1516                    okey[i] = key[i];                    ;
1517                    }
1518              else for (i = npkts - 1; i >= 0; i--)
1519                    if (pkts_vacant & (1ULL << i))
1520                      {
1521                            int j;
1522    
1523                            if (i == npkts - 1)
1524                              {
1525                                    /* 前段で、働くおじさんから
1526                                       結果をもらっていたら、何もしない */
1527                                    if (pkt_c != NULL)
1528                                      continue;
1529                              }
1530                            else
1531                              {
1532                                    /* 前段で取り出したばかりの
1533                                       働くおじさんは、尊重する */
1534                                    if (&pkts[i] == pkt_c)
1535                                      continue;
1536    
1537                                    /* queue full の場合は見送る */
1538                                    if (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp_crypt - 1, NQ_CRYPT)
1539                                            || q_crypt[WRAP(wp_crypt, NQ_CRYPT)] != NULL)
1540                                      break;
1541                              }
1542    
1543                            /* 鍵のセット */
1544                            for (j = 0; j < 8; j++)
1545                              {
1546                                    key_set64(&pkts[i].key64, j, key[j], key[j] ^ pkts[i].uk.key[j], 0);
1547                                    pkts[i].uk.key[j] = key[j];
1548                              }
1549    
1550                            if (i == npkts - 1)
1551                              {
1552                                    /* 次段で CRYPT64->CMP */
1553                                    assert(pkt_c == NULL);
1554                                    pkt_c = &pkts[i];
1555                                    assert(pkt_c == pkt_hit);
1556                              }
1557                            else
1558                              {
1559                                    /* キューにたたき込む */
1560                                    while (LOCK_CASP(&q_crypt[WRAP(wp_crypt, NQ_CRYPT)], &pkts[i], NULL) != NULL)
1561                                      {
1562                                            /* 設計上はここに来ない */
1563    #if DEBUG>=1
1564                                            fprintf(stderr,
1565                                                            "[XXX] q_crypt を汚してるのは誰だ? (rp=%3d, wp=%3d, v=%08X%08X)\n",
1566                                                            (unsigned)WRAP(rp_crypt, NQ_CRYPT),
1567                                                            (unsigned)WRAP(wp_crypt, NQ_CRYPT),
1568                                                            (unsigned)(pkts_vacant >> 32),
1569                                                            (unsigned)pkts_vacant);
1570                                            thread_sleep(1000);
1571    #endif
1572                                            thread_sleep(1);
1573                                      }
1574                                    LOCK_INC(&wp_crypt);
1575                                    pkts_vacant ^= 1ULL << i;
1576                                    assert(!(pkts_vacant & (1ULL << i)));   /* 削れ */
1577                              }
1578    
1579                            /* 鍵増加はこんなところに移動! */
1580                            assert(ks_activated);
1581                            if (!key_inc(key, 6) && !key_inc(key, KEY_SHUFFLE_POS))
1582                              {
1583                                    /* 鍵のシャッフル
1584                                       q_crypt が捌けるまで、set_salt() はできない */
1585    #if DEBUG>=1
1586                                    fprintf(stderr, "********************************SHUFFLE!\n");
1587    #endif
1588                                    thread_clear_event(event_ks_activated);
1589                                    key_reset(key, 0);
1590    
1591                                    /* キューの鍵が捌けるまでアイドル状態に */
1592                                    ks_activated = 0;
1593    
1594                                    /* スレッドをブーストして回る */
1595    #ifdef thread_set_priority
1596                                    for (j = 0; j < nthreads; j++)
1597                                      {
1598                                            assert(threads != NULL);
1599                                            thread_set_priority(threads[j].th, THREAD_PRIORITY_NORMAL);
1600                                      }
1601    #endif
1602    
1603                                    /* ループ続行はもはや不要 */
1604                                    break;
1605                              }
1606                      }
1607    
1608              /* することがなくなっている場合 */
1609              if (pkt_c == NULL)
1610                    {
1611                      assert(!ks_activated);
1612                      continue;
1613                  }                  }
1614    
1615            /* 呼ぶ!            /* 呼ぶ!
1616                   LR 初期化は、サブモジュール内で行うべし                   LR 初期化は、サブモジュール内で行うべし
1617                   FASTCALL に準じた呼び出しのため、                   FASTCALL に準じた呼び出しのため、
1618                   ホントはいろいろレジスタが破壊されるハズ…なんだが。 */                   ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
1619            cnt = CALL_CRYPT64(code, key64.k, param64.lr);            if (pkt_c != pkt_hit)
1620                    {
1621                      cnt = CALL_CMP64(code + code_cmp,
1622                                                       pkt_hit->param64.hit,
1623                                                       pkt_c->param64.lr);
1624                    }
1625              else
1626                    {
1627                      /* ようやく自スレッドで回せる */
1628                      cnt = CALL_CRYPT64(code,
1629                                                             &pkt_c->key64,
1630                                                             &pkt_c->param64);
1631                      if (code_cmp)
1632                            cnt = CALL_CMP64(code + code_cmp,
1633                                                             pkt_c->param64.hit,
1634                                                             pkt_c->param64.lr);
1635                    }
1636    
1637  #if DEBUG>=1  #if DEBUG>=1
1638            cnt2 = (int32_t)(cnt >> 32);            cnt2 = (int32_t)(cnt >> 32);
# Line 927  main(int argc, char *argv[]) Line 1647  main(int argc, char *argv[])
1647                  }                  }
1648  #endif  #endif
1649    
1650            /* ヒットしたときの処理 */            /* ヒットしたときの処理
1651                     key および lr は pkt_c に
1652                     合致判定は pkt_hit に入っているハズ */
1653            xhash_loaded = 0;            xhash_loaded = 0;
1654            for (kk = 0; kk < N_ALU; kk++)            for (kk = 0; kk < N_ALU; kk++)
1655                  {                  {
# Line 935  main(int argc, char *argv[]) Line 1657  main(int argc, char *argv[])
1657                    if (!(kk & (N_ALU / N_Q - 1)))                    if (!(kk & (N_ALU / N_Q - 1)))
1658                          nblk_total++, xhash_loaded = 0;                          nblk_total++, xhash_loaded = 0;
1659    
1660                    t = param64.t[HIT_ANY].a[kk];                    t = pkt_hit->param64.hit[HIT_ANY].a[kk];
1661  #ifndef KEYCHECK  #ifndef KEYCHECK
1662                    if (!t)                    if (!t)
1663                          continue;                          continue;
# Line 947  main(int argc, char *argv[]) Line 1669  main(int argc, char *argv[])
1669                          {                          {
1670                            static uint64_t xhash[64];                            static uint64_t xhash[64];
1671                            char hash[16];                            char hash[16];
1672                            unsigned char buf[32];                            uint8_t buf[32];
1673                            time_t tloc;                            time_t tloc;
1674    
1675  #ifndef KEYCHECK  #ifndef KEYCHECK
# Line 961  main(int argc, char *argv[]) Line 1683  main(int argc, char *argv[])
1683                            if (!xhash_loaded)                            if (!xhash_loaded)
1684                                  {                                  {
1685                                    nblk_hit++;                                    nblk_hit++;
1686                                    CALL_TR64(&param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash);                                    CALL_TR64(&pkt_c->param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash);
1687                                    xhash_loaded = 1;                                    xhash_loaded = 1;
1688                                  }                                  }
1689    
1690  #ifndef KEYCHECK  #ifndef KEYCHECK
1691                            /* 辞書を調べる */                            /* 辞書を調べる */
1692                            if (!((param64.t[HIT_BOOL].a[kk] & ((ALU_T)1 << k))                            if (!((pkt_hit->param64.hit[HIT_BOOL].a[kk] & ((ALU_T)1 << k))
1693                                          || wdict_ishit(param64.t,                                          || wdict_ishit(pkt_hit->param64.hit,
1694                                                                     kk, k,                                                                     kk, k,
1695                                                                     xhash[(ALU_BITS * kk + k) & 0x3F])))                                                                     xhash[(ALU_BITS * kk + k) & 0x3F])))
1696                                  continue;                                  continue;
# Line 982  main(int argc, char *argv[]) Line 1704  main(int argc, char *argv[])
1704                                  }                                  }
1705                            hash[10] = 0;                            hash[10] = 0;
1706    
1707                            memcpy(buf, key, 32);                            memcpy(buf, pkt_c->uk.key, 8);
1708                            buf[8] = buf[9] = 0;                            buf[8] = buf[9] = 0;
1709                            buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;                            buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
1710                            time( &tloc );                            time( &tloc );
# Line 998  if ( ok + ng >= 100000000 ) { Line 1720  if ( ok + ng >= 100000000 ) {
1720                                    if (cr)                                    if (cr)
1721                                          fprintf(stderr, "\n");                                          fprintf(stderr, "\n");
1722                                    cr = 0;                                    cr = 0;
1723    #if DEBUG>=1
1724                                      fprintf(stderr, "%3d:", pkt_c - pkts);
1725    #endif
1726  /* 魔改造 ヒットした日時を表示 */  /* 魔改造 ヒットした日時を表示 */
1727                                    log_printf(ofp,                                    log_printf(ofp,
1728                                                           "◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X) %s",                                                           "◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X) %s",
# Line 1020  if ( ok + ng >= 100000000 ) { Line 1745  if ( ok + ng >= 100000000 ) {
1745                                    if (cr)                                    if (cr)
1746                                          fprintf(stderr, "\n");                                          fprintf(stderr, "\n");
1747                                    cr = 0;                                    cr = 0;
1748    #if DEBUG>=1
1749                                      fprintf(stderr, "%3d:", pkt_c - pkts);
1750    #endif
1751                                    log_printf(ofp,                                    log_printf(ofp,
1752                                                           "◆%s            (%02X %02X %02X %02X %02X %02X %02X %02X   ) %s",                                                           "◆%s            (%02X %02X %02X %02X %02X %02X %02X %02X   ) %s",
1753                                                           hash,                                                           hash,
1754                                                           buf[0], buf[1], buf[2], buf[3],                                                           buf[0], buf[1], buf[2], buf[3],
1755                                                           buf[4], buf[5], buf[6], buf[7], ctime(&tloc) );                                                           buf[4], buf[5], buf[6], buf[7], ctime(&tloc) );
1756                                  }                                  }
1757    #ifdef KEYCHECK
1758  printf( "ok = %lu, ng = %lu\n", ok, ng );  printf( "ok = %lu, ng = %lu\n", ok, ng );
1759    #endif
1760                          }                          }
1761                  }                  }
1762    
# Line 1106  printf( "ok = %lu, ng = %lu\n", ok, ng ) Line 1836  printf( "ok = %lu, ng = %lu\n", ok, ng )
1836  /* 魔改造 速度表示は残さない */  /* 魔改造 速度表示は残さない */
1837                    cr = 0;                    cr = 0;
1838                  }                  }
 #if 1  
           if (!key_inc(3))  
                 {  
 #if DEBUG>=2  
                   printf("********************************\n");  
 #endif  
                   key_reset(0);  
                   set_salt(code, key);  
                   for (i = 0; i < 8; i++)  
                         key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);  
                 }  
 #endif  
1839          }          }
1840    
1841    return 0;    return 0;

Legend:
Removed from v.146  
changed lines
  Added in v.148

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26