freemyipod r465 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r464‎ | r465 | r466 >
Date:21:23, 21 January 2011
Author:theseven
Status:new
Tags:
Comment:
emCORE: Shared library support. Not tested yet.
Modified paths:
  • /emcore/trunk/SOURCES (modified) (history)
  • /emcore/trunk/execimage.c (modified) (history)
  • /emcore/trunk/execimage.h (modified) (history)
  • /emcore/trunk/export/emcorelib.h (added) (history)
  • /emcore/trunk/library.c (added) (history)
  • /emcore/trunk/library.h (added) (history)
  • /emcore/trunk/thread.c (modified) (history)

Diff [purge]

Index: emcore/trunk/execimage.c
@@ -25,6 +25,7 @@
2626 #include "console.h"
2727 #include "execimage.h"
2828 #include "mmu.h"
 29+#include "malloc.h"
2930
3031
3132 struct scheduler_thread* execimage(void* image, bool copy)
@@ -37,11 +38,13 @@
3839 header->signature[0], header->signature[1], header->signature[2],
3940 header->signature[3], header->signature[4], header->signature[5],
4041 header->signature[6], header->signature[7]);
 42+ if (!copy) free(image);
4143 return NULL;
4244 }
4345 if (header->version != EMCOREAPP_HEADER_VERSION)
4446 {
4547 cprintf(CONSOLE_BOOT, "execimage: Unsupported version! (%08X)\n", header->version);
 48+ if (!copy) free(image);
4649 return NULL;
4750 }
4851 off_t offset = header->textstart;
@@ -52,7 +55,10 @@
5356 off_t relocstart = header->relocstart - offset;
5457 uint32_t reloccount = header->reloccount;
5558 bool compressed = header->flags & EMCOREAPP_FLAG_COMPRESSED;
56 - size_t finalsize = textsize + bsssize + stacksize;
 59+ bool lib = header->flags & EMCOREAPP_FLAG_LIBRARY;
 60+ size_t finalsize;
 61+ if (lib) finalsize = textsize + bsssize;
 62+ else finalsize = textsize + bsssize + stacksize;
5763 size_t datasize = relocstart + reloccount * 4;
5864 size_t tempsize = MAX(finalsize, datasize);
5965 if (compressed)
@@ -61,6 +67,7 @@
6268 if (!alloc)
6369 {
6470 cprintf(CONSOLE_BOOT, "execimage: Out of memory!\n");
 71+ if (!copy) free(image);
6572 return NULL;
6673 }
6774 uint32_t decompsize;
@@ -67,9 +74,11 @@
6875 if (ucl_decompress(image + offset, datasize, alloc, &decompsize))
6976 {
7077 cprintf(CONSOLE_BOOT, "execimage: Decompression failed!\n");
 78+ if (!copy) free(image);
7179 free(alloc);
7280 return NULL;
7381 }
 82+ if (!copy) free(image);
7483 if (datasize != decompsize)
7584 {
7685 cprintf(CONSOLE_BOOT, "execimage: Decompressed size mismatch!\n");
@@ -76,7 +85,6 @@
7786 free(alloc);
7887 return NULL;
7988 }
80 - if (!copy) free(image);
8189 image = alloc;
8290 }
8391 else if (copy)
@@ -93,12 +101,14 @@
94102 else
95103 {
96104 memcpy(image, image + offset, datasize);
97 - image = realloc(image, tempsize);
98 - if (!image)
 105+ void* newimage = realloc(image, tempsize);
 106+ if (!newimage)
99107 {
 108+ free(image);
100109 cprintf(CONSOLE_BOOT, "execimage: Out of memory!\n");
101110 return NULL;
102111 }
 112+ else image = newimage;
103113 }
104114 for (; reloccount; reloccount--, relocstart += 4)
105115 {
@@ -109,10 +119,18 @@
110120 if (tempsize != finalsize) realloc(image, finalsize); /* Can only shrink => safe */
111121 clean_dcache();
112122 invalidate_icache();
113 - struct scheduler_thread* thread = thread_create(NULL, NULL, image + entrypoint,
114 - image + textsize + bsssize, stacksize,
115 - USER_THREAD, 127, false);
116 - reownalloc(image, thread);
117 - thread_resume(thread);
 123+ struct scheduler_thread* thread;
 124+ if (lib) thread = (struct scheduler_thread*)library_register(image, image + entrypoint);
 125+ else
 126+ {
 127+ thread = thread_create(NULL, NULL, image + entrypoint, image + textsize + bsssize,
 128+ stacksize, USER_THREAD, 127, false);
 129+ if (thread)
 130+ {
 131+ reownalloc(image, thread);
 132+ thread_resume(thread);
 133+ }
 134+ else free(image);
 135+ }
118136 return thread;
119137 }
Index: emcore/trunk/execimage.h
@@ -50,6 +50,7 @@
5151 };
5252
5353 #define EMCOREAPP_FLAG_COMPRESSED 0x00000001
 54+#define EMCOREAPP_FLAG_LIBRARY 0x00000002
