Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/scratch_impl.h
Show All 9 Lines | |||||
#include "scratch.h" | #include "scratch.h" | ||||
/* Using 16 bytes alignment because common architectures never have alignment | /* Using 16 bytes alignment because common architectures never have alignment | ||||
* requirements above 8 for any of the types we care about. In addition we | * requirements above 8 for any of the types we care about. In addition we | ||||
* leave some room because currently we don't care about a few bytes. | * leave some room because currently we don't care about a few bytes. | ||||
* TODO: Determine this at configure time. */ | * TODO: Determine this at configure time. */ | ||||
#define ALIGNMENT 16 | #define ALIGNMENT 16 | ||||
static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t init_size, size_t max_size) { | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { | ||||
secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); | secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); | ||||
if (ret != NULL) { | if (ret != NULL) { | ||||
ret->data = checked_malloc(error_callback, init_size); | memset(ret, 0, sizeof(*ret)); | ||||
if (ret->data == NULL) { | |||||
free (ret); | |||||
return NULL; | |||||
} | |||||
ret->offset = 0; | |||||
ret->init_size = init_size; | |||||
ret->max_size = max_size; | ret->max_size = max_size; | ||||
ret->error_callback = error_callback; | ret->error_callback = error_callback; | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { | ||||
if (scratch != NULL) { | if (scratch != NULL) { | ||||
free(scratch->data); | VERIFY_CHECK(scratch->frame == 0); | ||||
free(scratch); | free(scratch); | ||||
} | } | ||||
} | } | ||||
static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { | ||||
if (scratch->max_size <= objects * ALIGNMENT) { | size_t i = 0; | ||||
size_t allocated = 0; | |||||
for (i = 0; i < scratch->frame; i++) { | |||||
allocated += scratch->frame_size[i]; | |||||
} | |||||
if (scratch->max_size - allocated <= objects * ALIGNMENT) { | |||||
return 0; | return 0; | ||||
} | } | ||||
return scratch->max_size - objects * ALIGNMENT; | return scratch->max_size - allocated - objects * ALIGNMENT; | ||||
} | } | ||||
static int secp256k1_scratch_resize(secp256k1_scratch* scratch, size_t n, size_t objects) { | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { | ||||
VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); | |||||
if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { | |||||
n += objects * ALIGNMENT; | n += objects * ALIGNMENT; | ||||
if (n > scratch->init_size && n <= scratch->max_size) { | scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); | ||||
void *tmp = checked_realloc(scratch->error_callback, scratch->data, n); | if (scratch->data[scratch->frame] == NULL) { | ||||
if (tmp == NULL) { | |||||
return 0; | return 0; | ||||
} | } | ||||
scratch->init_size = n; | scratch->frame_size[scratch->frame] = n; | ||||
scratch->data = tmp; | scratch->offset[scratch->frame] = 0; | ||||
scratch->frame++; | |||||
return 1; | |||||
} else { | |||||
return 0; | |||||
} | } | ||||
return n <= scratch->max_size; | } | ||||
static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { | |||||
VERIFY_CHECK(scratch->frame > 0); | |||||
scratch->frame -= 1; | |||||
free(scratch->data[scratch->frame]); | |||||
} | } | ||||
static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { | ||||
void *ret; | void *ret; | ||||
size_t frame = scratch->frame - 1; | |||||
size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; | size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; | ||||
if (size + scratch->offset > scratch->init_size) { | |||||
if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { | |||||
return NULL; | return NULL; | ||||
} | } | ||||
ret = (void *) ((unsigned char *) scratch->data + scratch->offset); | ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); | ||||
memset(ret, 0, size); | memset(ret, 0, size); | ||||
scratch->offset += size; | scratch->offset[frame] += size; | ||||
return ret; | |||||
} | |||||
static void secp256k1_scratch_reset(secp256k1_scratch* scratch) { | return ret; | ||||
scratch->offset = 0; | |||||
} | } | ||||
#endif | #endif |