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