5455
5556
5657 #ifndef _TOOL
Index: emcore/trunk/export/emcorelib.h
@@ -0,0 +1,23 @@
 2+#include "syscallwrappers.h"
 3+
 4+
 5+#define EMCORE_LIB_HEADER(libidentifier, libversion, initfunc, shutdownfunc, apipointer) \
 6+ struct emcore_syscall_table* __emcore_syscall; \
 7+ int __emcore_lib_init() \
 8+ { \
 9+ asm volatile("swi\t2\n\tldr\tr1, =__emcore_syscall\n\tstr\tr0, [r1]\n\t" \
 10+ ::: "r0", "r1", "r2", "r3", "r12", "lr", "cc", "memory"); \
 11+ if (__embios_syscall->table_version < EMCORE_API_VERSION \
 12+ || __embios_syscall->table_minversion > EMCORE_API_VERSION) \
 13+ return 0x80000000; \
 14+ if (initfunc) return initfunc(); \
 15+ } \
 16+ struct emcorelib_header __attribute__((section(".emcoreentrypoint"))) __emcore_entrypoint() \
 17+ { \
 18+ .headerversion = EMCORELIB_HEADER_VERSION, \
 19+ .identifier = libidentifier, \
 20+ .version = libversion, \
 21+ .initfunc = __emcore_lib_init, \
 22+ .shutdownfunc = shutdownfunc, \
 23+ .api = apipointer \
 24+ };
Index: emcore/trunk/SOURCES
@@ -69,6 +69,7 @@
7070 init.c
7171 util.c
7272 malloc.c
 73+library.c
