6static void fpl_block_free(
struct fpool *fpl,
struct fpl_block *block);
13 u32 block_size, mem_size;
18 return KE_ILLEGAL_CONTEXT;
21 if (param->attr & ~(FA_THFIFO | FA_THPRI | FA_MEMBTM)) {
22 return KE_ILLEGAL_ATTR;
25 if (param->block_size == 0 || param->blocks == 0) {
26 return KE_ILLEGAL_MEMSIZE;
31 block_size = ALIGN(param->block_size);
32 mem_size = block_size * param->blocks;
34 mem = AllocSysMemory((param->attr & FA_MEMBTM) >> 9, mem_size, NULL);
40 fpl = heap_alloc(TAG_FPL,
sizeof(*fpl));
48 fpl->block_size = param->block_size;
49 fpl->blocks = param->blocks;
50 fpl->mem_size = mem_size;
51 fpl->event.attr = param->attr;
52 fpl->event.option = param->option;
54 list_init(&fpl->event.waiters);
55 list_insert(&thctx.fpool, &fpl->fpl_list);
58 for (
int i = 0; i < param->blocks; i++, mem += block_size) {
59 fpl_block_free(fpl, mem);
64 return MAKE_HANDLE(fpl);
67int DeleteFpl(
int fplId)
75 return KE_ILLEGAL_CONTEXT;
79 fpl = HANDLE_PTR(fplId);
80 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
82 return KE_UNKNOWN_FPLID;
85 list_for_each_safe (waiter, &fpl->event.waiters, queue) {
86 waiter->saved_regs->v0 = KE_WAIT_DELETE;
87 waiter->status = THS_READY;
88 list_remove(&waiter->queue);
89 readyq_insert_back(waiter);
92 waiter_count = fpl->event.waiter_count;
93 FreeSysMemory(fpl->memory);
94 list_remove(&fpl->fpl_list);
98 thctx.run_next = NULL;
99 return thread_leave(KE_OK, 0, state, 0);
107void *AllocateFpl(
int fplId)
115 return (
void *)KE_ILLEGAL_CONTEXT;
118 if (
CpuSuspendIntr(&state) == KE_CPUDI && (thctx.debug_flags & 8)) {
119 Kprintf(
"WARNING: AllocateFpl KE_CAN_NOT_WAIT\n");
122 fpl = HANDLE_PTR(fplId);
123 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
125 return (
void *)KE_UNKNOWN_FPLID;
129 block = fpl_block_alloc(fpl);
134 thread = thctx.current_thread;
136 thread->status = THS_WAIT;
137 thread->wait_type = TSW_FPL;
138 thread->wait_event = &fpl->event;
139 thctx.run_next = NULL;
141 fpl->event.waiter_count++;
143 if (fpl->event.attr & FA_THPRI) {
146 list_insert(&fpl->event.waiters, &
thread->queue);
149 return (
void *)thread_leave(KE_OK, 0, state, 1);
152void *pAllocateFpl(
int fplId)
159 return (
void *)KE_ILLEGAL_CONTEXT;
164 fpl = HANDLE_PTR(fplId);
165 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
167 return (
void *)KE_UNKNOWN_FPLID;
172 return (
void *)KE_NO_MEMORY;
175 block = fpl_block_alloc(fpl);
181void *ipAllocateFpl(
int fplId)
186 return (
void *)KE_ILLEGAL_CONTEXT;
189 fpl = HANDLE_PTR(fplId);
190 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
191 return (
void *)KE_UNKNOWN_FPLID;
195 return (
void *)KE_NO_MEMORY;
198 return fpl_block_alloc(fpl);
201int FreeFpl(
int fplId,
void *memory)
208 return KE_ILLEGAL_CONTEXT;
212 fpl = HANDLE_PTR(fplId);
213 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
215 return KE_UNKNOWN_FPLID;
218 if (memory < fpl->memory || memory >= (fpl->memory + fpl->mem_size)) {
219 return KE_ILLEGAL_MEMBLOCK;
222 if (fpl->event.waiter_count) {
223 waiter = list_first_entry(&fpl->event.waiters,
struct thread, queue);
224 fpl->event.waiter_count--;
225 list_remove(&waiter->queue);
226 waiter->status = THS_READY;
227 waiter->saved_regs->v0 = (u32)memory;
229 return thread_start(waiter, state);
232 fpl_block_free(fpl, memory);
243 return KE_ILLEGAL_CONTEXT;
247 fpl = HANDLE_PTR(fplId);
248 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
250 return KE_UNKNOWN_FPLID;
253 fpl_get_info(fpl,
info);
265 return KE_ILLEGAL_CONTEXT;
268 fpl = HANDLE_PTR(fplId);
269 if (!HANDLE_VERIFY(fplId, TAG_FPL)) {
270 return KE_UNKNOWN_FPLID;
273 fpl_get_info(fpl,
info);
294 tail->next = head->next;
300static void fpl_block_free(
struct fpool *fpl,
struct fpl_block *block)
307 block->next = tail->next;
318 info->attr = fpl->event.attr;
319 info->option = fpl->event.option;
320 info->blockSize = fpl->block_size;
321 info->numBlocks = fpl->blocks;
322 info->freeBlocks = fpl->free_blocks;
323 info->numWaitThreads = fpl->event.waiter_count;
int CpuResumeIntr(int state)
int QueryIntrContext(void)
int CpuSuspendIntr(int *state)