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
10: */
11: #define PetscCallQ(A) \
12: do { \
13: PetscErrorCode 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 0;
34: }
36: static inline PetscErrorCode PetscFPTDestroy(void)
37: {
38: PetscFPT data = PetscFPTData;
40: PetscFPTData = NULL;
41: if (!data) return 0;
42: PetscFree(data->functionpointer);
43: PetscFree(data->functionname);
44: PetscFree(data);
45: return 0;
46: }
48: /*
49: PetscFPTCreate Creates a PETSc look up table from function pointers to strings
51: Input Parameters:
52: . n - expected number of keys
54: */
55: static inline PetscErrorCode PetscFPTCreate(PetscInt n)
56: {
57: PetscFPT _PetscFPTData;
60: /* Cannot use PetscNew() here because it is not yet defined in the include file chain */
61: 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: PetscCalloc(sizeof(void *) * _PetscFPTData->tablesize, &_PetscFPTData->functionpointer);
65: PetscMalloc(sizeof(char **) * _PetscFPTData->tablesize, &_PetscFPTData->functionname);
66: _PetscFPTData->count = 0;
67: PetscFPTData = _PetscFPTData;
68: return (0);
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: {
80: if (!PetscFPTData) return 0;
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 0;
85: } else if (!PetscFPTData->functionpointer[hash]) {
86: PetscFPTData->count++;
87: PetscFPTData->functionpointer[hash] = key;
88: PetscFPTData->functionname[hash] = (char *)data;
89: return 0;
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 (0);
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 0;
118: }
120: #endif