Actual source code: petscfptimpl.h


  2: #ifndef PETSCFPIMPL_H
  3: #define PETSCFPIMPL_H
  4: #include <petscviewertypes.h>
  5: #include <petscsys.h>
  6: /*
  7:     Function pointer table that maps from function pointers to their string representation

  9:     Does not use the PetscFunctionBegin/Return() or PetscCall() because these routines are called within those macros
 10: */
 11: #define PetscCallQ(A) \
 12:   do { \
 13:     PetscErrorCode ierr = A; \
 14:     if (ierr) return (ierr); \
 15:   } while (0);

 17: typedef struct _n_PetscFPT *PetscFPT;
 18: struct _n_PetscFPT {
 19:   void   **functionpointer;
 20:   char   **functionname;
 21:   PetscInt count;
 22:   PetscInt tablesize;
 23: };
 24: PETSC_INTERN PetscFPT PetscFPTData;

 26: static inline PetscErrorCode PetscFPTView(PetscViewer viewer)
 27: {
 28:   if (PetscFPTData) {
 29:     for (PetscInt i = 0; i < PetscFPTData->tablesize; ++i) {
 30:       if (PetscFPTData->functionpointer[i]) printf("%s()\n", PetscFPTData->functionname[i]);
 31:     }
 32:   }
 33:   return PETSC_SUCCESS;
 34: }

 36: static inline PetscErrorCode PetscFPTDestroy(void)
 37: {
 38:   PetscFPT data = PetscFPTData;

 40:   PetscFPTData = NULL;
 41:   if (!data) return PETSC_SUCCESS;
 42:   PetscCallQ(PetscFree(data->functionpointer));
 43:   PetscCallQ(PetscFree(data->functionname));
 44:   PetscCallQ(PetscFree(data));
 45:   return PETSC_SUCCESS;
 46: }

 48: /*
 49:    PetscFPTCreate  Creates a PETSc look up table from function pointers to strings

 51:    Input Parameter:
 52: .     n - expected number of keys

 54: */
 55: static inline PetscErrorCode PetscFPTCreate(PetscInt n)
 56: {
 57:   PetscFPT _PetscFPTData;

 59:   PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n < 0");
 60:   /* Cannot use PetscNew() here because it is not yet defined in the include file chain */
 61:   PetscCallQ(PetscMalloc(sizeof(struct _n_PetscFPT), &_PetscFPTData));
 62:   _PetscFPTData->tablesize = (3 * n) / 2 + 17;
 63:   if (_PetscFPTData->tablesize < n) _PetscFPTData->tablesize = PETSC_MAX_INT / 4; /* overflow */
 64:   PetscCallQ(PetscCalloc(sizeof(void *) * _PetscFPTData->tablesize, &_PetscFPTData->functionpointer));
 65:   PetscCallQ(PetscMalloc(sizeof(char **) * _PetscFPTData->tablesize, &_PetscFPTData->functionname));
 66:   _PetscFPTData->count = 0;
 67:   PetscFPTData         = _PetscFPTData;
 68:   return PETSC_SUCCESS;
 69: }

 71: static inline unsigned long PetscFPTHashPointer(void *ptr)
 72: {
 73: #define PETSC_FPT_HASH_FACT 79943
 74:   return ((PETSC_FPT_HASH_FACT * ((size_t)ptr)) % PetscFPTData->tablesize);
 75: }

 77: static inline PetscErrorCode PetscFPTAdd(void *key, const char *data)
 78: {
 79:   PetscCheck(data, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Null function name");
 80:   if (!PetscFPTData) return PETSC_SUCCESS;
 81:   for (PetscInt i = 0, hash = (PetscInt)PetscFPTHashPointer(key); i < PetscFPTData->tablesize; ++i) {
 82:     if (PetscFPTData->functionpointer[hash] == key) {
 83:       PetscFPTData->functionname[hash] = (char *)data;
 84:       return PETSC_SUCCESS;
 85:     } else if (!PetscFPTData->functionpointer[hash]) {
 86:       PetscFPTData->count++;
 87:       PetscFPTData->functionpointer[hash] = key;
 88:       PetscFPTData->functionname[hash]    = (char *)data;
 89:       return PETSC_SUCCESS;
 90:     }
 91:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
 92:   }
 93:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Function pointer table is full");
 94: }

 96: /*
 97:     PetscFPTFind - checks if a function pointer is in the table

 99:     If data==0, then no entry exists

101: */
102: static inline PetscErrorCode PetscFPTFind(void *key, char const **data)
103: {
104:   PetscInt hash, ii = 0;

106:   *data = NULL;
107:   if (!PetscFPTData) return PETSC_SUCCESS;
108:   hash = PetscFPTHashPointer(key);
109:   while (ii++ < PetscFPTData->tablesize) {
110:     if (!PetscFPTData->functionpointer[hash]) break;
111:     else if (PetscFPTData->functionpointer[hash] == key) {
112:       *data = PetscFPTData->functionname[hash];
113:       break;
114:     }
115:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
116:   }
117:   return PETSC_SUCCESS;
118: }

120: #endif