7374 #ifdef HAVE_LCD
7475 drawing.S
7576 lcdconsole.c
Index: emcore/trunk/library.c
@@ -0,0 +1,243 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+#include "library.h"
 27+#include "malloc.h"
 28+#include "execimage.h"
 29+#include "thread.h"
 30+#ifdef HAVE_STORAGE
 31+#include "file.h"
 32+#include "dir.h"
 33+#endif
 34+#ifdef HAVE_BOOTFLASH
 35+#include "bootflash.h"
 36+#endif
 37+#ifdef HAVE_BUTTON
 38+#include "button.h"
 39+#endif
 40+
 41+
 42+struct library_handle* library_list_head;
 43+struct mutex library_mutex;
 44+
 45+
 46+struct library_handle* library_register(void* image, struct emcorelib_header* header)
 47+{
 48+ mutex_lock(&library_mutex, TIMEOUT_BLOCK);
 49+ struct library_handle* h;
 50+ for (h = library_list_head; h; h = h->next)
 51+ if (h->lib->identifier == header->identifier && h->lib->version == header->version)
 52+ {
 53+ mutex_unlock(&library_mutex);
 54+ return NULL;
 55+ }
 56+ if (header->initfunc && header->initfunc() < 0)
 57+ {
 58+ mutex_unlock(&library_mutex);
 59+ return NULL;
 60+ }
 61+ struct library_handle* handle = (struct library_handle*)malloc(sizeof(struct library_handle));
 62+ memset(handle, 0, sizeof(struct library_handle));
 63+ reownalloc(handle, (struct scheduler_thread*)handle);
 64+ reownalloc(image, (struct scheduler_thread*)handle);
 65+ handle->next = library_list_head;
 66+ handle->lib = header;
 67+ handle->alloc = image;
 68+ mutex_unlock(&library_mutex);
 69+ return handle;
 70+}
 71+
 72+int library_unload(struct library_handle* lib)
 73+{
 74+ mutex_lock(&library_mutex, TIMEOUT_BLOCK);
 75+ int i;
 76+ bool found = false;
 77+ struct library_handle* h;
 78+ for (h = library_list_head; h; h = h->next)
 79+ if (h == lib)
 80+ {
 81+ found = true;
 82+ break;
 83+ }
 84+ if (!found)
 85+ {
 86+ mutex_unlock(&library_mutex);
 87+ return -1;
 88+ }
 89+ for (i = 0; i < ARRAYLEN(lib->users); i++)
 90+ if (lib->users[i])
 91+ {
 92+ mutex_unlock(&library_mutex);
 93+ return -2;
 94+ }
 95+ if (lib->moreusers)
 96+ for (i = 0; i < lib->moreusers_size / 4; i++)
 97+ if (lib->moreusers[i])
 98+ {
 99+ mutex_unlock(&library_mutex);
 100+ return -2;
 101+ }
 102+ if (lib->lib->shutdownfunc && lib->lib->shutdownfunc() < 0)
 103+ {
 104+ mutex_unlock(&library_mutex);
 105+ return -3;
 106+ }
 107+ if (library_list_head == lib) library_list_head = lib->next;
 108+ else
 109+ for (h = library_list_head; h; h = h->next)
 110+ if (h == lib)
 111+ {
 112+ h->next = lib->next;
 113+ break;
 114+ }
 115+ library_release_all_of_thread((struct scheduler_thread*)lib);
 116+#ifdef HAVE_STORAGE
 117+ close_all_of_process((struct scheduler_thread*)lib);
 118+ closedir_all_of_process((struct scheduler_thread*)lib);
 119+#endif
 120+#ifdef HAVE_BUTTON
 121+ button_unregister_all_of_thread((struct scheduler_thread*)lib);
 122+#endif
 123+ free_all_of_thread((struct scheduler_thread*)lib);
 124+ mutex_unlock(&library_mutex);
 125+ return 0;
 126+}
 127+
 128+struct emcorelib_header* get_library_ext(uint32_t identifier, uint32_t minversion,
 129+ uint32_t maxversion, enum library_sourcetype sourcetype,
 130+ void* source, struct scheduler_thread* owner)
 131+{
 132+ int i;
 133+ int version = minversion - 1;
 134+ struct library_handle* h;
 135+ struct library_handle* best = NULL;
 136+ mutex_lock(&library_mutex, TIMEOUT_BLOCK);
 137+ for (h = library_list_head; h; h = h->next)
 138+ if (h->lib->identifier == identifier &&
 139+ h->lib->version > version && h->lib->version <= maxversion)
 140+ {
 141+ best = h;
 142+ version = h->lib->version;
 143+ break;
 144+ }
 145+ if (!best)
 146+ {
 147+ mutex_unlock(&library_mutex);
 148+ return NULL;
 149+ }
 150+ for (i = 0; i < ARRAYLEN(best->users); i++)
 151+ if (best->users[i] == NULL)
 152+ {
 153+ best->users[i] = owner;
 154+ mutex_unlock(&library_mutex);
 155+ return best->lib;
 156+ }
 157+ if (best->moreusers)
 158+ for (i = 0; i < best->moreusers_size / 4; i++)
 159+ if (h->moreusers[i] == NULL)
 160+ {
 161+ h->moreusers[i] = owner;
 162+ mutex_unlock(&library_mutex);
 163+ return best->lib;
 164+ }
 165+ void* newalloc = realloc(best->moreusers, best->moreusers_size + 64);
 166+ if (!newalloc)
 167+ {
 168+ mutex_unlock(&library_mutex);
 169+ return NULL;
 170+ }
 171+ best->moreusers = (void**)newalloc;
 172+ best->moreusers[best->moreusers_size / 4] = owner;
 173+ best->moreusers_size += 64;
 174+ mutex_unlock(&library_mutex);
 175+ return best->lib;
 176+}
 177+
 178+struct emcorelib_header* get_library(uint32_t identifier, uint32_t minversion, uint32_t maxversion,
 179+ enum library_sourcetype sourcetype, void* source)
 180+{
 181+ return get_library_ext(identifier, minversion, maxversion, sourcetype, source, current_thread);
 182+}
 183+
 184+int release_library_ext(struct emcorelib_header* lib, struct scheduler_thread* owner)
 185+{
 186+ int i;
 187+ int rc = -2;
 188+ struct library_handle* h;
 189+ mutex_lock(&library_mutex, TIMEOUT_BLOCK);
 190+ for (h = library_list_head; h; h = h->next)
 191+ if (h->lib == lib)
 192+ {
 193+ rc = -1;
 194+ for (i = 0; i < ARRAYLEN(h->users); i++)
 195+ if (h->users[i] == owner)
 196+ {
 197+ h->users[i] = NULL;
 198+ rc = 0;
 199+ break;
 200+ }
 201+ if (rc && h->moreusers)
 202+ for (i = 0; i < h->moreusers_size / 4; i++)
 203+ if (h->moreusers[i] == owner)
 204+ {
 205+ h->moreusers[i] = NULL;
 206+ rc = 0;
 207+ break;
 208+ }
 209+ break;
 210+ }
 211+ mutex_unlock(&library_mutex);
 212+ return rc;
 213+}
 214+
 215+int release_library(struct emcorelib_header* lib)
 216+{
 217+ return release_library_ext(lib, current_thread);
 218+}
 219+
 220+int library_release_all_of_thread(struct scheduler_thread* thread)
 221+{
 222+ mutex_lock(&library_mutex, TIMEOUT_BLOCK);
 223+ int i;
 224+ int released = 0;
 225+ struct library_handle* h;
 226+ for (h = library_list_head; h; h = h->next)
 227+ {
 228+ for (i = 0; i < ARRAYLEN(h->users); i++)
 229+ if (h->users[i] == thread)
 230+ {
 231+ h->users[i] = NULL;
 232+ released++;
 233+ }
 234+ if (h->moreusers)
 235+ for (i = 0; i < h->moreusers_size / 4; i++)
 236+ if (h->moreusers[i] == thread)
 237+ {
 238+ h->moreusers[i] = NULL;
 239+ released++;
 240+ }
 241+ }
 242+ mutex_unlock(&library_mutex);
 243+ return released;
 244+}
