grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / exec / settaskstorageslot.c
blob0917f095b0220fb7a5a20245a8261a867c651b19
1 /*
2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <exec/nodes.h>
9 #include <exec/lists.h>
11 #include "exec_intern.h"
12 #include "taskstorage.h"
14 /*****************************************************************************
16 NAME */
17 #include <proto/exec.h>
19 AROS_LH2(BOOL, SetTaskStorageSlot,
21 /* LOCATION */
22 AROS_LHA(LONG, id, D0),
23 AROS_LHA(IPTR , value, D1),
24 struct ExecBase *, SysBase, 184, Exec)
26 /* FUNCTION
27 Puts a new value in a task storage slot. If necessary, the number of
28 task storage slots will be increased.
30 INPUTS
31 id - slot ID returned from AllocTaskStorageSlot().
32 value - value to store in the slot.
34 RESULT
35 success - TRUE if the value was successfully stored.
37 NOTES
39 EXAMPLE
41 BUGS
43 SEE ALSO
44 AllocTaskStorageSlot(), FreeTaskStorageSlot(), GetTaskStorageSlot()
46 INTERNALS
48 ******************************************************************************/
50 AROS_LIBFUNC_INIT
52 struct ETask *et = GetETask(GET_THIS_TASK);
53 IPTR *ts;
55 D(bug("SetTaskStorage: %p: Set TaskStorageSlot %d to %p\n", et, id, (APTR)value);)
57 if (!et) {
58 /* Only ETasks can do this */
59 D(bug("SetTaskStorage: Not an ETask!\n");)
60 return FALSE;
63 /* Valid ID? */
64 if (id < 1) {
65 D(bug("SetTaskStorage: Invalid ID %d\n", id);)
66 return FALSE;
69 ts = et->et_TaskStorage;
70 if (ts == NULL) {
71 /* No TaskStorage? Allocate some. */
72 ULONG slots = ((id + TASKSTORAGEPUDDLE) / TASKSTORAGEPUDDLE) * TASKSTORAGEPUDDLE;
73 ts = AllocMem(slots * sizeof(ts[0]), MEMF_ANY | MEMF_CLEAR);
74 if (ts == NULL) {
75 D(bug("SetTaskStorage: Can't allocate %d slots\n", slots);)
76 return FALSE;
79 ts[__TS_FIRSTSLOT] = slots;
81 /* Replacing of the pointer needs to be atomic due to GetParentTaskStorageSlot() */
82 et->et_TaskStorage = ts;
83 } else if (ts[__TS_FIRSTSLOT] <= id) {
84 IPTR *newts;
85 ULONG newslots = ((id + TASKSTORAGEPUDDLE) / TASKSTORAGEPUDDLE) * TASKSTORAGEPUDDLE;
86 size_t oldslots = ts[__TS_FIRSTSLOT];
88 newts = AllocMem(newslots * sizeof(ts[0]), MEMF_ANY);
89 if (newts == NULL) {
90 D(bug("SetTaskStorage: Can't allocate %d new slots\n", newslots);)
91 return FALSE;
94 newts[__TS_FIRSTSLOT] = newslots;
96 CopyMem(&ts[__TS_FIRSTSLOT+1], &newts[__TS_FIRSTSLOT+1],
97 (oldslots-1) * sizeof(ts[0]));
98 memset(&newts[oldslots], 0, (newslots - oldslots) * sizeof(ts[0]));
100 /* Replacing of the pointer needs to be atomic due to GetParentTaskStorageSlot() */
101 et->et_TaskStorage = newts;
102 FreeMem(ts, oldslots * sizeof(ts[0]));
105 et->et_TaskStorage[id] = value;
107 return TRUE;
109 AROS_LIBFUNC_EXIT