]> Git Repo - secp256k1.git/blame - src/scratch_impl.h
Keep LDFLAGS if `--coverage`
[secp256k1.git] / src / scratch_impl.h
CommitLineData
548de42e
AP
1/**********************************************************************
2 * Copyright (c) 2017 Andrew Poelstra *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5 **********************************************************************/
6
7#ifndef _SECP256K1_SCRATCH_IMPL_H_
8#define _SECP256K1_SCRATCH_IMPL_H_
9
10#include "scratch.h"
11
12/* Using 16 bytes alignment because common architectures never have alignment
13 * requirements above 8 for any of the types we care about. In addition we
14 * leave some room because currently we don't care about a few bytes.
15 * TODO: Determine this at configure time. */
16#define ALIGNMENT 16
17
6fe50439 18static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) {
548de42e
AP
19 secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret));
20 if (ret != NULL) {
6fe50439 21 memset(ret, 0, sizeof(*ret));
548de42e
AP
22 ret->max_size = max_size;
23 ret->error_callback = error_callback;
24 }
25 return ret;
26}
27
28static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) {
29 if (scratch != NULL) {
6fe50439 30 VERIFY_CHECK(scratch->frame == 0);
548de42e
AP
31 free(scratch);
32 }
33}
34
35static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) {
6fe50439
AP
36 size_t i = 0;
37 size_t allocated = 0;
38 for (i = 0; i < scratch->frame; i++) {
39 allocated += scratch->frame_size[i];
40 }
41 if (scratch->max_size - allocated <= objects * ALIGNMENT) {
548de42e
AP
42 return 0;
43 }
6fe50439 44 return scratch->max_size - allocated - objects * ALIGNMENT;
548de42e
AP
45}
46
6fe50439
AP
47static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) {
48 VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES);
49
50 if (n <= secp256k1_scratch_max_allocation(scratch, objects)) {
51 n += objects * ALIGNMENT;
52 scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n);
53 if (scratch->data[scratch->frame] == NULL) {
548de42e
AP
54 return 0;
55 }
6fe50439
AP
56 scratch->frame_size[scratch->frame] = n;
57 scratch->offset[scratch->frame] = 0;
58 scratch->frame++;
59 return 1;
60 } else {
61 return 0;
548de42e 62 }
6fe50439
AP
63}
64
65static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) {
66 VERIFY_CHECK(scratch->frame > 0);
67 scratch->frame -= 1;
68 free(scratch->data[scratch->frame]);
548de42e
AP
69}
70
71static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) {
72 void *ret;
6fe50439 73 size_t frame = scratch->frame - 1;
548de42e 74 size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
6fe50439
AP
75
76 if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) {
548de42e
AP
77 return NULL;
78 }
6fe50439 79 ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]);
548de42e 80 memset(ret, 0, size);
6fe50439 81 scratch->offset[frame] += size;
548de42e 82
6fe50439 83 return ret;
548de42e
AP
84}
85
86#endif
This page took 0.031012 seconds and 4 git commands to generate.