clean the code a little by reducing amout of places where gcc decides to put ud2...
[AROS.git] / rom / exec / settaskstorageslot.c
blob37ad985e45fc010f11f4da0f90272b908b39454c
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 Task *ThisTask = GET_THIS_TASK;
53 struct ETask *et = ThisTask ? GetETask(ThisTask) : NULL;
54 IPTR *ts;
56 D(bug("SetTaskStorage: %p: Set TaskStorageSlot %d to %p\n", et, id, (APTR)value);)
58 if (!et) {
59 /* Only ETasks can do this */
60 D(bug("SetTaskStorage: Not an ETask!\n");)
61 return FALSE;
64 /* Valid ID? */
65 if (id < 1) {
66 D(bug("SetTaskStorage: Invalid ID %d\n", id);)
67 return FALSE;
70 ts = et->et_TaskStorage;
71 if (ts == NULL) {
72 /* No TaskStorage? Allocate some. */
73 ULONG slots = ((id + TASKSTORAGEPUDDLE) / TASKSTORAGEPUDDLE) * TASKSTORAGEPUDDLE;
74 ts = AllocMem(slots * sizeof(ts[0]), MEMF_ANY | MEMF_CLEAR);
75 if (ts == NULL) {
76 D(bug("SetTaskStorage: Can't allocate %d slots\n", slots);)
77 return FALSE;
80 ts[__TS_FIRSTSLOT] = slots;
82 /* Replacing of the pointer needs to be atomic due to GetParentTaskStorageSlot() */
83 et->et_TaskStorage = ts;
84 } else if (ts[__TS_FIRSTSLOT] <= id) {
85 IPTR *newts;
86 ULONG newslots = ((id + TASKSTORAGEPUDDLE) / TASKSTORAGEPUDDLE) * TASKSTORAGEPUDDLE;
87 size_t oldslots = ts[__TS_FIRSTSLOT];
89 newts = AllocMem(newslots * sizeof(ts[0]), MEMF_ANY);
90 if (newts == NULL) {
91 D(bug("SetTaskStorage: Can't allocate %d new slots\n", newslots);)
92 return FALSE;
95 newts[__TS_FIRSTSLOT] = newslots;
97 CopyMem(&ts[__TS_FIRSTSLOT+1], &newts[__TS_FIRSTSLOT+1],
98 (oldslots-1) * sizeof(ts[0]));
99 memset(&newts[oldslots], 0, (newslots - oldslots) * sizeof(ts[0]));
101 /* Replacing of the pointer needs to be atomic due to GetParentTaskStorageSlot() */
102 et->et_TaskStorage = newts;
103 FreeMem(ts, oldslots * sizeof(ts[0]));
106 et->et_TaskStorage[id] = value;
108 return TRUE;
110 AROS_LIBFUNC_EXIT