Index: Makefile
===================================================================
--- Makefile (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ Makefile (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -30,5 +30,8 @@
#
-.PHONY: all config config_default distclean clean cscope
+CSCOPE = cscope
+STANSE = stanse
+
+.PHONY: all config config_default distclean clean cscope stanse
all: Makefile.config config.h config.defs
@@ -36,4 +39,12 @@
$(MAKE) -C uspace
$(MAKE) -C boot
+
+stanse: Makefile.config config.h config.defs
+ $(MAKE) -C kernel clean
+ $(MAKE) -C kernel EXTRA_TOOL=stanse
+ $(STANSE) --checker ReachabilityChecker --checker ThreadChecker:contrib/$(STANSE)/ThreadChecker.xml --jobfile kernel/kernel.job
+
+cscope:
+ find kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out
Makefile.config: config_default
@@ -50,13 +61,8 @@
distclean: clean
- rm -f Makefile.config config.h config.defs tools/*.pyc
+ rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc
clean:
- -$(MAKE) -C kernel clean
- -$(MAKE) -C uspace clean
- -$(MAKE) -C boot clean
-
-cscope:
- find kernel boot uspace -regex '^.*\.[chsS]$$' -print > srclist
- rm -f cscope.out
- cscope -bi srclist
+ $(MAKE) -C kernel clean
+ $(MAKE) -C uspace clean
+ $(MAKE) -C boot clean
Index: contrib/bazaar/mbprotect/__init__.py
===================================================================
--- contrib/bazaar/mbprotect/__init__.py (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ contrib/bazaar/mbprotect/__init__.py (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -52,10 +52,17 @@
return
- # Look for old tip in new main branch.
+ # First permitted case is appending changesets to main branch.Look for
+ # old tip in new main branch.
for revision_id in repo.iter_reverse_revision_history(params.new_revid):
if revision_id == params.old_revid:
return # Found old tip
- # Old tip was not found. Reject the change.
+ # Another permitted case is backing out changesets. Look for new tip
+ # in old branch.
+ for revision_id in repo.iter_reverse_revision_history(params.old_revid):
+ if revision_id == params.new_revid:
+ return # Found new tip
+
+ # Trying to do something else. Reject the change.
raise TipChangeRejected('Bad tip. Read http://trac.helenos.org/trac.fcgi/' +
'wiki/BazaarWorkflow')
Index: contrib/stanse/ThreadChecker.xml
===================================================================
--- contrib/stanse/ThreadChecker.xml (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
+++ contrib/stanse/ThreadChecker.xml (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+ _mutex_lock_timeout
+
+
+
+
+
+
+
+ mutex_unlock
+
+
+
+
+
+
Index: kernel/Makefile
===================================================================
--- kernel/Makefile (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/Makefile (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -33,7 +33,8 @@
all: ../version ../Makefile.config ../config.h ../config.defs
-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
- $(MAKE) -f Makefile.build
+ $(MAKE) -f Makefile.build EXTRA_TOOL=$(EXTRA_TOOL)
clean:
- rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
+ rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(JOB) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
+ find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o.preproc' -follow -exec rm \{\} \;
Index: kernel/Makefile.build
===================================================================
--- kernel/Makefile.build (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/Makefile.build (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -91,5 +91,5 @@
## Cross-platform assembly to start a symtab.data section
#
-SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
+SYMTAB_SECTION = ".section symtab.data, \"a\", $(ATSIGN)progbits;"
## Simple detection for the type of the host system
@@ -110,5 +110,5 @@
ifeq ($(COMPILER),gcc_native)
CC = gcc
- GCC = $(CC)
+ GCC = gcc
AS = $(BINUTILS_PREFIX)as
LD = $(BINUTILS_PREFIX)ld
@@ -168,4 +168,5 @@
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
+
## Generic kernel sources
@@ -384,4 +385,7 @@
test/fpu/%.o: test/fpu/%.c $(DEPEND)
$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
+ifeq ($(EXTRA_TOOL),stanse)
+ ../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
+endif
#
@@ -390,4 +394,7 @@
%.o: %.c $(DEPEND)
$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@
+ifeq ($(EXTRA_TOOL),stanse)
+ ../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
+endif
$(REAL_MAP).o: $(REAL_MAP).bin
Index: kernel/Makefile.common
===================================================================
--- kernel/Makefile.common (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/Makefile.common (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -36,4 +36,5 @@
BIN = kernel.bin
MAP = kernel.map
+JOB = kernel.job
MAP_PREV = $(MAP).prev
DISASM = kernel.disasm
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/amd64/include/mm/page.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -177,4 +177,22 @@
#define PFERR_CODE_ID (1 << 4)
+/** Page Table Entry. */
+typedef struct {
+ unsigned present : 1;
+ unsigned writeable : 1;
+ unsigned uaccessible : 1;
+ unsigned page_write_through : 1;
+ unsigned page_cache_disable : 1;
+ unsigned accessed : 1;
+ unsigned dirty : 1;
+ unsigned unused: 1;
+ unsigned global : 1;
+ unsigned soft_valid : 1; /**< Valid content even if present bit is cleared. */
+ unsigned avl : 2;
+ unsigned addr_12_31 : 30;
+ unsigned addr_32_51 : 21;
+ unsigned no_execute : 1;
+} __attribute__ ((packed)) pte_t;
+
static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
{
Index: kernel/arch/amd64/include/types.h
===================================================================
--- kernel/arch/amd64/include/types.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/amd64/include/types.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -82,22 +82,4 @@
#define PRIxn "llx"
-/** Page Table Entry. */
-typedef struct {
- unsigned present : 1;
- unsigned writeable : 1;
- unsigned uaccessible : 1;
- unsigned page_write_through : 1;
- unsigned page_cache_disable : 1;
- unsigned accessed : 1;
- unsigned dirty : 1;
- unsigned unused: 1;
- unsigned global : 1;
- unsigned soft_valid : 1; /**< Valid content even if present bit is cleared. */
- unsigned avl : 2;
- unsigned addr_12_31 : 30;
- unsigned addr_32_51 : 21;
- unsigned no_execute : 1;
-} __attribute__ ((packed)) pte_t;
-
#endif
Index: kernel/arch/arm32/include/mm/page.h
===================================================================
--- kernel/arch/arm32/include/mm/page.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/arm32/include/mm/page.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -75,5 +75,5 @@
/* Get PTE address accessors for each level. */
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
- ((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
+ ((pte_t *) ((((pte_t *)(ptl0))[(i)].l0).coarse_table_addr << 10))
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
(ptl1)
@@ -81,19 +81,19 @@
(ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
- ((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
+ ((uintptr_t) ((((pte_t *)(ptl3))[(i)].l1).frame_base_addr << 12))
/* Set PTE address accessors for each level. */
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
- (set_ptl0_addr((pte_level0_t *) (ptl0)))
+ (set_ptl0_addr((pte_t *) (ptl0)))
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
- (((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
+ (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
- (((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
+ (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
- get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i))
+ get_pt_level0_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
@@ -101,13 +101,13 @@
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
- get_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i))
+ get_pt_level1_flags((pte_t *) (ptl3), (size_t) (i))
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
- set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i), (x))
+ set_pt_level0_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
- set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x))
+ set_pt_level1_flags((pte_t *) (ptl3), (size_t) (i), (x))
/* Macros for querying the last-level PTE entries. */
@@ -115,10 +115,9 @@
(*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) \
- (((pte_level0_t *) (pte))->descriptor_type != 0)
+ (((pte_t *) (pte))->l0.descriptor_type != 0)
#define PTE_GET_FRAME_ARCH(pte) \
- (((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
+ (((pte_t *) (pte))->l1.frame_base_addr << FRAME_WIDTH)
#define PTE_WRITABLE_ARCH(pte) \
- (((pte_level1_t *) (pte))->access_permission_0 == \
- PTE_AP_USER_RW_KERNEL_RW)
+ (((pte_t *) (pte))->l1.access_permission_0 == PTE_AP_USER_RW_KERNEL_RW)
#define PTE_EXECUTABLE_ARCH(pte) \
1
@@ -159,4 +158,8 @@
} ATTRIBUTE_PACKED pte_level1_t;
+typedef union {
+ pte_level0_t l0;
+ pte_level1_t l1;
+} pte_t;
/* Level 1 page tables access permissions */
@@ -191,5 +194,5 @@
* @param pt Pointer to the page table to set.
*/
-static inline void set_ptl0_addr(pte_level0_t *pt)
+static inline void set_ptl0_addr(pte_t *pt)
{
asm volatile (
@@ -205,7 +208,7 @@
* @param i Index of the entry to return.
*/
-static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i)
-{
- pte_level0_t *p = &pt[i];
+static inline int get_pt_level0_flags(pte_t *pt, size_t i)
+{
+ pte_level0_t *p = &pt[i].l0;
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
@@ -220,7 +223,7 @@
* @param i Index of the entry to return.
*/
-static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i)
-{
- pte_level1_t *p = &pt[i];
+static inline int get_pt_level1_flags(pte_t *pt, size_t i)
+{
+ pte_level1_t *p = &pt[i].l1;
int dt = p->descriptor_type;
@@ -245,7 +248,7 @@
* @param flags new flags
*/
-static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags)
-{
- pte_level0_t *p = &pt[i];
+static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
+{
+ pte_level0_t *p = &pt[i].l0;
if (flags & PAGE_NOT_PRESENT) {
@@ -273,7 +276,7 @@
* @param flags New flags.
*/
-static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags)
-{
- pte_level1_t *p = &pt[i];
+static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
+{
+ pte_level1_t *p = &pt[i].l1;
if (flags & PAGE_NOT_PRESENT) {
Index: kernel/arch/arm32/include/types.h
===================================================================
--- kernel/arch/arm32/include/types.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/arm32/include/types.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -87,13 +87,4 @@
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */
-/** Page table entry.
- *
- * We have different structs for level 0 and level 1 page table entries.
- * See page.h for definition of pte_level*_t.
- */
-typedef struct {
- unsigned dummy : 32;
-} pte_t;
-
#endif
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/ia32/include/mm/page.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -146,4 +146,20 @@
#define PFERR_CODE_RSVD (1 << 3)
+/** Page Table Entry. */
+typedef struct {
+ unsigned present : 1;
+ unsigned writeable : 1;
+ unsigned uaccessible : 1;
+ unsigned page_write_through : 1;
+ unsigned page_cache_disable : 1;
+ unsigned accessed : 1;
+ unsigned dirty : 1;
+ unsigned pat : 1;
+ unsigned global : 1;
+ unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */
+ unsigned avl : 2;
+ unsigned frame_address : 20;
+} __attribute__ ((packed)) pte_t;
+
static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
{
Index: kernel/arch/ia32/include/types.h
===================================================================
--- kernel/arch/ia32/include/types.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/ia32/include/types.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -80,20 +80,4 @@
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */
-/** Page Table Entry. */
-typedef struct {
- unsigned present : 1;
- unsigned writeable : 1;
- unsigned uaccessible : 1;
- unsigned page_write_through : 1;
- unsigned page_cache_disable : 1;
- unsigned accessed : 1;
- unsigned dirty : 1;
- unsigned pat : 1;
- unsigned global : 1;
- unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */
- unsigned avl : 2;
- unsigned frame_address : 20;
-} __attribute__ ((packed)) pte_t;
-
#endif
Index: kernel/arch/mips32/include/mm/page.h
===================================================================
--- kernel/arch/mips32/include/mm/page.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/mips32/include/mm/page.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -141,4 +141,18 @@
#include
+/** Page Table Entry. */
+typedef struct {
+ unsigned g : 1; /**< Global bit. */
+ unsigned p : 1; /**< Present bit. */
+ unsigned d : 1; /**< Dirty bit. */
+ unsigned cacheable : 1; /**< Cacheable bit. */
+ unsigned : 1; /**< Unused. */
+ unsigned soft_valid : 1; /**< Valid content even if not present. */
+ unsigned pfn : 24; /**< Physical frame number. */
+ unsigned w : 1; /**< Page writable bit. */
+ unsigned a : 1; /**< Accessed bit. */
+} pte_t;
+
+
static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
{
Index: kernel/arch/mips32/include/types.h
===================================================================
--- kernel/arch/mips32/include/types.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/mips32/include/types.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -80,17 +80,4 @@
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */
-/** Page Table Entry. */
-typedef struct {
- unsigned g : 1; /**< Global bit. */
- unsigned p : 1; /**< Present bit. */
- unsigned d : 1; /**< Dirty bit. */
- unsigned cacheable : 1; /**< Cacheable bit. */
- unsigned : 1; /**< Unused. */
- unsigned soft_valid : 1; /**< Valid content even if not present. */
- unsigned pfn : 24; /**< Physical frame number. */
- unsigned w : 1; /**< Page writable bit. */
- unsigned a : 1; /**< Accessed bit. */
-} pte_t;
-
#endif
Index: kernel/arch/ppc32/include/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/mm/page.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/ppc32/include/mm/page.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -131,4 +131,15 @@
#include
+/** Page Table Entry. */
+typedef struct {
+ unsigned present : 1; /**< Present bit. */
+ unsigned page_write_through : 1; /**< Write thought caching. */
+ unsigned page_cache_disable : 1; /**< No caching. */
+ unsigned accessed : 1; /**< Accessed bit. */
+ unsigned global : 1; /**< Global bit. */
+ unsigned valid : 1; /**< Valid content even if not present. */
+ unsigned pfn : 20; /**< Physical frame number. */
+} pte_t;
+
static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
{
Index: kernel/arch/ppc32/include/types.h
===================================================================
--- kernel/arch/ppc32/include/types.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/arch/ppc32/include/types.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -82,15 +82,4 @@
#define PRIxn "x"
-/** Page Table Entry. */
-typedef struct {
- unsigned present : 1; /**< Present bit. */
- unsigned page_write_through : 1; /**< Write thought caching. */
- unsigned page_cache_disable : 1; /**< No caching. */
- unsigned accessed : 1; /**< Accessed bit. */
- unsigned global : 1; /**< Global bit. */
- unsigned valid : 1; /**< Valid content even if not present. */
- unsigned pfn : 20; /**< Physical frame number. */
-} pte_t;
-
#endif
Index: kernel/genarch/include/mm/as_pt.h
===================================================================
--- kernel/genarch/include/mm/as_pt.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/genarch/include/mm/as_pt.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -36,6 +36,5 @@
#define KERN_AS_PT_H_
-#include
-#include
+#include
#define AS_PAGE_TABLE
Index: kernel/genarch/include/mm/page_pt.h
===================================================================
--- kernel/genarch/include/mm/page_pt.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/genarch/include/mm/page_pt.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -44,7 +44,8 @@
#define KERN_PAGE_PT_H_
-#include
#include
#include
+#include
+#include
/*
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/include/ipc/ipc.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -51,14 +51,12 @@
/** This is answer to a call */
#define IPC_CALL_ANSWERED (1 << 0)
-/** This call will not be freed on error */
-#define IPC_CALL_STATIC_ALLOC (1 << 1)
/** Answer will not be passed to userspace, will be discarded */
-#define IPC_CALL_DISCARD_ANSWER (1 << 2)
+#define IPC_CALL_DISCARD_ANSWER (1 << 1)
/** Call was forwarded */
-#define IPC_CALL_FORWARDED (1 << 3)
+#define IPC_CALL_FORWARDED (1 << 2)
/** Identify connect_me_to answer */
-#define IPC_CALL_CONN_ME_TO (1 << 4)
+#define IPC_CALL_CONN_ME_TO (1 << 3)
/** Interrupt notification */
-#define IPC_CALL_NOTIF (1 << 5)
+#define IPC_CALL_NOTIF (1 << 4)
/*
@@ -267,4 +265,7 @@
waitq_t wq;
+ /** Linkage for the list of task's synchronous answerboxes. */
+ link_t sync_box_link;
+
/** Phones connected to this answerbox. */
link_t connected_phones;
@@ -316,25 +317,31 @@
} call_t;
+
+extern answerbox_t *ipc_phone_0;
+
+
extern void ipc_init(void);
-extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
-extern void ipc_answer(answerbox_t *, call_t *);
+
+extern call_t * ipc_call_alloc(int);
+extern void ipc_call_free(call_t *);
+
extern int ipc_call(phone_t *, call_t *);
extern int ipc_call_sync(phone_t *, call_t *);
+extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
+extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
+extern void ipc_answer(answerbox_t *, call_t *);
+
extern void ipc_phone_init(phone_t *);
extern void ipc_phone_connect(phone_t *, answerbox_t *);
-extern void ipc_call_free(call_t *);
-extern call_t * ipc_call_alloc(int);
+extern int ipc_phone_hangup(phone_t *);
+
extern void ipc_answerbox_init(answerbox_t *, struct task *);
-extern void ipc_call_static_init(call_t *);
-extern void task_print_list(void);
-extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
+
extern void ipc_cleanup(void);
-extern int ipc_phone_hangup(phone_t *);
extern void ipc_backsend_err(phone_t *, call_t *, unative_t);
-extern void ipc_print_task(task_id_t);
extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
extern void ipc_cleanup_call_list(link_t *);
-extern answerbox_t *ipc_phone_0;
+extern void ipc_print_task(task_id_t);
#endif
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/include/proc/task.h (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -98,4 +98,6 @@
*/
atomic_t active_calls;
+ /** List of synchronous answerboxes. */
+ link_t sync_box_head;
#ifdef CONFIG_UDEBUG
@@ -132,4 +134,5 @@
extern int task_kill(task_id_t id);
extern uint64_t task_get_accounting(task_t *t);
+extern void task_print_list(void);
extern void cap_set(task_t *t, cap_t caps);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/ipc.c (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -62,4 +62,5 @@
static slab_cache_t *ipc_call_slab;
+static slab_cache_t *ipc_answerbox_slab;
/** Initialize a call structure.
@@ -96,15 +97,4 @@
}
-/** Initialize a statically allocated call structure.
- *
- * @param call Statically allocated kernel call structure to be
- * initialized.
- */
-void ipc_call_static_init(call_t *call)
-{
- _ipc_call_init(call);
- call->flags |= IPC_CALL_STATIC_ALLOC;
-}
-
/** Deallocate a call structure.
*
@@ -113,5 +103,4 @@
void ipc_call_free(call_t *call)
{
- ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
/* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
if (call->buffer)
@@ -130,4 +119,5 @@
spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
waitq_initialize(&box->wq);
+ link_initialize(&box->sync_box_link);
list_initialize(&box->connected_phones);
list_initialize(&box->calls);
@@ -179,15 +169,41 @@
int ipc_call_sync(phone_t *phone, call_t *request)
{
- answerbox_t sync_box;
-
- ipc_answerbox_init(&sync_box, TASK);
+ answerbox_t *sync_box;
+ ipl_t ipl;
+
+ sync_box = slab_alloc(ipc_answerbox_slab, 0);
+ ipc_answerbox_init(sync_box, TASK);
+
+ /*
+ * Put the answerbox on the TASK's list of synchronous answerboxes so
+ * that it can be cleaned up if the call is interrupted.
+ */
+ ipl = interrupts_disable();
+ spinlock_lock(&TASK->lock);
+ list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
+ spinlock_unlock(&TASK->lock);
+ interrupts_restore(ipl);
/* We will receive data in a special box. */
- request->callerbox = &sync_box;
+ request->callerbox = sync_box;
ipc_call(phone, request);
- if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
- SYNCH_FLAGS_INTERRUPTIBLE))
+ if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
+ SYNCH_FLAGS_INTERRUPTIBLE)) {
+ /* The answerbox and the call will be freed by ipc_cleanup(). */
return EINTR;
+ }
+
+ /*
+ * The answer arrived without interruption so we can remove the
+ * answerbox from the TASK's list of synchronous answerboxes.
+ */
+ (void) interrupts_disable();
+ spinlock_lock(&TASK->lock);
+ list_remove(&sync_box->sync_box_link);
+ spinlock_unlock(&TASK->lock);
+ interrupts_restore(ipl);
+
+ slab_free(ipc_answerbox_slab, sync_box);
return EOK;
}
@@ -520,4 +536,5 @@
int i;
call_t *call;
+ ipl_t ipl;
/* Disconnect all our phones ('ipc_phone_hangup') */
@@ -545,5 +562,19 @@
spinlock_unlock(&TASK->answerbox.lock);
- /* Wait for all async answers to arrive */
+ /* Wait for all answers to interrupted synchronous calls to arrive */
+ ipl = interrupts_disable();
+ while (!list_empty(&TASK->sync_box_head)) {
+ answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
+ answerbox_t, sync_box_link);
+
+ list_remove(&box->sync_box_link);
+ call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
+ SYNCH_FLAGS_NONE);
+ ipc_call_free(call);
+ slab_free(ipc_answerbox_slab, box);
+ }
+ interrupts_restore(ipl);
+
+ /* Wait for all answers to asynchronous calls to arrive */
while (1) {
/* Go through all phones, until all are FREE... */
@@ -552,6 +583,8 @@
for (i = 0; i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
- atomic_get(&TASK->phones[i].active_calls) == 0)
+ atomic_get(&TASK->phones[i].active_calls) == 0) {
TASK->phones[i].state = IPC_PHONE_FREE;
+ TASK->phones[i].callee = NULL;
+ }
/* Just for sure, we might have had some
@@ -574,5 +607,4 @@
ASSERT((call->flags & IPC_CALL_ANSWERED) ||
(call->flags & IPC_CALL_NOTIF));
- ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
/*
@@ -593,4 +625,6 @@
ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
NULL, 0);
+ ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
+ sizeof(answerbox_t), 0, NULL, NULL, 0);
}
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/irq.c (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -418,5 +418,4 @@
case CMD_ACCEPT:
return IRQ_ACCEPT;
- break;
case CMD_DECLINE:
default:
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/sysipc.c (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -61,5 +61,5 @@
{ \
if (phoneid > IPC_MAX_PHONES) { \
- err; \
+ err \
} \
phone = &TASK->phones[phoneid]; \
@@ -122,5 +122,4 @@
case IPC_M_DATA_READ:
return 1;
- break;
default:
return 0;
@@ -376,5 +375,5 @@
phone_t *cloned_phone;
GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
- return ENOENT);
+ return ENOENT;);
phones_lock(cloned_phone, phone);
if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
@@ -531,39 +530,42 @@
unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data)
{
- call_t call;
+ call_t *call;
phone_t *phone;
int res;
int rc;
- GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
- ipc_call_static_init(&call);
- IPC_SET_METHOD(call.data, method);
- IPC_SET_ARG1(call.data, arg1);
- IPC_SET_ARG2(call.data, arg2);
- IPC_SET_ARG3(call.data, arg3);
+ GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+ call = ipc_call_alloc(0);
+ IPC_SET_METHOD(call->data, method);
+ IPC_SET_ARG1(call->data, arg1);
+ IPC_SET_ARG2(call->data, arg2);
+ IPC_SET_ARG3(call->data, arg3);
/*
* To achieve deterministic behavior, zero out arguments that are beyond
* the limits of the fast version.
*/
- IPC_SET_ARG4(call.data, 0);
- IPC_SET_ARG5(call.data, 0);
-
- if (!(res = request_preprocess(&call, phone))) {
+ IPC_SET_ARG4(call->data, 0);
+ IPC_SET_ARG5(call->data, 0);
+
+ if (!(res = request_preprocess(call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
- rc = ipc_call_sync(phone, &call);
+ rc = ipc_call_sync(phone, call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
- if (rc != EOK)
+ if (rc != EOK) {
+ /* The call will be freed by ipc_cleanup(). */
return rc;
- process_answer(&call);
+ }
+ process_answer(call);
} else {
- IPC_SET_RETVAL(call.data, res);
- }
- rc = STRUCT_TO_USPACE(&data->args, &call.data.args);
+ IPC_SET_RETVAL(call->data, res);
+ }
+ rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
+ ipc_call_free(call);
if (rc != 0)
return rc;
@@ -584,32 +586,38 @@
ipc_data_t *reply)
{
- call_t call;
+ call_t *call;
phone_t *phone;
int res;
int rc;
- ipc_call_static_init(&call);
- rc = copy_from_uspace(&call.data.args, &question->args,
- sizeof(call.data.args));
- if (rc != 0)
+ GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+ call = ipc_call_alloc(0);
+ rc = copy_from_uspace(&call->data.args, &question->args,
+ sizeof(call->data.args));
+ if (rc != 0) {
+ ipc_call_free(call);
return (unative_t) rc;
-
- GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
- if (!(res = request_preprocess(&call, phone))) {
+ }
+
+
+ if (!(res = request_preprocess(call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
- rc = ipc_call_sync(phone, &call);
+ rc = ipc_call_sync(phone, call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
- if (rc != EOK)
+ if (rc != EOK) {
+ /* The call will be freed by ipc_cleanup(). */
return rc;
- process_answer(&call);
+ }
+ process_answer(call);
} else
- IPC_SET_RETVAL(call.data, res);
-
- rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
+ IPC_SET_RETVAL(call->data, res);
+
+ rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
+ ipc_call_free(call);
if (rc != 0)
return rc;
@@ -658,5 +666,5 @@
return IPC_CALLRET_TEMPORARY;
- GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+ GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
call = ipc_call_alloc(0);
@@ -697,5 +705,5 @@
return IPC_CALLRET_TEMPORARY;
- GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+ GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
call = ipc_call_alloc(0);
@@ -747,5 +755,5 @@
call->flags |= IPC_CALL_FORWARDED;
- GET_CHECK_PHONE(phone, phoneid, {
+ GET_CHECK_PHONE(phone, phoneid, {
IPC_SET_RETVAL(call->data, EFORWARD);
ipc_answer(&TASK->answerbox, call);
@@ -952,5 +960,5 @@
phone_t *phone;
- GET_CHECK_PHONE(phone, phoneid, return ENOENT);
+ GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
if (ipc_phone_hangup(phone))
@@ -991,6 +999,4 @@
if (call->flags & IPC_CALL_NOTIF) {
- ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
-
/* Set in_phone_hash to the interrupt counter */
call->data.phone = (void *) call->priv;
@@ -1005,6 +1011,4 @@
if (call->flags & IPC_CALL_ANSWERED) {
process_answer(call);
-
- ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
if (call->flags & IPC_CALL_DISCARD_ANSWER) {
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/lib/elf.c (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -163,5 +163,4 @@
case PT_LOAD:
return load_segment(entry, elf, as);
- break;
case PT_DYNAMIC:
case PT_INTERP:
@@ -182,5 +181,4 @@
default:
return EE_UNSUPPORTED;
- break;
}
return EE_OK;
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/proc/task.c (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -75,6 +75,9 @@
static task_id_t task_counter = 0;
+static slab_cache_t *task_slab;
+
/* Forward declarations. */
static void task_kill_internal(task_t *);
+static int tsk_constructor(void *, int);
/** Initialize kernel tasks support. */
@@ -83,4 +86,6 @@
TASK = NULL;
avltree_create(&tasks_tree);
+ task_slab = slab_cache_create("task_slab", sizeof(task_t), 0,
+ tsk_constructor, NULL, 0);
}
@@ -128,4 +133,33 @@
}
+int tsk_constructor(void *obj, int kmflags)
+{
+ task_t *ta = obj;
+ int i;
+
+ atomic_set(&ta->refcount, 0);
+ atomic_set(&ta->lifecount, 0);
+ atomic_set(&ta->active_calls, 0);
+
+ spinlock_initialize(&ta->lock, "task_ta_lock");
+ mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
+ list_initialize(&ta->th_head);
+ list_initialize(&ta->sync_box_head);
+
+ ipc_answerbox_init(&ta->answerbox, ta);
+ for (i = 0; i < IPC_MAX_PHONES; i++)
+ ipc_phone_init(&ta->phones[i]);
+
+#ifdef CONFIG_UDEBUG
+ /* Init kbox stuff */
+ ta->kb.thread = NULL;
+ ipc_answerbox_init(&ta->kb.box, ta);
+ mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
+#endif
+
+ return 0;
+}
+
/** Create new task with no threads.
*
@@ -140,21 +174,12 @@
ipl_t ipl;
task_t *ta;
- int i;
-
- ta = (task_t *) malloc(sizeof(task_t), 0);
-
+
+ ta = (task_t *) slab_alloc(task_slab, 0);
task_create_arch(ta);
-
- spinlock_initialize(&ta->lock, "task_ta_lock");
- list_initialize(&ta->th_head);
ta->as = as;
-
memcpy(ta->name, name, TASK_NAME_BUFLEN);
ta->name[TASK_NAME_BUFLEN - 1] = 0;
- atomic_set(&ta->refcount, 0);
- atomic_set(&ta->lifecount, 0);
ta->context = CONTEXT;
-
ta->capabilities = 0;
ta->cycles = 0;
@@ -165,28 +190,15 @@
/* Init kbox stuff */
- ipc_answerbox_init(&ta->kb.box, ta);
- ta->kb.thread = NULL;
- mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
ta->kb.finished = false;
#endif
- ipc_answerbox_init(&ta->answerbox, ta);
- for (i = 0; i < IPC_MAX_PHONES; i++)
- ipc_phone_init(&ta->phones[i]);
- if ((ipc_phone_0) && (context_check(ipc_phone_0->task->context,
- ta->context)))
+ if ((ipc_phone_0) &&
+ (context_check(ipc_phone_0->task->context, ta->context)))
ipc_phone_connect(&ta->phones[0], ipc_phone_0);
- atomic_set(&ta->active_calls, 0);
-
- mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
btree_create(&ta->futexes);
ipl = interrupts_disable();
-
- /*
- * Increment address space reference count.
- */
atomic_inc(&as->refcount);
-
spinlock_lock(&tasks_lock);
ta->taskid = ++task_counter;
@@ -229,5 +241,5 @@
as_destroy(t->as);
- free(t);
+ slab_free(task_slab, t);
TASK = NULL;
}
Index: tools/config.py
===================================================================
--- tools/config.py (revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ tools/config.py (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -227,5 +227,8 @@
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
+
+ sys.stderr.write("Fetching current revision identifier ... ")
version = subprocess.Popen(['bzr', 'version-info', '--custom', '--template={clean}:{revno}:{revision_id}'], stdout = subprocess.PIPE).communicate()[0].split(':')
+ sys.stderr.write("OK\n")
if (len(version) == 3):
Index: tools/jobfile.py
===================================================================
--- tools/jobfile.py (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
+++ tools/jobfile.py (revision 3f35634cf8784398faec3ed02b32b4a4ffe2033a)
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2009 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+"""
+Add a source/object file pair to a Stanse jobfile
+"""
+
+import sys
+import os
+import fcntl
+
+def usage(prname):
+ "Print usage syntax"
+ print prname + "