]> Git Repo - secp256k1.git/blob - src/scratch_impl.h
Merge #509: Fix algorithm selection in bench_ecmult
[secp256k1.git] / src / scratch_impl.h
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
18 static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) {
19     secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret));
20     if (ret != NULL) {
21         memset(ret, 0, sizeof(*ret));
22         ret->max_size = max_size;
23         ret->error_callback = error_callback;
24     }
25     return ret;
26 }
27
28 static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) {
29     if (scratch != NULL) {
30         VERIFY_CHECK(scratch->frame == 0);
31         free(scratch);
32     }
33 }
34
35 static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) {
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) {
42         return 0;
43     }
44     return scratch->max_size - allocated - objects * ALIGNMENT;
45 }
46
47 static 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) {
54             return 0;
55         }
56         scratch->frame_size[scratch->frame] = n;
57         scratch->offset[scratch->frame] = 0;
58         scratch->frame++;
59         return 1;
60     } else {
61         return 0;
62     }
63 }
64
65 static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) {
66     VERIFY_CHECK(scratch->frame > 0);
67     scratch->frame -= 1;
68     free(scratch->data[scratch->frame]);
69 }
70
71 static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) {
72     void *ret;
73     size_t frame = scratch->frame - 1;
74     size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
75
76     if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) {
77         return NULL;
78     }
79     ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]);
80     memset(ret, 0, size);
81     scratch->offset[frame] += size;
82
83     return ret;
84 }
85
86 #endif
This page took 0.027512 seconds and 4 git commands to generate.