Index: emcore/trunk/thread.c
@@ -27,6 +27,7 @@
2828 #include "panic.h"
2929 #include "util.h"
3030 #include "malloc.h"
 31+#include "library.h"
3132 #ifdef HAVE_STORAGE
3233 #include "dir.h"
3334 #include "file.h"
@@ -470,6 +471,7 @@
471472
472473 leave_critical_section(mode);
473474
 475+ library_release_all_of_thread(thread);
474476 #ifdef HAVE_STORAGE
475477 close_all_of_process(thread);
476478 closedir_all_of_process(thread);
Index: emcore/trunk/library.h
@@ -0,0 +1,80 @@
 2+//
 3+//
 4+// Copyright 2011 TheSeven
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __LIBRARY_H__
 26+#define __LIBRARY_H__
 27+
 28+
 29+#ifdef _TOOL
 30+#include <stdint.h>
 31+#else
 32+#include "global.h"
 33+#include "thread.h"
 34+#endif
 35+
 36+
 37+#define EMCORELIB_HEADER_VERSION 1
 38+struct emcorelib_header
 39+{
 40+ uint32_t headerversion;
 41+ uint32_t identifier;
 42+ uint32_t version;
 43+ int (*initfunc)();
 44+ int (*shutdownfunc)();
 45+ void* api;
 46+};
 47+
 48+struct library_handle
 49+{
 50+ struct library_handle* next;
 51+ struct emcorelib_header* lib;
 52+ void* alloc;
 53+ void* users[16];
 54+ void** moreusers;
 55+ size_t moreusers_size;
 56+};
 57+
 58+enum library_sourcetype
 59+{
 60+ LIBSOURCE_RAM_ALLOCED = 1,
 61+ LIBSOURCE_RAM_NEEDCOPY = 2,
 62+ LIBSOURCE_BOOTFLASH = 3,
 63+ LIBSOURCE_FILESYSTEM = 4
 64+};
 65+
 66+
 67+#ifndef _TOOL
 68+struct library_handle* library_register(void* image, struct emcorelib_header* header);
 69+int library_unload(struct library_handle* lib);
 70+struct emcorelib_header* get_library(uint32_t identifier, uint32_t minversion, uint32_t maxversion,
 71+ enum library_sourcetype sourcetype, void* source);
 72+struct emcorelib_header* get_library_ext(uint32_t identifier, uint32_t minversion,
 73+ uint32_t maxversion, enum library_sourcetype sourcetype,
 74+ void* source, struct scheduler_thread* owner);
 75+int release_library(struct emcorelib_header* lib);
 76+int release_library_ext(struct emcorelib_header* lib, struct scheduler_thread* owner);
 77+int library_release_all_of_thread(struct scheduler_thread* thread);
 78+#endif
 79+
 80+
 81+#endif