| OLD | NEW |
| 1 /* ***** BEGIN LICENSE BLOCK ***** | 1 /* ***** BEGIN LICENSE BLOCK ***** |
| 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 3 * | 3 * |
| 4 * The contents of this file are subject to the Mozilla Public License Version | 4 * The contents of this file are subject to the Mozilla Public License Version |
| 5 * 1.1 (the "License"); you may not use this file except in compliance with | 5 * 1.1 (the "License"); you may not use this file except in compliance with |
| 6 * the License. You may obtain a copy of the License at | 6 * the License. You may obtain a copy of the License at |
| 7 * http://www.mozilla.org/MPL/ | 7 * http://www.mozilla.org/MPL/ |
| 8 * | 8 * |
| 9 * Software distributed under the License is distributed on an "AS IS" basis, | 9 * Software distributed under the License is distributed on an "AS IS" basis, |
| 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 * under the terms of either the GPL or the LGPL, and not to allow others to | 28 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 29 * use your version of this file under the terms of the MPL, indicate your | 29 * use your version of this file under the terms of the MPL, indicate your |
| 30 * decision by deleting the provisions above and replace them with the notice | 30 * decision by deleting the provisions above and replace them with the notice |
| 31 * and other provisions required by the GPL or the LGPL. If you do not delete | 31 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 32 * the provisions above, a recipient may use your version of this file under | 32 * the provisions above, a recipient may use your version of this file under |
| 33 * the terms of any one of the MPL, the GPL or the LGPL. | 33 * the terms of any one of the MPL, the GPL or the LGPL. |
| 34 * | 34 * |
| 35 * ***** END LICENSE BLOCK ***** */ | 35 * ***** END LICENSE BLOCK ***** */ |
| 36 | 36 |
| 37 #ifdef DEBUG | 37 #ifdef DEBUG |
| 38 static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.12 $ $Date
: 2008/05/13 01:22:35 $"; | 38 static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.13 $ $Date
: 2010/03/15 08:29:31 $"; |
| 39 #endif /* DEBUG */ | 39 #endif /* DEBUG */ |
| 40 | 40 |
| 41 /* | 41 /* |
| 42 * arena.c | 42 * arena.c |
| 43 * | 43 * |
| 44 * This contains the implementation of NSS's thread-safe arenas. | 44 * This contains the implementation of NSS's thread-safe arenas. |
| 45 */ | 45 */ |
| 46 | 46 |
| 47 #ifndef BASE_H | 47 #ifndef BASE_H |
| 48 #include "base.h" | 48 #include "base.h" |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 * A pointer to the replacement segment of memory | 1019 * A pointer to the replacement segment of memory |
| 1020 */ | 1020 */ |
| 1021 | 1021 |
| 1022 NSS_EXTERN void * | 1022 NSS_EXTERN void * |
| 1023 nss_ZRealloc | 1023 nss_ZRealloc |
| 1024 ( | 1024 ( |
| 1025 void *pointer, | 1025 void *pointer, |
| 1026 PRUint32 newSize | 1026 PRUint32 newSize |
| 1027 ) | 1027 ) |
| 1028 { | 1028 { |
| 1029 NSSArena *arena; |
| 1029 struct pointer_header *h, *new_h; | 1030 struct pointer_header *h, *new_h; |
| 1030 PRUint32 my_newSize = newSize + sizeof(struct pointer_header); | 1031 PRUint32 my_newSize = newSize + sizeof(struct pointer_header); |
| 1031 void *rv; | 1032 void *rv; |
| 1032 | 1033 |
| 1033 if( my_newSize < sizeof(struct pointer_header) ) { | 1034 if( my_newSize < sizeof(struct pointer_header) ) { |
| 1034 /* Wrapped */ | 1035 /* Wrapped */ |
| 1035 nss_SetError(NSS_ERROR_NO_MEMORY); | 1036 nss_SetError(NSS_ERROR_NO_MEMORY); |
| 1036 return (void *)NULL; | 1037 return (void *)NULL; |
| 1037 } | 1038 } |
| 1038 | 1039 |
| 1039 if( (void *)NULL == pointer ) { | 1040 if( (void *)NULL == pointer ) { |
| 1040 nss_SetError(NSS_ERROR_INVALID_POINTER); | 1041 nss_SetError(NSS_ERROR_INVALID_POINTER); |
| 1041 return (void *)NULL; | 1042 return (void *)NULL; |
| 1042 } | 1043 } |
| 1043 | 1044 |
| 1044 h = (struct pointer_header *)((char *)pointer | 1045 h = (struct pointer_header *)((char *)pointer |
| 1045 - sizeof(struct pointer_header)); | 1046 - sizeof(struct pointer_header)); |
| 1046 | 1047 |
| 1047 /* Check any magic here */ | 1048 /* Check any magic here */ |
| 1048 | 1049 |
| 1049 if( newSize == h->size ) { | 1050 if( newSize == h->size ) { |
| 1050 /* saves thrashing */ | 1051 /* saves thrashing */ |
| 1051 return pointer; | 1052 return pointer; |
| 1052 } | 1053 } |
| 1053 | 1054 |
| 1054 if( (NSSArena *)NULL == h->arena ) { | 1055 arena = h->arena; |
| 1056 if (!arena) { |
| 1055 /* Heap */ | 1057 /* Heap */ |
| 1056 new_h = (struct pointer_header *)PR_Calloc(1, my_newSize); | 1058 new_h = (struct pointer_header *)PR_Calloc(1, my_newSize); |
| 1057 if( (struct pointer_header *)NULL == new_h ) { | 1059 if( (struct pointer_header *)NULL == new_h ) { |
| 1058 nss_SetError(NSS_ERROR_NO_MEMORY); | 1060 nss_SetError(NSS_ERROR_NO_MEMORY); |
| 1059 return (void *)NULL; | 1061 return (void *)NULL; |
| 1060 } | 1062 } |
| 1061 | 1063 |
| 1062 new_h->arena = (NSSArena *)NULL; | 1064 new_h->arena = (NSSArena *)NULL; |
| 1063 new_h->size = newSize; | 1065 new_h->size = newSize; |
| 1064 rv = (void *)((char *)new_h + sizeof(struct pointer_header)); | 1066 rv = (void *)((char *)new_h + sizeof(struct pointer_header)); |
| 1065 | 1067 |
| 1066 if( newSize > h->size ) { | 1068 if( newSize > h->size ) { |
| 1067 (void)nsslibc_memcpy(rv, pointer, h->size); | 1069 (void)nsslibc_memcpy(rv, pointer, h->size); |
| 1068 (void)nsslibc_memset(&((char *)rv)[ h->size ], | 1070 (void)nsslibc_memset(&((char *)rv)[ h->size ], |
| 1069 0, (newSize - h->size)); | 1071 0, (newSize - h->size)); |
| 1070 } else { | 1072 } else { |
| 1071 (void)nsslibc_memcpy(rv, pointer, newSize); | 1073 (void)nsslibc_memcpy(rv, pointer, newSize); |
| 1072 } | 1074 } |
| 1073 | 1075 |
| 1074 (void)nsslibc_memset(pointer, 0, h->size); | 1076 (void)nsslibc_memset(pointer, 0, h->size); |
| 1075 h->size = 0; | 1077 h->size = 0; |
| 1076 PR_Free(h); | 1078 PR_Free(h); |
| 1077 | 1079 |
| 1078 return rv; | 1080 return rv; |
| 1079 } else { | 1081 } else { |
| 1080 void *p; | 1082 void *p; |
| 1081 /* Arena */ | 1083 /* Arena */ |
| 1082 #ifdef NSSDEBUG | 1084 #ifdef NSSDEBUG |
| 1083 if( PR_SUCCESS != nssArena_verifyPointer(h->arena) ) { | 1085 if (PR_SUCCESS != nssArena_verifyPointer(arena)) { |
| 1084 return (void *)NULL; | 1086 return (void *)NULL; |
| 1085 } | 1087 } |
| 1086 #endif /* NSSDEBUG */ | 1088 #endif /* NSSDEBUG */ |
| 1087 | 1089 |
| 1088 if( (PRLock *)NULL == h->arena->lock ) { | 1090 if (!arena->lock) { |
| 1089 /* Just got destroyed.. so this pointer is invalid */ | 1091 /* Just got destroyed.. so this pointer is invalid */ |
| 1090 nss_SetError(NSS_ERROR_INVALID_POINTER); | 1092 nss_SetError(NSS_ERROR_INVALID_POINTER); |
| 1091 return (void *)NULL; | 1093 return (void *)NULL; |
| 1092 } | 1094 } |
| 1093 PR_Lock(h->arena->lock); | 1095 PR_Lock(arena->lock); |
| 1094 | 1096 |
| 1095 #ifdef ARENA_THREADMARK | 1097 #ifdef ARENA_THREADMARK |
| 1096 if( (PRThread *)NULL != h->arena->marking_thread ) { | 1098 if (arena->marking_thread) { |
| 1097 if( PR_GetCurrentThread() != h->arena->marking_thread ) { | 1099 if (PR_GetCurrentThread() != arena->marking_thread) { |
| 1098 PR_Unlock(h->arena->lock); | 1100 PR_Unlock(arena->lock); |
| 1099 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); | 1101 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); |
| 1100 return (void *)NULL; | 1102 return (void *)NULL; |
| 1101 } | 1103 } |
| 1102 } | 1104 } |
| 1103 #endif /* ARENA_THREADMARK */ | 1105 #endif /* ARENA_THREADMARK */ |
| 1104 | 1106 |
| 1105 if( newSize < h->size ) { | 1107 if( newSize < h->size ) { |
| 1106 /* | 1108 /* |
| 1107 * We have no general way of returning memory to the arena | 1109 * We have no general way of returning memory to the arena |
| 1108 * (mark/release doesn't work because things may have been | 1110 * (mark/release doesn't work because things may have been |
| 1109 * allocated after this object), so the memory is gone | 1111 * allocated after this object), so the memory is gone |
| 1110 * anyway. We might as well just return the same pointer to | 1112 * anyway. We might as well just return the same pointer to |
| 1111 * the user, saying "yeah, uh-hunh, you can only use less of | 1113 * the user, saying "yeah, uh-hunh, you can only use less of |
| 1112 * it now." We'll zero the leftover part, of course. And | 1114 * it now." We'll zero the leftover part, of course. And |
| 1113 * in fact we might as well *not* adjust h->size-- this way, | 1115 * in fact we might as well *not* adjust h->size-- this way, |
| 1114 * if the user reallocs back up to something not greater than | 1116 * if the user reallocs back up to something not greater than |
| 1115 * the original size, then voila, there's the memory! This | 1117 * the original size, then voila, there's the memory! This |
| 1116 * way a thrash big/small/big/small doesn't burn up the arena. | 1118 * way a thrash big/small/big/small doesn't burn up the arena. |
| 1117 */ | 1119 */ |
| 1118 char *extra = &((char *)pointer)[ newSize ]; | 1120 char *extra = &((char *)pointer)[ newSize ]; |
| 1119 (void)nsslibc_memset(extra, 0, (h->size - newSize)); | 1121 (void)nsslibc_memset(extra, 0, (h->size - newSize)); |
| 1120 PR_Unlock(h->arena->lock); | 1122 PR_Unlock(arena->lock); |
| 1121 return pointer; | 1123 return pointer; |
| 1122 } | 1124 } |
| 1123 | 1125 |
| 1124 PR_ARENA_ALLOCATE(p, &h->arena->pool, my_newSize); | 1126 PR_ARENA_ALLOCATE(p, &arena->pool, my_newSize); |
| 1125 if( (void *)NULL == p ) { | 1127 if( (void *)NULL == p ) { |
| 1126 PR_Unlock(h->arena->lock); | 1128 PR_Unlock(arena->lock); |
| 1127 nss_SetError(NSS_ERROR_NO_MEMORY); | 1129 nss_SetError(NSS_ERROR_NO_MEMORY); |
| 1128 return (void *)NULL; | 1130 return (void *)NULL; |
| 1129 } | 1131 } |
| 1130 | 1132 |
| 1131 new_h = (struct pointer_header *)p; | 1133 new_h = (struct pointer_header *)p; |
| 1132 new_h->arena = h->arena; | 1134 new_h->arena = arena; |
| 1133 new_h->size = newSize; | 1135 new_h->size = newSize; |
| 1134 rv = (void *)((char *)new_h + sizeof(struct pointer_header)); | 1136 rv = (void *)((char *)new_h + sizeof(struct pointer_header)); |
| 1135 if (rv != pointer) { | 1137 if (rv != pointer) { |
| 1136 (void)nsslibc_memcpy(rv, pointer, h->size); | 1138 (void)nsslibc_memcpy(rv, pointer, h->size); |
| 1137 (void)nsslibc_memset(pointer, 0, h->size); | 1139 (void)nsslibc_memset(pointer, 0, h->size); |
| 1138 } | 1140 } |
| 1139 (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size)); | 1141 (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size)); |
| 1140 h->arena = (NSSArena *)NULL; | 1142 h->arena = (NSSArena *)NULL; |
| 1141 h->size = 0; | 1143 h->size = 0; |
| 1142 PR_Unlock(new_h->arena->lock); | 1144 PR_Unlock(arena->lock); |
| 1143 return rv; | 1145 return rv; |
| 1144 } | 1146 } |
| 1145 /*NOTREACHED*/ | 1147 /*NOTREACHED*/ |
| 1146 } | 1148 } |
| 1147 | 1149 |
| 1148 PRStatus | 1150 PRStatus |
| 1149 nssArena_Shutdown(void) | 1151 nssArena_Shutdown(void) |
| 1150 { | 1152 { |
| 1151 PRStatus rv = PR_SUCCESS; | 1153 PRStatus rv = PR_SUCCESS; |
| 1152 #ifdef DEBUG | 1154 #ifdef DEBUG |
| 1153 rv = nssPointerTracker_finalize(&arena_pointer_tracker); | 1155 rv = nssPointerTracker_finalize(&arena_pointer_tracker); |
| 1154 #endif | 1156 #endif |
| 1155 return rv; | 1157 return rv; |
| 1156 } | 1158 } |
| OLD | NEW |