From 8f253a20bc7fa28c9a3af8124a96ca5de645f3f1 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sun, 26 Jul 2020 18:11:36 -0500 Subject: [PATCH 01/36] Add a gpu device abstraction - note that this is for 2D graphics only --- Kconfig | 6 + include/nautilus/dev.h | 4 +- include/nautilus/gpudev.h | 285 ++++++++++++++++++++++++++++++++++++++ src/arch/gem5/init.c | 2 + src/arch/x64/init.c | 2 + src/nautilus/Makefile | 1 + src/nautilus/gpudev.c | 246 ++++++++++++++++++++++++++++++++ 7 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 include/nautilus/gpudev.h create mode 100644 src/nautilus/gpudev.c diff --git a/Kconfig b/Kconfig index 9892f8acd..3f4a16999 100644 --- a/Kconfig +++ b/Kconfig @@ -1190,6 +1190,12 @@ config DEBUG_GROUP default n help Turn on debug output for network device interface + config DEBUG_GPUDEV + bool "Debug GPU (Graphics) Device Interface" + depends on DEBUG_DEV + default n + help + Turn on debug output for GPU (graphics) device interface config DEBUG_PARTITION bool "Debug Partitioning" depends on PARTITION_SUPPORT && DEBUG_DEV diff --git a/include/nautilus/dev.h b/include/nautilus/dev.h index 7cb30f4d9..3a5c2ec52 100644 --- a/include/nautilus/dev.h +++ b/include/nautilus/dev.h @@ -35,7 +35,9 @@ typedef enum { NK_DEV_BUS, NK_DEV_CHAR, NK_DEV_BLK, - NK_DEV_NET + NK_DEV_NET, + NK_DEV_GRAPHICS, + NK_DEV_SOUND, } nk_dev_type_t ; diff --git a/include/nautilus/gpudev.h b/include/nautilus/gpudev.h new file mode 100644 index 000000000..35a0f12a8 --- /dev/null +++ b/include/nautilus/gpudev.h @@ -0,0 +1,285 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The Interweaving Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + +#ifndef __GPU_DEV +#define __GPU_DEV + +#include + + +/* + Don't get too excited by the use of the term "GPU". + + This is currently simply an abstraction for 2D accelerated graphics + cards. Video modes are either 2D graphics or text + + text: all are basic VGA 1 byte char, 1 byte attr + + graphics: all are 4 bytes, 1 byte per channel, + rgb + optional alpha, selective order + + */ + + +typedef struct nk_gpu_dev_video_mode { + enum {NK_GPU_DEV_MODE_TYPE_TEXT, NK_GPU_DEV_MODE_TYPE_GRAPHICS_2D } type; + uint32_t width; // width and height of screen (pixels or + uint32_t height; + + uint8_t channel_offset[4]; // for graphics, channel offsets into a pixel (-1 means channel does not exist) +#define NK_GPU_DEV_CHANNEL_OFFSET_RED 0 // for text, channel 0 is the character, channel 1 is the attribute +#define NK_GPU_DEV_CHANNEL_OFFSET_GREEN 1 +#define NK_GPU_DEV_CHANNEL_OFFSET_BLUE 2 +#define NK_GPU_DEV_CHANNEL_OFFSET_ALPHA 3 +#define NK_GPU_DEV_CHANNEL_OFFSET_TEXT 0 +#define NK_GPU_DEV_CHANNEL_OFFSET_ATTR 1 + + uint64_t flags; +#define NK_GPU_DEV_HAS_CLIPPING 0x1 // does the mode support clipping by box? +#define NK_GPU_DEV_HAS_CLIPPING_REGION 0x2 // does the mode support clipping by arbitrary region? +#define NK_GPU_DEV_HAS_MOUSE_CURSOR 0x100 // does the mode allow setting a mouse cursor? + + + uint32_t mouse_cursor_width; // size of mouse cursor, if supported + uint32_t mouse_cursor_height; // bitmap format is assumed to be the same as the mode's format + + void *mode_data; // opaque pointer to any info driver wants to associate with it + // should be static data, caller will not delete this +} nk_gpu_dev_video_mode_t; + + +// coordinate (0,0) is top left and (width-1,height-1) is bottom right +typedef struct nk_gpu_dev_coordinate { + uint32_t x; + uint32_t y; +} nk_gpu_dev_coordinate_t; + + +// bounding box, clipping, etc +// coordinate system as with nk_gpu_dev_coordinate_t +typedef struct nk_gpu_dev_box { + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +} nk_gpu_dev_box_t; + +typedef struct nk_gpu_dev_region { + // CURRENTLY NOT IMPLEMENTED + // A region is an arbitrary clump of binary pixels + // The pixels that are on are part of the region + // drawing can be clipped to a region + // a possible efficient region implementation is a quadtree +} nk_gpu_dev_region_t; + +typedef union nk_gpu_dev_char { + uint16_t raw; + struct { + uint8_t symbol; // Assume classic PC north american code page (ASCII+Europe+graphics chars) + uint8_t attribute; // standard VGA attributes + }; +} nk_gpu_dev_char_t; + +typedef union nk_gpu_dev_pixel { + uint32_t raw; + // the channel offsets are given in a mode + uint8_t channels[4]; +} nk_gpu_dev_pixel_t; + +// 32 bit full color bitmap, same as screen +typedef struct nk_gpu_dev_bitmap { + uint32_t width; + uint32_t height; + nk_gpu_dev_pixel_t pixels[0]; // row major order, no interleaving +} nk_gpu_dev_bitmap_t; + + +typedef enum nk_gpu_dev_bit_blit_op { + NK_GPU_DEV_BIT_BLIT_OP_COPY, + NK_GPU_DEV_BIT_BLIT_OP_NOT, + NK_GPU_DEV_BIT_BLIT_OP_AND, + NK_GPU_DEV_BIT_BLIT_OP_OR, + NK_GPU_DEV_BIT_BLIT_OP_NAND, + NK_GPU_DEV_BIT_BLIT_OP_NOR, + NK_GPU_DEV_BIT_BLIT_OP_XOR, + NK_GPU_DEV_BIT_BLIT_OP_XNOR, + NK_GPU_DEV_BIT_BLIT_OP_PLUS, // arithmetic bit blit ops should use saturating arithmetic + NK_GPU_DEV_BIT_BLIT_OP_MINUS, + NK_GPU_DEV_BIT_BLIT_OP_MULTIPLY, + NK_GPU_DEV_BIT_BLIT_OP_DIVIDE, +} nk_gpu_dev_bit_blit_op_t; + +// simple bitmap fonts (256 symbols, assume ASCII) +// binary bitmap. 0=> empty, 1=>filled +typedef struct nk_gpu_dev_font { + uint32_t width; // size of character in pixels + uint32_t height; + uint8_t data[0]; // contains 256 character bitmaps, row major order +} nk_gpu_dev_font_t; + + +struct nk_gpu_dev_int { + // this must be first so it derives cleanly + // from nk_dev_int + struct nk_dev_int dev_int; + + // gpudev-specific interface - set to zero if not available + // an interface either succeeds (returns zero) or fails (returns -1) + + // discover the modes supported by the device + // modes = array of modes on entry, filled out on return + // num = size of array on entry, number of modes found on return + // + int (*get_available_modes)(void *state, nk_gpu_dev_video_mode_t modes[], uint32_t *num); + + // grab the current mode - useful in case you need to reset it later + int (*get_mode)(void *state, nk_gpu_dev_video_mode_t *mode); + + // set a video mode based on the modes discovered + // this will switch to the mode before returning + int (*set_mode)(void *state, nk_gpu_dev_video_mode_t *mode); + + // drawing commands + + // each of these is asynchronous - the implementation should start the operation + // but not necessarily finish it. In particular, nothing needs to be drawn + // until flush is invoked + + // flush - wait until all preceding drawing commands are visible by the user + int (*flush)(void *state); + + // text mode drawing commands + int (*text_set_char)(void *state, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_char_t *val); + // cursor location in text mode + int (*text_set_cursor)(void *state, nk_gpu_dev_coordinate_t *location, uint32_t flags); +#define NK_GPU_DEV_TEXT_CURSOR_ON 1 +#define NK_GPU_DEV_TEXT_CURSOR_BLINK 2 + + // graphics mode drawing commands + // confine drawing to this box or region + int (*graphics_set_clipping_box)(void *state, nk_gpu_dev_box_t *box); + int (*graphics_set_clipping_region)(void *state, nk_gpu_dev_region_t *region); + + // draw stuff + int (*graphics_draw_pixel)(void *state, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_pixel_t *pixel); + int (*graphics_draw_line)(void *state, nk_gpu_dev_coordinate_t *start, nk_gpu_dev_coordinate_t *end, nk_gpu_dev_pixel_t *pixel); + int (*graphics_draw_poly)(void *state, nk_gpu_dev_coordinate_t *coord_list, uint32_t count, nk_gpu_dev_pixel_t *pixel); + int (*graphics_fill_box_with_pixel)(void *state, nk_gpu_dev_box_t *box, nk_gpu_dev_pixel_t *pixel, nk_gpu_dev_bit_blit_op_t op); + int (*graphics_fill_box_with_bitmap)(void *state, nk_gpu_dev_box_t *box, nk_gpu_dev_bitmap_t *bitmap, nk_gpu_dev_bit_blit_op_t op); + int (*graphics_copy_box)(void *state, nk_gpu_dev_box_t *source_box, nk_gpu_dev_box_t *dest_box, nk_gpu_dev_bit_blit_op_t op); + int (*graphics_draw_text)(void *state, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_font_t *font, char *string); + + // mouse functions, if supported + int (*graphics_set_cursor_bitmap)(void *state, nk_gpu_dev_bitmap_t *bitmap); + // the location is the position of the top-left pixel in the bitmap + int (*graphics_set_cursor)(void *state, nk_gpu_dev_coordinate_t *location); + +}; + + +struct nk_gpu_dev; + +typedef struct nk_gpu_dev nk_gpu_dev_t; + +// +// device registry - called by device drivers +// +// +struct nk_gpu_dev * nk_gpu_dev_register(char *name, uint64_t flags, struct nk_gpu_dev_int *inter, void *state); +int nk_gpu_dev_unregister(struct nk_gpu_dev *); + + + +// +// Functions below are called by users of this abstraction +// + +// device find by name +struct nk_gpu_dev * nk_gpu_dev_find(char *name); + +// tell me what modes the device has +int nk_gpu_dev_get_available_modes(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t modes[], uint32_t *num); + +// give me a snapshot of the current mode (overwrites mode argument) +int nk_gpu_dev_get_mode(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t *mode); + + +// switch to a specific mode, ideally one returned grom get_available_modes +int nk_gpu_dev_set_mode(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t *mode); + + +// flush output to the user. drawing commands are allowed to be buffered by the device. +// it is not until you call this function that you know your output is on the screen +int nk_gpu_dev_flush(nk_gpu_dev_t *dev); + +// output a character in a text mode +int nk_gpu_dev_text_set_char(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_char_t *val); +// locate and configure the cursor in a text mode +// you probably want to use the "on" flag +int nk_gpu_dev_text_set_cursor(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, uint32_t flags); + +// graphics mode drawing commands + +// confine drawing to this subregion +// this requires that clipping be supported by the driver +int nk_gpu_dev_graphics_set_clipping_box(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box); +int nk_gpu_dev_graphics_set_clipping_region(nk_gpu_dev_t *dev, nk_gpu_dev_region_t *region); + +// draw stuff +// note that fills and copies are bit blits +int nk_gpu_dev_graphics_draw_pixel(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_pixel_t *pixel); +int nk_gpu_dev_graphics_draw_line(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *start, nk_gpu_dev_coordinate_t *end, nk_gpu_dev_pixel_t *pixel); +int nk_gpu_dev_graphics_draw_poly(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *coord_list, uint32_t count, nk_gpu_dev_pixel_t *pixel); +int nk_gpu_dev_graphics_fill_box_with_pixel(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box, nk_gpu_dev_pixel_t *pixel, nk_gpu_dev_bit_blit_op_t op); +int nk_gpu_dev_graphics_fill_box_with_bitmap(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box, nk_gpu_dev_bitmap_t *bitmap, nk_gpu_dev_bit_blit_op_t op); +int nk_gpu_dev_graphics_copy_box(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *source_box, nk_gpu_dev_box_t *dest_box, nk_gpu_dev_bit_blit_op_t op); +int nk_gpu_dev_graphics_draw_text(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_font_t *font, char *string); + +// confiure mouse cursor, if supported +int nk_gpu_dev_graphics_set_cursor_bitmap(nk_gpu_dev_t *dev, nk_gpu_dev_bitmap_t *bitmap); +int nk_gpu_dev_graphics_set_cursor(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location); + +// helper tools for drawing + +// bitmaps +nk_gpu_dev_bitmap_t *nk_gpu_dev_bitmap_create(uint32_t width, uint32_t height); +// for reading/writing pixels in the bitmap +#define NK_GPU_DEV_BITMAP_PIXEL(bitmap,x,y) ((bitmap)->pixels[(y)*((bitmap)->width)+(x)]) +void nk_gpu_dev_bitmap_destroy(nk_gpu_dev_bitmap_t *bitmap); + +// fonts +nk_gpu_dev_font_t *nk_gpu_dev_font_create(uint32_t width, uint32_t height); +#define NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y) ((ch)*(((font)->width) * ((font)->height)) + ((y)*((font)->width)) + (x)) +#define NK_GPU_DEV_FONT_BIT_GET(font,ch,x,y) (((font)->data[NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)/8] >> (NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)%8)) & 0x1) +#define NK_GPU_DEV_FONT_BIT_SET(font,ch,x,y) ((font)->data[NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)/8]) |= 0x1 << (NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)%8) +#define NK_GPU_DEV_FONT_BIT_RESET(font,ch,x,y) ((font)->data[NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)/8]) &= ~(0x1 << (NK_GPU_DEV_FONT_BIT_OFFSET(font,ch,x,y)%8)) +void nk_gpu_dev_font_destroy(nk_gpu_dev_font_t *font); + + + + +// called on BSP at startup and shutdown, respectively +int nk_gpu_dev_init(); +int nk_gpu_dev_deinit(); + +#endif + diff --git a/src/arch/gem5/init.c b/src/arch/gem5/init.c index ed496543d..155663726 100644 --- a/src/arch/gem5/init.c +++ b/src/arch/gem5/init.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,7 @@ init (unsigned long mbd, nk_char_dev_init(); nk_block_dev_init(); nk_net_dev_init(); + nk_gpu_dev_init(); nk_vc_print(NAUT_WELCOME); diff --git a/src/arch/x64/init.c b/src/arch/x64/init.c index ee9a0581b..9219fcaa3 100644 --- a/src/arch/x64/init.c +++ b/src/arch/x64/init.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -335,6 +336,7 @@ init (unsigned long mbd, nk_char_dev_init(); nk_block_dev_init(); nk_net_dev_init(); + nk_gpu_dev_init(); nk_vc_print(NAUT_WELCOME); diff --git a/src/nautilus/Makefile b/src/nautilus/Makefile index 1c6a41d55..597a2e7ad 100644 --- a/src/nautilus/Makefile +++ b/src/nautilus/Makefile @@ -46,6 +46,7 @@ obj-y += \ chardev.o \ blkdev.o \ netdev.o \ + gpudev.o \ fs.o \ loader.o \ shell.o \ diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c new file mode 100644 index 000000000..13baccdab --- /dev/null +++ b/src/nautilus/gpudev.c @@ -0,0 +1,246 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The Interweaving Project + * All rights reserved. + * + * Author: Peter Dinda + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + +#include +#include +#include + +#ifndef NAUT_CONFIG_DEBUG_GPUDEV +#undef DEBUG_PRINT +#define DEBUG_PRINT(fmt, args...) +#endif + +#define ERROR(fmt, args...) ERROR_PRINT("gpudev: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("gpudev: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("gpudev: " fmt, ##args) + + +struct nk_gpu_dev { + // must be first member + struct nk_dev dev; +}; + + + +#if 0 +static spinlock_t state_lock; + +#define STATE_LOCK_CONF uint8_t _state_lock_flags +#define STATE_LOCK() _state_lock_flags = spin_lock_irq_save(&state_lock) +#define STATE_UNLOCK() spin_unlock_irq_restore(&state_lock, _state_lock_flags); + +#endif + +int nk_gpu_dev_init() +{ + INFO("init\n"); + return 0; +} + +int nk_gpu_dev_deinit() +{ + INFO("deinit\n"); + return 0; +} + + +struct nk_gpu_dev * nk_gpu_dev_register(char *name, uint64_t flags, struct nk_gpu_dev_int *inter, void *state) +{ + INFO("register device %s\n",name); + return (struct nk_gpu_dev *) nk_dev_register(name,NK_DEV_GRAPHICS,flags,(struct nk_dev_int *)inter,state); +} + +int nk_gpu_dev_unregister(struct nk_gpu_dev *d) +{ + INFO("unregister device %s\n", d->dev.name); + return nk_dev_unregister((struct nk_dev *)d); +} + +struct nk_gpu_dev * nk_gpu_dev_find(char *name) +{ + DEBUG("find %s\n",name); + struct nk_dev *d = nk_dev_find(name); + if (d->type!=NK_DEV_GRAPHICS) { + DEBUG("%s not found\n",name); + return 0; + } else { + DEBUG("%s found\n",name); + return (struct nk_gpu_dev*) d; + } +} + + +#define BOILERPLATE(str,f,args...) \ + struct nk_dev *d = (struct nk_dev *)(&(dev->dev)); \ + struct nk_gpu_dev_int *di = (struct nk_gpu_dev_int *)(d->interface); \ + \ + DEBUG(str " of %s\n",d->name); \ + \ + if (di && di->f) { \ + return di->f(d->state,##args); \ + } else { \ + ERROR(str " not supported on %s\n", d->name); \ + return -1; \ + } + + + +int nk_gpu_dev_get_available_modes(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t modes[], uint32_t *num) +{ + BOILERPLATE("get available modes",get_available_modes,modes,num); +} + +int nk_gpu_dev_get_mode(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t *mode) +{ + BOILERPLATE("get mode",get_mode,mode); +} + +int nk_gpu_dev_set_mode(nk_gpu_dev_t *dev, nk_gpu_dev_video_mode_t *mode) +{ + BOILERPLATE("set mode",set_mode,mode); +} + +int nk_gpu_dev_flush(nk_gpu_dev_t *dev) +{ + BOILERPLATE("flush",flush); +} + +int nk_gpu_dev_text_set_char(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_char_t *val) +{ + BOILERPLATE("text set char",text_set_char,location,val); +} + +int nk_gpu_dev_text_set_cursor(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, uint32_t flags) +{ + BOILERPLATE("text set cursor",text_set_cursor,location,flags); +} + +int nk_gpu_dev_graphics_set_clipping_box(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box) +{ + BOILERPLATE("graphics set clipping box",graphics_set_clipping_box,box); +} + +int nk_gpu_dev_graphics_set_clipping_region(nk_gpu_dev_t *dev, nk_gpu_dev_region_t *region) +{ + BOILERPLATE("graphics set clipping region",graphics_set_clipping_region,region); +} + +int nk_gpu_dev_graphics_draw_pixel(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_pixel_t *pixel) +{ + BOILERPLATE("graphics draw pixel",graphics_draw_pixel,location,pixel); +} + +int nk_gpu_dev_graphics_draw_line(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *start, nk_gpu_dev_coordinate_t *end, nk_gpu_dev_pixel_t *pixel) +{ + BOILERPLATE("graphics draw line",graphics_draw_line,start,end,pixel); +} + +int nk_gpu_dev_graphics_draw_poly(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *coord_list, uint32_t count, nk_gpu_dev_pixel_t *pixel) +{ + BOILERPLATE("graphics draw poly",graphics_draw_poly,coord_list,count,pixel); +} + +int nk_gpu_dev_graphics_fill_box_with_pixel(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box, nk_gpu_dev_pixel_t *pixel, nk_gpu_dev_bit_blit_op_t op) +{ + BOILERPLATE("graphics fill box with pixel",graphics_fill_box_with_pixel,box,pixel,op); +} + +int nk_gpu_dev_graphics_fill_box_with_bitmap(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *box, nk_gpu_dev_bitmap_t *bitmap, nk_gpu_dev_bit_blit_op_t op) +{ + BOILERPLATE("graphics fill box with bitmap",graphics_fill_box_with_bitmap,box,bitmap,op); +} + +int nk_gpu_dev_graphics_copy_box(nk_gpu_dev_t *dev, nk_gpu_dev_box_t *source_box, nk_gpu_dev_box_t *dest_box, nk_gpu_dev_bit_blit_op_t op) +{ + BOILERPLATE("graphics copy box",graphics_copy_box,source_box,dest_box,op); +} + +int nk_gpu_dev_graphics_draw_text(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location, nk_gpu_dev_font_t *font, char *string) +{ + BOILERPLATE("graphics draw text",graphics_draw_text,location,font,string); +} + + +int nk_gpu_dev_graphics_set_cursor_bitmap(nk_gpu_dev_t *dev, nk_gpu_dev_bitmap_t *bitmap) +{ + BOILERPLATE("graphics set cursor bitmap",graphics_set_cursor_bitmap,bitmap); +} + +int nk_gpu_dev_graphics_set_cursor(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *location) +{ + BOILERPLATE("graphics set cursor",graphics_set_cursor, location); +} + + +nk_gpu_dev_bitmap_t *nk_gpu_dev_bitmap_create(uint32_t width, uint32_t height) +{ + uint64_t size = sizeof(nk_gpu_dev_bitmap_t)+sizeof(nk_gpu_dev_pixel_t)*width*height; + nk_gpu_dev_bitmap_t *b = malloc(size); + + if (!b) { + ERROR("failed to allocate bitmap\n"); + return 0; + } + + memset(b,0,size); + + b->width=width; + b->height=height; + + return b; +} + +void nk_gpu_dev_bitmap_destroy(nk_gpu_dev_bitmap_t *bitmap) +{ + free(bitmap); +} + +#define CEIL_DIV(x,y) ((x/y) + !!(x%y)) + +nk_gpu_dev_font_t *nk_gpu_dev_font_create(uint32_t width, uint32_t height) +{ + uint64_t numbits = 256 * width * height; + uint64_t size = sizeof(nk_gpu_dev_font_t)+CEIL_DIV(numbits,8); + nk_gpu_dev_font_t *f = malloc(size); + + if (!f) { + ERROR("failed to allocate font\n"); + return 0; + } + + memset(f,0,size); + + f->width=width; + f->height=height; + + return f; +} + +void nk_gpu_dev_font_destroy(nk_gpu_dev_font_t *font) +{ + free(font); +} + + + From e8683ac1f646e0ab4af4b2d9b3b711acd0864e97 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 7 Sep 2020 12:26:07 -0500 Subject: [PATCH 02/36] Cleanup of virtio_pci stuff suggested by clang warnings --- include/dev/virtio_pci.h | 2 +- src/dev/virtio_blk.c | 2 +- src/dev/virtio_net.c | 2 +- src/dev/virtio_pci.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/dev/virtio_pci.h b/include/dev/virtio_pci.h index a9b4d3e78..2099f0676 100644 --- a/include/dev/virtio_pci.h +++ b/include/dev/virtio_pci.h @@ -219,7 +219,7 @@ void virtio_pci_write_regb(struct virtio_pci_dev *dev, uint32_t offset, uint structures. Then access the fields in the structure using atomics. *****************************************************************/ -#if __GNUC__ < 5 +#if !defined(__clang__) && __GNUC__ < 5 #define __ATOMIC_SEQ_CST 0 #define __atomic_load_n(srcptr, cmodel) __sync_fetch_and_or(srcptr,0) #define __atomic_store_n(destptr, value, cmodel) ({ *(destptr) = value; __sync_synchronize(); }) diff --git a/src/dev/virtio_blk.c b/src/dev/virtio_blk.c index a311fe3de..db64145ce 100644 --- a/src/dev/virtio_blk.c +++ b/src/dev/virtio_blk.c @@ -543,7 +543,7 @@ int virtio_blk_init(struct virtio_pci_dev *dev) { char buf[DEV_NAME_LEN]; - if (!dev->model==VIRTIO_PCI_LEGACY_MODEL) { + if (!(dev->model==VIRTIO_PCI_LEGACY_MODEL)) { ERROR("currently only supported with legacy model\n"); return -1; } diff --git a/src/dev/virtio_net.c b/src/dev/virtio_net.c index 56617cfec..ce63a7834 100644 --- a/src/dev/virtio_net.c +++ b/src/dev/virtio_net.c @@ -547,7 +547,7 @@ int virtio_net_init(struct virtio_pci_dev *dev) { char buf[DEV_NAME_LEN]; - if (!dev->model==VIRTIO_PCI_LEGACY_MODEL) { + if (!(dev->model==VIRTIO_PCI_LEGACY_MODEL)) { ERROR("currently only supported with legacy model\n"); return -1; } diff --git a/src/dev/virtio_pci.c b/src/dev/virtio_pci.c index 099ac0eaa..9a715f46d 100644 --- a/src/dev/virtio_pci.c +++ b/src/dev/virtio_pci.c @@ -701,9 +701,9 @@ static int virtqueue_init_modern(struct virtio_pci_dev *dev) DEBUG("virtq used at %p\n", dev->virtq[i].vq.used); // tell the device where our virtqueue is - virtio_pci_atomic_store(&dev->common->queue_desc, dev->virtq[i].vq.desc); - virtio_pci_atomic_store(&dev->common->queue_driver, dev->virtq[i].vq.avail); - virtio_pci_atomic_store(&dev->common->queue_device, dev->virtq[i].vq.used); + virtio_pci_atomic_store(&dev->common->queue_desc, (addr_t)dev->virtq[i].vq.desc); + virtio_pci_atomic_store(&dev->common->queue_driver, (addr_t)dev->virtq[i].vq.avail); + virtio_pci_atomic_store(&dev->common->queue_device, (addr_t)dev->virtq[i].vq.used); if (dev->itype==VIRTIO_PCI_MSI_X_INTERRUPT) { From 3d3bd099bcb255d7a60581774dd185c869a3afaf Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 7 Sep 2020 13:52:14 -0500 Subject: [PATCH 03/36] Add test routines to gpudev, plus other cleanup --- include/nautilus/gpudev.h | 13 ++- src/nautilus/gpudev.c | 176 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 1 deletion(-) diff --git a/include/nautilus/gpudev.h b/include/nautilus/gpudev.h index 35a0f12a8..f3577864a 100644 --- a/include/nautilus/gpudev.h +++ b/include/nautilus/gpudev.h @@ -102,9 +102,10 @@ typedef union nk_gpu_dev_char { typedef union nk_gpu_dev_pixel { uint32_t raw; // the channel offsets are given in a mode - uint8_t channels[4]; + uint8_t channel[4]; } nk_gpu_dev_pixel_t; + // 32 bit full color bitmap, same as screen typedef struct nk_gpu_dev_bitmap { uint32_t width; @@ -260,6 +261,16 @@ int nk_gpu_dev_graphics_set_cursor(nk_gpu_dev_t *dev, nk_gpu_dev_coordinate_t *l // helper tools for drawing +// pixels +#define NK_GPU_DEV_PIXEL_SET_RGBA(m,p,r,g,b,a) \ + (p)->channel[(m)->channel_offset[NK_GPU_DEV_CHANNEL_OFFSET_RED]]=(r); \ + (p)->channel[(m)->channel_offset[NK_GPU_DEV_CHANNEL_OFFSET_GREEN]]=(g); \ + (p)->channel[(m)->channel_offset[NK_GPU_DEV_CHANNEL_OFFSET_BLUE]]=(b); \ + (p)->channel[(m)->channel_offset[NK_GPU_DEV_CHANNEL_OFFSET_ALPHA]]=(a); + +// chars +#define NK_GPU_DEV_CHAR_SET_SYM_ATTR(d,c,s,a) c->symbol = s; c->attribute = a + // bitmaps nk_gpu_dev_bitmap_t *nk_gpu_dev_bitmap_create(uint32_t width, uint32_t height); // for reading/writing pixels in the bitmap diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c index 13baccdab..7c838296b 100644 --- a/src/nautilus/gpudev.c +++ b/src/nautilus/gpudev.c @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #ifndef NAUT_CONFIG_DEBUG_GPUDEV #undef DEBUG_PRINT @@ -243,4 +246,177 @@ void nk_gpu_dev_font_destroy(nk_gpu_dev_font_t *font) } +#define MAX_MODES 64 + +#define PRINT_MODE(spec, count, m) \ + nk_vc_printf(spec "mode %d: %s %u by %u, offsets %u %u %u %u, flags %016lx %s %s %s, mouse %u by %u\n", \ + (count), \ + (m)->type==NK_GPU_DEV_MODE_TYPE_TEXT ? "text" : \ + (m)->type==NK_GPU_DEV_MODE_TYPE_GRAPHICS_2D ? "graphics (2d)" : "UNKNOWN", \ + (m)->width, (m)->height, \ + (m)->channel_offset[0], (m)->channel_offset[1], (m)->channel_offset[2], (m)->channel_offset[3], \ + (m)->flags, \ + (m)->flags & NK_GPU_DEV_HAS_CLIPPING ? "clipping" : "", \ + (m)->flags & NK_GPU_DEV_HAS_CLIPPING_REGION ? "clipping_region" : "", \ + (m)->flags & NK_GPU_DEV_HAS_MOUSE_CURSOR ? "mouse_cursor" : "", \ + (m)->mouse_cursor_width, (m)->mouse_cursor_height) + + +static int handle_gputest (char * buf, void * priv) +{ + char name[32]; + struct nk_gpu_dev *d; + nk_gpu_dev_video_mode_t modes[MAX_MODES], prevmode, *curmode; + uint32_t nummodes=MAX_MODES; + + if ((sscanf(buf,"gputest %s",name)!=1)) { + nk_vc_printf("gputest devname\n",buf); + return -1; + } + + if (!(d=nk_gpu_dev_find(name))) { + nk_vc_printf("Can't find %s\n",name); + return -1; + } + + if (nk_gpu_dev_get_mode(d,&prevmode)) { + nk_vc_printf("Can't get mode\n"); + return -1; + } + + PRINT_MODE("current ",0,&prevmode); + + if (nk_gpu_dev_get_available_modes(d,modes,&nummodes)) { + nk_vc_printf("Can't get available modes from %s\n",name); + return -1; + } + + uint32_t i, sel=-1; + + nk_vc_printf("Available modes are\n"); + for (i=0;iwidth; + box.height = curmode->height; + + NK_GPU_DEV_PIXEL_SET_RGBA(curmode,&pixel,0,0,0,0); + + CHECK(nk_gpu_dev_graphics_fill_box_with_pixel(d, + &box, + &pixel, + NK_GPU_DEV_BIT_BLIT_OP_COPY)); + + CHECK(nk_gpu_dev_flush(d)); + + nk_vc_printf("cleared screen to black\n"); + + // draw some random colored boxes with xor blits + for (i=0;i<100;i++) { + box.x = rand() % curmode->width; + box.y = rand() % curmode->height; + box.width = rand() % curmode->width; + box.height = rand() % curmode->height; + + NK_GPU_DEV_PIXEL_SET_RGBA(curmode,&pixel,rand()%256,rand()%256,rand()%256,0); + + CHECK(nk_gpu_dev_graphics_fill_box_with_pixel(d, + &box, + &pixel, + NK_GPU_DEV_BIT_BLIT_OP_XOR)); + + } + + CHECK(nk_gpu_dev_flush(d)); + + nk_vc_printf("drew boxes\n"); + + nk_sleep(5000000000UL); // five seconds + + + // clear screen purple + + box.x = box.y = 0; + box.width = curmode->width; + box.height = curmode->height; + + NK_GPU_DEV_PIXEL_SET_RGBA(curmode,&pixel,0x6a,0x0d,0xad,0); + + CHECK(nk_gpu_dev_graphics_fill_box_with_pixel(d, + &box, + &pixel, + NK_GPU_DEV_BIT_BLIT_OP_COPY)); + + CHECK(nk_gpu_dev_flush(d)); + + nk_vc_printf("cleared screen to purple\n"); + + nk_gpu_dev_coordinate_t start, end; + + // draw some random colored lines + for (i=0;i<100;i++) { + start.x = rand() % curmode->width; + start.y = rand() % curmode->height; + end.x = rand() % curmode->width; + end.y = rand() % curmode->height; + + NK_GPU_DEV_PIXEL_SET_RGBA(curmode,&pixel,rand()%256,rand()%256,rand()%256,0); + + CHECK(nk_gpu_dev_graphics_draw_line(d,&start,&end,&pixel)); + + } + + CHECK(nk_gpu_dev_flush(d)); + + nk_vc_printf("drew lines\n"); + + nk_sleep(5000000000UL); // five seconds + + nk_vc_printf("reseting to original mode\n"); + + if (nk_gpu_dev_set_mode(d,&prevmode)) { + nk_vc_printf("Cannot switch back to previous mode\n"); + return -1; + } + + nk_vc_printf("Basic gputest complete\n"); + + return 0; +} + + +static struct shell_cmd_impl gputest_impl = { + .cmd = "gputest", + .help_str = "gputest dev", + .handler = handle_gputest, +}; +nk_register_shell_cmd(gputest_impl); + From d3f0f06056ac9411faaae11051b1ffa4baae8803 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 7 Sep 2020 15:37:43 -0500 Subject: [PATCH 04/36] More cleanup of gpudev interface --- include/nautilus/gpudev.h | 6 +++++- src/nautilus/dev.c | 3 ++- src/nautilus/gpudev.c | 5 ----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/nautilus/gpudev.h b/include/nautilus/gpudev.h index f3577864a..ce4cf923f 100644 --- a/include/nautilus/gpudev.h +++ b/include/nautilus/gpudev.h @@ -197,7 +197,11 @@ struct nk_gpu_dev_int { }; -struct nk_gpu_dev; +struct nk_gpu_dev { + // must be first member + struct nk_dev dev; +}; + typedef struct nk_gpu_dev nk_gpu_dev_t; diff --git a/src/nautilus/dev.c b/src/nautilus/dev.c index e70e1d4f4..96887e754 100644 --- a/src/nautilus/dev.c +++ b/src/nautilus/dev.c @@ -172,7 +172,8 @@ void nk_dev_dump_devices() d->type==NK_DEV_INTR ? "interrupt" : d->type==NK_DEV_CHAR ? "char" : d->type==NK_DEV_BLK ? "block" : - d->type==NK_DEV_NET ? "net" : "unknown", + d->type==NK_DEV_NET ? "net" : + d->type==NK_DEV_GRAPHICS ? "graphics" : "unknown", d->flags, d->interface, d->state); diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c index 7c838296b..21166d278 100644 --- a/src/nautilus/gpudev.c +++ b/src/nautilus/gpudev.c @@ -39,11 +39,6 @@ #define INFO(fmt, args...) INFO_PRINT("gpudev: " fmt, ##args) -struct nk_gpu_dev { - // must be first member - struct nk_dev dev; -}; - #if 0 From aacacb21e8b6b5d2032b7434da2b53a05570b3da Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Fri, 11 Sep 2020 15:00:48 -0500 Subject: [PATCH 05/36] More tests in gpudev interface --- include/nautilus/gpudev.h | 2 +- src/nautilus/gpudev.c | 44 +++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/include/nautilus/gpudev.h b/include/nautilus/gpudev.h index ce4cf923f..271dafcd1 100644 --- a/include/nautilus/gpudev.h +++ b/include/nautilus/gpudev.h @@ -115,7 +115,7 @@ typedef struct nk_gpu_dev_bitmap { typedef enum nk_gpu_dev_bit_blit_op { - NK_GPU_DEV_BIT_BLIT_OP_COPY, + NK_GPU_DEV_BIT_BLIT_OP_COPY=0, NK_GPU_DEV_BIT_BLIT_OP_NOT, NK_GPU_DEV_BIT_BLIT_OP_AND, NK_GPU_DEV_BIT_BLIT_OP_OR, diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c index 21166d278..bf7e9e0b2 100644 --- a/src/nautilus/gpudev.c +++ b/src/nautilus/gpudev.c @@ -334,19 +334,19 @@ static int handle_gputest (char * buf, void * priv) nk_vc_printf("cleared screen to black\n"); // draw some random colored boxes with xor blits - for (i=0;i<100;i++) { + for (i=0;i<1024;i++) { box.x = rand() % curmode->width; box.y = rand() % curmode->height; - box.width = rand() % curmode->width; - box.height = rand() % curmode->height; + box.width = rand() % (curmode->width - box.x); + box.height = rand() % (curmode->height - box.y); NK_GPU_DEV_PIXEL_SET_RGBA(curmode,&pixel,rand()%256,rand()%256,rand()%256,0); CHECK(nk_gpu_dev_graphics_fill_box_with_pixel(d, &box, &pixel, - NK_GPU_DEV_BIT_BLIT_OP_XOR)); - + rand() % (NK_GPU_DEV_BIT_BLIT_OP_DIVIDE+1))); + CHECK(nk_gpu_dev_flush(d)); } CHECK(nk_gpu_dev_flush(d)); @@ -376,7 +376,7 @@ static int handle_gputest (char * buf, void * priv) nk_gpu_dev_coordinate_t start, end; // draw some random colored lines - for (i=0;i<100;i++) { + for (i=0;i<1024;i++) { start.x = rand() % curmode->width; start.y = rand() % curmode->height; end.x = rand() % curmode->width; @@ -386,6 +386,7 @@ static int handle_gputest (char * buf, void * priv) CHECK(nk_gpu_dev_graphics_draw_line(d,&start,&end,&pixel)); + CHECK(nk_gpu_dev_flush(d)); } CHECK(nk_gpu_dev_flush(d)); @@ -394,8 +395,39 @@ static int handle_gputest (char * buf, void * priv) nk_sleep(5000000000UL); // five seconds + + nk_gpu_dev_box_t src, dst; + + // move box of pixels around the screen + for (i=0;i<1024;i++) { + src.x = rand() % curmode->width; + src.y = rand() % curmode->height; + src.width = rand() % (curmode->width - box.x); + src.height = rand() % (curmode->height - box.y); + dst.x = rand() % curmode->width; + dst.y = rand() % curmode->height; + dst.width = src.width; + dst.height = src.height; + + CHECK(nk_gpu_dev_graphics_copy_box(d, + &src, + &dst, + rand() % (NK_GPU_DEV_BIT_BLIT_OP_DIVIDE+1))); + CHECK(nk_gpu_dev_flush(d)); + } + + CHECK(nk_gpu_dev_flush(d)); + + nk_vc_printf("drew boxes\n"); + + nk_sleep(5000000000UL); // five seconds + + nk_vc_printf("reseting to original mode\n"); + + + if (nk_gpu_dev_set_mode(d,&prevmode)) { nk_vc_printf("Cannot switch back to previous mode\n"); return -1; From 35bb63fd4813fc5ac97732893a778fd4f6d8181a Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sun, 13 Sep 2020 19:04:38 -0500 Subject: [PATCH 06/36] Minor gpudev tweak --- src/nautilus/gpudev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c index bf7e9e0b2..d1aec584e 100644 --- a/src/nautilus/gpudev.c +++ b/src/nautilus/gpudev.c @@ -418,7 +418,7 @@ static int handle_gputest (char * buf, void * priv) CHECK(nk_gpu_dev_flush(d)); - nk_vc_printf("drew boxes\n"); + nk_vc_printf("moved boxes\n"); nk_sleep(5000000000UL); // five seconds From d4afbd68cadeb816737a60550cba4d43a143ae9c Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Thu, 10 Sep 2020 20:11:04 -0500 Subject: [PATCH 07/36] More gpu dev interface cleanup --- src/nautilus/gpudev.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/nautilus/gpudev.c b/src/nautilus/gpudev.c index d1aec584e..444e5c04a 100644 --- a/src/nautilus/gpudev.c +++ b/src/nautilus/gpudev.c @@ -244,16 +244,13 @@ void nk_gpu_dev_font_destroy(nk_gpu_dev_font_t *font) #define MAX_MODES 64 #define PRINT_MODE(spec, count, m) \ - nk_vc_printf(spec "mode %d: %s %u by %u, offsets %u %u %u %u, flags %016lx %s %s %s, mouse %u by %u\n", \ + nk_vc_printf(spec "mode %d: %s %u by %u, offsets %u %u %u %u, flags 0x%lx, mouse %u by %u\n", \ (count), \ (m)->type==NK_GPU_DEV_MODE_TYPE_TEXT ? "text" : \ (m)->type==NK_GPU_DEV_MODE_TYPE_GRAPHICS_2D ? "graphics (2d)" : "UNKNOWN", \ (m)->width, (m)->height, \ (m)->channel_offset[0], (m)->channel_offset[1], (m)->channel_offset[2], (m)->channel_offset[3], \ (m)->flags, \ - (m)->flags & NK_GPU_DEV_HAS_CLIPPING ? "clipping" : "", \ - (m)->flags & NK_GPU_DEV_HAS_CLIPPING_REGION ? "clipping_region" : "", \ - (m)->flags & NK_GPU_DEV_HAS_MOUSE_CURSOR ? "mouse_cursor" : "", \ (m)->mouse_cursor_width, (m)->mouse_cursor_height) @@ -288,7 +285,7 @@ static int handle_gputest (char * buf, void * priv) uint32_t i, sel=-1; - nk_vc_printf("Available modes are\n"); + nk_vc_printf("Available modes are:\n"); for (i=0;i Date: Mon, 21 Dec 2020 15:41:59 -0600 Subject: [PATCH 08/36] Update testing config for gpudev --- configs/testing/default.config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/testing/default.config b/configs/testing/default.config index 6912f89c9..938f5716f 100644 --- a/configs/testing/default.config +++ b/configs/testing/default.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Wed Jul 29 15:52:51 2020 +# Mon Dec 21 15:41:45 2020 # # @@ -86,8 +86,8 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # Optimizations # NAUT_CONFIG_FPU_SAVE=y -# NAUT_CONFIG_KICK_SCHEDULE is not set -# NAUT_CONFIG_HALT_WHILE_IDLE is not set +NAUT_CONFIG_KICK_SCHEDULE=y +NAUT_CONFIG_HALT_WHILE_IDLE=y # NAUT_CONFIG_THREAD_OPTIMIZE is not set # From 324dd473c2362f5458da8469e6bc0d4cac929d4a Mon Sep 17 00:00:00 2001 From: Drew Kersnar Date: Fri, 25 Sep 2020 01:03:24 -0500 Subject: [PATCH 09/36] Monitor fix - printing more registers --- src/nautilus/monitor.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/nautilus/monitor.c b/src/nautilus/monitor.c index 7ced0e430..6c6b98c39 100644 --- a/src/nautilus/monitor.c +++ b/src/nautilus/monitor.c @@ -845,7 +845,9 @@ static int execute_disable(char command[]) disable(dreg_num); - vga_puts("register 0 disabled"); + DS("register "); + DS(potential_num); + DS(" disabled \n"); return 0; } @@ -1045,7 +1047,8 @@ monitor_print_regs (struct nk_regs * r) PRINT3(rip, " ", rflags, "", rbp, " "); PRINT3(rsp, " ", rax, " ", rbx, " "); - PRINT3(rsi, " ", r8, " ", r9, " "); + PRINT3(rcx, " ", rdx, " ", rsi, " "); + PRINT3(rdi, " ", r8, " ", r9, " "); PRINT3(r10, " ", r11, " ", r12, " "); PRINT3(r13, " ", r14, " ", r15, " "); @@ -1067,7 +1070,7 @@ monitor_print_regs (struct nk_regs * r) asm volatile("movq %%cr8, %0": "=r" (cr8)); PRINT3CR(cr0, " ", cr2, " ", cr3, " "); - PRINT2CR(cr4, " ", cr8, " "); + PRINT3CR(cr4, " ", cr8, " ", efer, " "); } #ifdef NAUT_CONFIG_PROVENANCE @@ -1105,7 +1108,7 @@ static void dump_call(void) goto done; \ } \ DHQ(((uint64_t)__builtin_return_address(k))); DS(": "); \ - PROV((uint64_t)__builtin_return_address(k)); \ + PROV((uint64_t)__builtin_return_address(k)); DS("\n"); \ BT(0); BT(1); From 4327082344847f47a17fc4330c1709eb0f845a85 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 13 Apr 2020 13:46:14 -0500 Subject: [PATCH 10/36] configs and readme for cs446 spring 2020 --- README.cs446-s20 | 36 ++++++ configs/cs446-s20-example-config | 201 +++++++++++++++++++++++++++++++ run | 1 + 3 files changed, 238 insertions(+) create mode 100644 README.cs446-s20 create mode 100644 configs/cs446-s20-example-config create mode 100755 run diff --git a/README.cs446-s20 b/README.cs446-s20 new file mode 100644 index 000000000..e122f6a7f --- /dev/null +++ b/README.cs446-s20 @@ -0,0 +1,36 @@ +To set up: + +You should be on the cs446-s20 branch to start + +$ cp configs/cs446-s20-example-config .config + +$ make isoimage + +$ ./run + + +CHANGING CONFIGURATION + +$ make menuconfig + + +MONITOR + +to enter the monitor, press F9 + +The monitor will also be entered on any unhandled +exception, interrupt, panic, hang, etc. + +The watchdog timer is active and will bark after one +second of seeing no interrupts + +GDB + +to attach a debugger: + +$ ./run & + +$ gdb nautilus.bin +(gdb) target remote localhost:1234 + + diff --git a/configs/cs446-s20-example-config b/configs/cs446-s20-example-config new file mode 100644 index 000000000..f36e9c4ad --- /dev/null +++ b/configs/cs446-s20-example-config @@ -0,0 +1,201 @@ +# +# Automatically generated make config: don't edit +#Nautilus: +# Mon Apr 13 13:31:21 2020 +# + +# +# Platform +# +NAUT_CONFIG_X86_64_HOST=y +# NAUT_CONFIG_XEON_PHI is not set +# NAUT_CONFIG_HVM_HRT is not set +# NAUT_CONFIG_GEM5 is not set +NAUT_CONFIG_MAX_CPUS=256 +NAUT_CONFIG_MAX_IOAPICS=16 +# NAUT_CONFIG_PALACIOS is not set + +# +# Build +# +NAUT_CONFIG_USE_NAUT_BUILTINS=y +NAUT_CONFIG_CXX_SUPPORT=y +# NAUT_CONFIG_RUST_SUPPORT is not set +NAUT_CONFIG_USE_GCC=y +# NAUT_CONFIG_USE_CLANG is not set +# NAUT_CONFIG_USE_WLLVM is not set +NAUT_CONFIG_COMPILER_PREFIX="" +NAUT_CONFIG_COMPILER_SUFFIX="" +NAUT_CONFIG_TOOLCHAIN_ROOT="" + +# +# Configuration +# +NAUT_CONFIG_MAX_THREADS=1024 +# NAUT_CONFIG_RUN_TESTS_AT_BOOT is not set +NAUT_CONFIG_THREAD_EXIT_KEYCODE=196 +# NAUT_CONFIG_USE_TICKETLOCKS is not set +# NAUT_CONFIG_PARTITION_SUPPORT is not set +NAUT_CONFIG_VIRTUAL_CONSOLE_DISPLAY_NAME=y +# NAUT_CONFIG_VIRTUAL_CONSOLE_CHARDEV_CONSOLE is not set +NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR=y +NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR_ALL=y + +# +# Scheduler Options +# +NAUT_CONFIG_UTILIZATION_LIMIT=99 +NAUT_CONFIG_SPORADIC_RESERVATION=10 +NAUT_CONFIG_APERIODIC_RESERVATION=10 +NAUT_CONFIG_HZ=10 +NAUT_CONFIG_INTERRUPT_REINJECTION_DELAY_NS=10000 +# NAUT_CONFIG_AUTO_REAP is not set +# NAUT_CONFIG_WORK_STEALING is not set +# NAUT_CONFIG_TASK_IN_SCHED is not set +# NAUT_CONFIG_TASK_THREAD is not set +# NAUT_CONFIG_TASK_IN_IDLE is not set +# NAUT_CONFIG_INTERRUPT_THREAD is not set +# NAUT_CONFIG_APERIODIC_DYNAMIC_QUANTUM is not set +# NAUT_CONFIG_APERIODIC_DYNAMIC_LIFETIME is not set +# NAUT_CONFIG_APERIODIC_LOTTERY is not set +NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y + +# +# Fiber Options +# +# NAUT_CONFIG_FIBER_ENABLE is not set +# NAUT_CONFIG_REAL_MODE_INTERFACE is not set + +# +# Watchdog Options +# +NAUT_CONFIG_WATCHDOG=y +NAUT_CONFIG_WATCHDOG_DEFAULT_TIME_MS=1000 +# NAUT_CONFIG_DEBUG_WATCHDOG is not set +# NAUT_CONFIG_ISOCORE is not set +# NAUT_CONFIG_CACHEPART is not set + +# +# Garbage Collection Options +# +# NAUT_CONFIG_GARBAGE_COLLECTION is not set + +# +# FPU Options +# +# NAUT_CONFIG_XSAVE_SUPPORT is not set + +# +# Optimizations +# +NAUT_CONFIG_FPU_SAVE=y +NAUT_CONFIG_KICK_SCHEDULE=y +NAUT_CONFIG_HALT_WHILE_IDLE=y +# NAUT_CONFIG_THREAD_OPTIMIZE is not set + +# +# Debugging +# +NAUT_CONFIG_DEBUG_INFO=y +NAUT_CONFIG_DEBUG_PRINTS=y +NAUT_CONFIG_ENABLE_ASSERTS=y +# NAUT_CONFIG_PROFILE is not set +# NAUT_CONFIG_SILENCE_UNDEF_ERR is not set +# NAUT_CONFIG_ENABLE_STACK_CHECK is not set +# NAUT_CONFIG_ENABLE_REMOTE_DEBUGGING is not set +NAUT_CONFIG_ENABLE_MONITOR=y +# NAUT_CONFIG_DEBUG_PAGING is not set +# NAUT_CONFIG_DEBUG_BOOTMEM is not set +# NAUT_CONFIG_DEBUG_CMDLINE is not set +# NAUT_CONFIG_DEBUG_TESTS is not set +# NAUT_CONFIG_DEBUG_BUDDY is not set +# NAUT_CONFIG_DEBUG_KMEM is not set +# NAUT_CONFIG_DEBUG_FPU is not set +# NAUT_CONFIG_DEBUG_SMP is not set +# NAUT_CONFIG_DEBUG_SHELL is not set +# NAUT_CONFIG_DEBUG_SFI is not set +# NAUT_CONFIG_DEBUG_CXX is not set +# NAUT_CONFIG_DEBUG_THREADS is not set +# NAUT_CONFIG_DEBUG_TASKS is not set +# NAUT_CONFIG_DEBUG_WAITQUEUES is not set +# NAUT_CONFIG_DEBUG_FUTURES is not set +# NAUT_CONFIG_DEBUG_GROUP is not set +# NAUT_CONFIG_DEBUG_SCHED is not set +# NAUT_CONFIG_DEBUG_GROUP_SCHED is not set +# NAUT_CONFIG_DEBUG_TIMERS is not set +# NAUT_CONFIG_DEBUG_SEMAPHORES is not set +# NAUT_CONFIG_DEBUG_MSG_QUEUES is not set +# NAUT_CONFIG_DEBUG_SYNCH is not set +# NAUT_CONFIG_DEBUG_BARRIER is not set +# NAUT_CONFIG_DEBUG_NUMA is not set +# NAUT_CONFIG_DEBUG_VIRTUAL_CONSOLE is not set +# NAUT_CONFIG_DEBUG_DEV is not set +# NAUT_CONFIG_DEBUG_FILESYSTEM is not set +# NAUT_CONFIG_DEBUG_LOADER is not set +# NAUT_CONFIG_DEBUG_LINKER is not set +# NAUT_CONFIG_DEBUG_PMC is not set + +# +# Address Spaces +# +# NAUT_CONFIG_ASPACES is not set + +# +# Runtimes +# +# NAUT_CONFIG_LEGION_RT is not set +# NAUT_CONFIG_NDPC_RT is not set +# NAUT_CONFIG_NESL_RT is not set +# NAUT_CONFIG_OPENMP_RT is not set +NAUT_CONFIG_RACKET_RT=y + +# +# Devices +# + +# +# Serial Options +# +NAUT_CONFIG_SERIAL_REDIRECT=y +NAUT_CONFIG_SERIAL_REDIRECT_PORT=1 +# NAUT_CONFIG_APIC_FORCE_XAPIC_MODE is not set +# NAUT_CONFIG_APIC_TIMER_CALIBRATE_INDEPENDENTLY is not set +# NAUT_CONFIG_DEBUG_APIC is not set +# NAUT_CONFIG_DEBUG_IOAPIC is not set +# NAUT_CONFIG_DEBUG_PCI is not set +NAUT_CONFIG_DISABLE_PS2_MOUSE=y +# NAUT_CONFIG_DEBUG_PS2 is not set +# NAUT_CONFIG_GPIO is not set +# NAUT_CONFIG_DEBUG_PIT is not set +# NAUT_CONFIG_HPET is not set +NAUT_CONFIG_VIRTIO_PCI=y +# NAUT_CONFIG_DEBUG_VIRTIO_PCI is not set +NAUT_CONFIG_VIRTIO_NET=y +# NAUT_CONFIG_DEBUG_VIRTIO_NET is not set +NAUT_CONFIG_VIRTIO_BLK=y +# NAUT_CONFIG_DEBUG_VIRTIO_BLK is not set +NAUT_CONFIG_E1000_PCI=y +# NAUT_CONFIG_DEBUG_E1000_PCI is not set +NAUT_CONFIG_E1000E_PCI=y +# NAUT_CONFIG_DEBUG_E1000E_PCI is not set +# NAUT_CONFIG_MLX3_PCI is not set +# NAUT_CONFIG_RAMDISK is not set +NAUT_CONFIG_ATA=y +# NAUT_CONFIG_DEBUG_ATA is not set + +# +# Filesystems +# +# NAUT_CONFIG_EXT2_FILESYSTEM_DRIVER is not set +# NAUT_CONFIG_FAT32_FILESYSTEM_DRIVER is not set + +# +# Networking +# +# NAUT_CONFIG_NET_ETHERNET is not set +# NAUT_CONFIG_NET_COLLECTIVE is not set + +# +# Languages +# +# NAUT_CONFIG_LOAD_LUA is not set diff --git a/run b/run new file mode 100755 index 000000000..7268d49fd --- /dev/null +++ b/run @@ -0,0 +1 @@ +make -j isoimage && qemu-system-x86_64 -smp 1 -m 2048 -vga std -serial stdio -cdrom nautilus.iso -gdb tcp::1234 From 28afcd746f759fb2fcc103bc87a195daff0e9dc3 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 4 May 2020 13:22:12 -0500 Subject: [PATCH 11/36] Add initial glue code for omp (kmp) --- .config | 198 ++++++++++++++++++++++++++++++++++++ ENV | 1 + Kconfig | 8 +- Makefile | 4 + include/rt/openmp/omp.h | 1 + include/rt/openmp/omp/omp.h | 107 +++++++++++++++++++ src/nautilus/naut_string.c | 18 ++++ src/rt/openmp/omp/Makefile | 2 + src/rt/openmp/omp/glue.c | 1 + src/rt/openmp/omp/omp.c | 48 +++++++++ src/test/openmp/Makefile | 8 +- 11 files changed, 392 insertions(+), 4 deletions(-) create mode 100644 .config create mode 100644 ENV create mode 120000 include/rt/openmp/omp.h create mode 100644 include/rt/openmp/omp/omp.h create mode 100644 src/rt/openmp/omp/glue.c create mode 100644 src/rt/openmp/omp/omp.c diff --git a/.config b/.config new file mode 100644 index 000000000..29801c413 --- /dev/null +++ b/.config @@ -0,0 +1,198 @@ +# +# Automatically generated make config: don't edit +#Nautilus: +# Sun May 3 17:46:19 2020 +# + +# +# Platform +# +NAUT_CONFIG_X86_64_HOST=y +# NAUT_CONFIG_XEON_PHI is not set +# NAUT_CONFIG_HVM_HRT is not set +# NAUT_CONFIG_GEM5 is not set +NAUT_CONFIG_MAX_CPUS=256 +NAUT_CONFIG_MAX_IOAPICS=16 +# NAUT_CONFIG_PALACIOS is not set + +# +# Build +# +NAUT_CONFIG_USE_NAUT_BUILTINS=y +NAUT_CONFIG_CXX_SUPPORT=y +# NAUT_CONFIG_RUST_SUPPORT is not set +# NAUT_CONFIG_USE_GCC is not set +NAUT_CONFIG_USE_CLANG=y +# NAUT_CONFIG_USE_WLLVM is not set +NAUT_CONFIG_COMPILER_PREFIX="" +NAUT_CONFIG_COMPILER_SUFFIX="" +NAUT_CONFIG_TOOLCHAIN_ROOT="" + +# +# Configuration +# +NAUT_CONFIG_MAX_THREADS=1024 +# NAUT_CONFIG_RUN_TESTS_AT_BOOT is not set +NAUT_CONFIG_THREAD_EXIT_KEYCODE=196 +# NAUT_CONFIG_USE_TICKETLOCKS is not set +# NAUT_CONFIG_PARTITION_SUPPORT is not set +NAUT_CONFIG_VIRTUAL_CONSOLE_DISPLAY_NAME=y +# NAUT_CONFIG_VIRTUAL_CONSOLE_CHARDEV_CONSOLE is not set +NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR=y +NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR_ALL=y + +# +# Scheduler Options +# +NAUT_CONFIG_UTILIZATION_LIMIT=99 +NAUT_CONFIG_SPORADIC_RESERVATION=10 +NAUT_CONFIG_APERIODIC_RESERVATION=10 +NAUT_CONFIG_HZ=10 +NAUT_CONFIG_INTERRUPT_REINJECTION_DELAY_NS=10000 +# NAUT_CONFIG_AUTO_REAP is not set +# NAUT_CONFIG_WORK_STEALING is not set +# NAUT_CONFIG_TASK_IN_SCHED is not set +# NAUT_CONFIG_TASK_THREAD is not set +# NAUT_CONFIG_TASK_IN_IDLE is not set +# NAUT_CONFIG_INTERRUPT_THREAD is not set +# NAUT_CONFIG_APERIODIC_DYNAMIC_QUANTUM is not set +# NAUT_CONFIG_APERIODIC_DYNAMIC_LIFETIME is not set +# NAUT_CONFIG_APERIODIC_LOTTERY is not set +NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y + +# +# Fiber Options +# +# NAUT_CONFIG_FIBER_ENABLE is not set +# NAUT_CONFIG_REAL_MODE_INTERFACE is not set + +# +# Watchdog Options +# +NAUT_CONFIG_WATCHDOG=y +NAUT_CONFIG_WATCHDOG_DEFAULT_TIME_MS=1000 +# NAUT_CONFIG_DEBUG_WATCHDOG is not set +# NAUT_CONFIG_ISOCORE is not set +# NAUT_CONFIG_CACHEPART is not set + +# +# Garbage Collection Options +# +# NAUT_CONFIG_GARBAGE_COLLECTION is not set + +# +# FPU Options +# +# NAUT_CONFIG_XSAVE_SUPPORT is not set + +# +# Optimizations +# +NAUT_CONFIG_FPU_SAVE=y +NAUT_CONFIG_KICK_SCHEDULE=y +NAUT_CONFIG_HALT_WHILE_IDLE=y +# NAUT_CONFIG_THREAD_OPTIMIZE is not set + +# +# Debugging +# +NAUT_CONFIG_DEBUG_INFO=y +NAUT_CONFIG_DEBUG_PRINTS=y +NAUT_CONFIG_ENABLE_ASSERTS=y +# NAUT_CONFIG_PROFILE is not set +# NAUT_CONFIG_SILENCE_UNDEF_ERR is not set +# NAUT_CONFIG_ENABLE_STACK_CHECK is not set +# NAUT_CONFIG_ENABLE_REMOTE_DEBUGGING is not set +NAUT_CONFIG_ENABLE_MONITOR=y +# NAUT_CONFIG_DEBUG_PAGING is not set +# NAUT_CONFIG_DEBUG_BOOTMEM is not set +# NAUT_CONFIG_DEBUG_CMDLINE is not set +# NAUT_CONFIG_DEBUG_TESTS is not set +# NAUT_CONFIG_DEBUG_BUDDY is not set +# NAUT_CONFIG_DEBUG_KMEM is not set +# NAUT_CONFIG_DEBUG_FPU is not set +# NAUT_CONFIG_DEBUG_SMP is not set +# NAUT_CONFIG_DEBUG_SHELL is not set +# NAUT_CONFIG_DEBUG_SFI is not set +# NAUT_CONFIG_DEBUG_CXX is not set +# NAUT_CONFIG_DEBUG_THREADS is not set +# NAUT_CONFIG_DEBUG_TASKS is not set +# NAUT_CONFIG_DEBUG_WAITQUEUES is not set +# NAUT_CONFIG_DEBUG_FUTURES is not set +# NAUT_CONFIG_DEBUG_GROUP is not set +# NAUT_CONFIG_DEBUG_SCHED is not set +# NAUT_CONFIG_DEBUG_GROUP_SCHED is not set +# NAUT_CONFIG_DEBUG_TIMERS is not set +# NAUT_CONFIG_DEBUG_SEMAPHORES is not set +# NAUT_CONFIG_DEBUG_MSG_QUEUES is not set +# NAUT_CONFIG_DEBUG_SYNCH is not set +# NAUT_CONFIG_DEBUG_BARRIER is not set +# NAUT_CONFIG_DEBUG_NUMA is not set +# NAUT_CONFIG_DEBUG_VIRTUAL_CONSOLE is not set +# NAUT_CONFIG_DEBUG_DEV is not set +# NAUT_CONFIG_DEBUG_FILESYSTEM is not set +# NAUT_CONFIG_DEBUG_LOADER is not set +# NAUT_CONFIG_DEBUG_LINKER is not set +# NAUT_CONFIG_DEBUG_PMC is not set + +# +# Address Spaces +# +# NAUT_CONFIG_ASPACES is not set + +# +# Runtimes +# +# NAUT_CONFIG_LEGION_RT is not set +# NAUT_CONFIG_NDPC_RT is not set +# NAUT_CONFIG_NESL_RT is not set +NAUT_CONFIG_OPENMP_RT=y +NAUT_CONFIG_OPENMP_RT_OMP=y +NAUT_CONFIG_OPENMP_RT_INSTALL_DIR="/home/pdinda/class/ompnk" +# NAUT_CONFIG_OPENMP_RT_GOMP is not set +NAUT_CONFIG_OPENMP_RT_DEBUG=y +NAUT_CONFIG_OPENMP_RT_TESTS=y +NAUT_CONFIG_RACKET_RT=y + +# +# Devices +# + +# +# Serial Options +# +NAUT_CONFIG_SERIAL_REDIRECT=y +NAUT_CONFIG_SERIAL_REDIRECT_PORT=1 +# NAUT_CONFIG_APIC_FORCE_XAPIC_MODE is not set +# NAUT_CONFIG_APIC_TIMER_CALIBRATE_INDEPENDENTLY is not set +# NAUT_CONFIG_DEBUG_APIC is not set +# NAUT_CONFIG_DEBUG_IOAPIC is not set +# NAUT_CONFIG_DEBUG_PCI is not set +NAUT_CONFIG_DISABLE_PS2_MOUSE=y +# NAUT_CONFIG_DEBUG_PS2 is not set +# NAUT_CONFIG_GPIO is not set +# NAUT_CONFIG_DEBUG_PIT is not set +# NAUT_CONFIG_HPET is not set +# NAUT_CONFIG_VIRTIO_PCI is not set +# NAUT_CONFIG_E1000_PCI is not set +# NAUT_CONFIG_E1000E_PCI is not set +# NAUT_CONFIG_MLX3_PCI is not set +# NAUT_CONFIG_RAMDISK is not set +# NAUT_CONFIG_ATA is not set + +# +# Filesystems +# +# NAUT_CONFIG_EXT2_FILESYSTEM_DRIVER is not set +# NAUT_CONFIG_FAT32_FILESYSTEM_DRIVER is not set + +# +# Networking +# +# NAUT_CONFIG_NET_ETHERNET is not set +# NAUT_CONFIG_NET_COLLECTIVE is not set + +# +# Languages +# +# NAUT_CONFIG_LOAD_LUA is not set diff --git a/ENV b/ENV new file mode 100644 index 000000000..2a203b6a6 --- /dev/null +++ b/ENV @@ -0,0 +1 @@ +export PATH=/home/pdinda/llvm/bin:$PATH diff --git a/Kconfig b/Kconfig index 3f4a16999..73a566cf2 100644 --- a/Kconfig +++ b/Kconfig @@ -1361,7 +1361,7 @@ menu "Runtimes" bool "OpenMP RT" default n help - Include the GOMP-compatible OpenMP run-time + Include the an OpenMP run-time choice depends on OPENMP_RT @@ -1371,6 +1371,12 @@ menu "Runtimes" config OPENMP_RT_OMP bool "CLANG-compatible (OMP)" + config OPENMP_RT_INSTALL_DIR + string "Installation Directory" + depends on OPENMP_RT_OMP + help + Where to find your libomp.a and omp.h + config OPENMP_RT_GOMP bool "GNU-compatible (GOMP) [going away]" diff --git a/Makefile b/Makefile index f0529e967..14e46a796 100644 --- a/Makefile +++ b/Makefile @@ -617,6 +617,10 @@ endif # NAUT_CONFIG_CXX_SUPPORT #/usr/lib64/libc.a \ +ifdef NAUT_CONFIG_OPENMP_RT_OMP + libs-y += $(NAUT_CONFIG_OPENMP_RT_INSTALL_DIR)/lib/libomp.a +endif + ifdef NAUT_CONFIG_PALACIOS PALACIOS_DIR=$(subst "",,$(NAUT_CONFIG_PALACIOS_DIR)) CFLAGS += -I$(PALACIOS_DIR)/nautilus -I$(PALACIOS_DIR)/palacios/include diff --git a/include/rt/openmp/omp.h b/include/rt/openmp/omp.h new file mode 120000 index 000000000..c1aa0ca9d --- /dev/null +++ b/include/rt/openmp/omp.h @@ -0,0 +1 @@ +openmp \ No newline at end of file diff --git a/include/rt/openmp/omp/omp.h b/include/rt/openmp/omp/omp.h new file mode 100644 index 000000000..97e0c022f --- /dev/null +++ b/include/rt/openmp/omp/omp.h @@ -0,0 +1,107 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The V3VEE Project + * The Hobbes Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ +#ifndef _NK_OMP_ +#define _NK_OMP_ + +// Run-time startup and shutdown - invoke in init +// after scheduling is active +int nk_openmp_init(); +void nk_openmp_deinit(); + + +// Promote the current thread into an OMP "main" +// thread. You usually only need to do this +// once at the start of an OMP program. Child threads +// created/used by an OMP program will automatically be +// OMP threads + +int nk_openmp_thread_init(); +int nk_openmp_thread_deinit(); + + +// +// publicly visible functions in compliance with OMP standard +// +// +// Generated code also calls into RT-specific functions (e.g. GOMP_parallel) +// but these do not have prototypes in the header file +// + +int omp_get_active_level(); +int omp_get_ancestor_thread_num(int level); +int omp_get_cancellation(); +int omp_get_default_device(); +int omp_get_dynamic(); +int omp_get_level(void); +int omp_get_max_active_levels(void); +int omp_get_max_task_priority(void); +int omp_get_max_threads(void); +int omp_get_nested(void); +int omp_get_num_devices(void); +int omp_get_num_procs(void); +int omp_get_num_teams(void); +int omp_get_num_threads(void); + +typedef int omp_proc_bind_t; + +omp_proc_bind_t omp_get_proc_bind(void); + +typedef int * omp_sched_t; + +void omp_get_schedule(omp_sched_t *kind, int *chunk_size); + +int omp_get_team_num(void); +int omp_get_team_size(int level); +int omp_get_thread_limit(void); +int omp_get_thread_num(void); +int omp_in_parallel(void); +int omp_in_final(void); +int omp_is_initial_device(void); +void omp_set_default_device(int device_num); +void omp_set_dynamic(int dynamic_threads); +void omp_set_max_active_levels(int max_levels); +void omp_set_nested(int nested); +void omp_set_num_threads(int num_threads); +void omp_set_schedule(omp_sched_t kind, int chunk_size); + +typedef void * omp_lock_t; + +void omp_init_lock(omp_lock_t *lock); +void omp_set_lock(omp_lock_t *lock); +int omp_test_lock(omp_lock_t *lock); +void omp_unset_lock(omp_lock_t *lock); +void omp_destroy_lock(omp_lock_t *lock); + + +typedef omp_lock_t omp_nest_lock_t; + +void omp_init_nest_lock(omp_nest_lock_t *lock); +void omp_set_nest_lock(omp_nest_lock_t *lock); +int omp_test_nest_lock(omp_nest_lock_t *lock); +void omp_unset_nest_lock(omp_nest_lock_t *lock); +void omp_destroy_nest_lock(omp_nest_lock_t *lock); + +double omp_get_wtick(void); +double omp_get_wtime(void); + +#endif diff --git a/src/nautilus/naut_string.c b/src/nautilus/naut_string.c index a01e621b5..b4ee54a62 100644 --- a/src/nautilus/naut_string.c +++ b/src/nautilus/naut_string.c @@ -687,6 +687,24 @@ strstr (const char * s1, const char * s2) return NULL; } +char * +strcasestr (const char * s1, const char * s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *)s1; + l1 = strlen(s1); + while (l1 >= l2) { + l1--; + if (!strncasecmp(s1, s2, l2)) + return (char *)s1; + s1++; + } + return NULL; +} + void str_tolower (char * s) diff --git a/src/rt/openmp/omp/Makefile b/src/rt/openmp/omp/Makefile index e69de29bb..b9d17d13c 100644 --- a/src/rt/openmp/omp/Makefile +++ b/src/rt/openmp/omp/Makefile @@ -0,0 +1,2 @@ +obj-y = omp.o glue.o + diff --git a/src/rt/openmp/omp/glue.c b/src/rt/openmp/omp/glue.c new file mode 100644 index 000000000..c4daee554 --- /dev/null +++ b/src/rt/openmp/omp/glue.c @@ -0,0 +1 @@ +int some_glue_thing_for_omp; diff --git a/src/rt/openmp/omp/omp.c b/src/rt/openmp/omp/omp.c new file mode 100644 index 000000000..9b29f2ff3 --- /dev/null +++ b/src/rt/openmp/omp/omp.c @@ -0,0 +1,48 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The V3VEE Project + * The Hobbes Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + + +#include +#include + +int nk_openmp_init() +{ + return 0; +} + +void nk_openmp_deinit() +{ +} + + +int nk_openmp_thread_init() +{ + return 0; +} + +int nk_openmp_thread_deinit() +{ + return 0; +} + + diff --git a/src/test/openmp/Makefile b/src/test/openmp/Makefile index 91350f27d..927f8fae6 100644 --- a/src/test/openmp/Makefile +++ b/src/test/openmp/Makefile @@ -1,6 +1,8 @@ -CFLAGS += -fopenmp + +CFLAGS += -fopenmp -Iinclude/rt/openmp + obj-y += test_openmp.o -obj-y += openmpbench_C_v31/ -obj-y += streamcluster/ +#obj-y += openmpbench_C_v31/ +#obj-y += streamcluster/ From 0366d6914eedbfb2a975bb45054d426426d8d1a2 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sat, 9 May 2020 12:04:21 -0500 Subject: [PATCH 12/36] More glue code for kmp --- .config | 2 +- src/nautilus/libccompat.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.config b/.config index 29801c413..d5666712d 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Sun May 3 17:46:19 2020 +# Sat May 9 12:03:33 2020 # # diff --git a/src/nautilus/libccompat.c b/src/nautilus/libccompat.c index 2ea5e4b8d..b68f40c68 100644 --- a/src/nautilus/libccompat.c +++ b/src/nautilus/libccompat.c @@ -878,3 +878,16 @@ GEN_DEF(strxfrm) GEN_DEF(wcsxfrm) GEN_DEF(__kernel_standard); GEN_DEF(__get_cpu_features); + + +// KMP + +// SOFT FLOAT - NOT SURE WHY IT IS USING THESE +GEN_DEF(__mulxc3) +GEN_DEF(__muldc3) +GEN_DEF(__mulsc3) +GEN_DEF(__divxc3) +GEN_DEF(__divdc3) +GEN_DEF(__divsc3) + + From 3ccea5aea05b29a796baa170b2ba1679ca1a5829 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sat, 9 May 2020 12:25:47 -0500 Subject: [PATCH 13/36] Add stub generator code, and generated stubs --- find_undef.pl | 9 +++++ src/nautilus/Makefile | 1 + src/nautilus/libccompat.c | 60 +++++++++++++++++++++++++++++++ src/nautilus/libccompat_nomacro.c | 19 ++++++++++ 4 files changed, 89 insertions(+) create mode 100755 find_undef.pl create mode 100644 src/nautilus/libccompat_nomacro.c diff --git a/find_undef.pl b/find_undef.pl new file mode 100755 index 000000000..90ea4ef28 --- /dev/null +++ b/find_undef.pl @@ -0,0 +1,9 @@ +#!/usr/bin/perl -w + +while () { + $sym{$1} = 1 if (/undefined reference to `(.*)'/); +} + +print map { "GEN_DEF($_)\n" } sort keys %sym; + + diff --git a/src/nautilus/Makefile b/src/nautilus/Makefile index 597a2e7ad..23f42d83c 100644 --- a/src/nautilus/Makefile +++ b/src/nautilus/Makefile @@ -38,6 +38,7 @@ obj-y += \ acpi.o \ numa.o \ libccompat.o \ + libccompat_nomacro.o \ nemo.o \ pmc.o \ setjmp.o \ diff --git a/src/nautilus/libccompat.c b/src/nautilus/libccompat.c index b68f40c68..7e95251b0 100644 --- a/src/nautilus/libccompat.c +++ b/src/nautilus/libccompat.c @@ -891,3 +891,63 @@ GEN_DEF(__divdc3) GEN_DEF(__divsc3) +// Other stuff KMP needs, for a start +GEN_DEF(atexit) +GEN_DEF(catclose) +GEN_DEF(catgets) +GEN_DEF(catopen) +GEN_DEF(close) +GEN_DEF(closedir) +GEN_DEF(dlsym) +GEN_DEF(environ) +GEN_DEF(fgetc) +GEN_DEF(gethostname) +GEN_DEF(getpid) +GEN_DEF(getrlimit) +GEN_DEF(getrusage) +GEN_DEF(gettimeofday) +GEN_DEF(open) +GEN_DEF(opendir) +GEN_DEF(pthread_atfork) +GEN_DEF(pthread_attr_destroy) +GEN_DEF(pthread_attr_getstack) +GEN_DEF(pthread_attr_init) +GEN_DEF(pthread_attr_setdetachstate) +GEN_DEF(pthread_attr_setstacksize) +GEN_DEF(pthread_cancel) +GEN_DEF(pthread_cond_destroy) +GEN_DEF(pthread_cond_init) +GEN_DEF(pthread_cond_signal) +GEN_DEF(pthread_cond_wait) +GEN_DEF(pthread_condattr_init) +GEN_DEF(pthread_create) +GEN_DEF(pthread_exit) +GEN_DEF(pthread_getattr_np) +GEN_DEF(pthread_getspecific) +GEN_DEF(pthread_join) +GEN_DEF(pthread_key_create) +GEN_DEF(pthread_key_delete) +GEN_DEF(pthread_mutex_destroy) +GEN_DEF(pthread_mutex_trylock) +GEN_DEF(pthread_mutexattr_init) +GEN_DEF(pthread_self) +GEN_DEF(pthread_setcancelstate) +GEN_DEF(pthread_setcanceltype) +GEN_DEF(pthread_setspecific) +GEN_DEF(qsort) +GEN_DEF(readdir) +GEN_DEF(sched_yield) +GEN_DEF(setenv) +GEN_DEF(sigaction) +GEN_DEF(sigaddset) +GEN_DEF(sigdelset) +GEN_DEF(sigemptyset) +GEN_DEF(sigfillset) +GEN_DEF(sigismember) +GEN_DEF(sleep) +GEN_DEF(strerror_r) +GEN_DEF(strtok_r) +GEN_DEF(sysconf) +GEN_DEF(times) +GEN_DEF(unsetenv) +GEN_DEF(vfscanf) diff --git a/src/nautilus/libccompat_nomacro.c b/src/nautilus/libccompat_nomacro.c new file mode 100644 index 000000000..f3cad3266 --- /dev/null +++ b/src/nautilus/libccompat_nomacro.c @@ -0,0 +1,19 @@ + + +#define NONCANONICAL_ADDR (void*)0xdeafbeef10000000ULL; + +void *stdin=NONCANONICAL_ADDR; +void *stdout=NONCANONICAL_ADDR; +void *stderr=NONCANONICAL_ADDR; + + +int isdigit(int c) +{ + return c>='0' && c<='9'; +} + +int toupper(int c) +{ + return (c>='a' && c<='z') ? c-'a'+'A' : c; +} + From fdf6e58dbc8f2239316858e26d8f107fc6b7c4d8 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Tue, 12 May 2020 18:03:10 -0500 Subject: [PATCH 14/36] Add environment variable support, with multiple environments This makes environment variables available. A default global namespace is also created, but additional namespaces can also be created just in case we want to do this in the future for process-like abstractions --- include/nautilus/env.h | 58 ++++++ src/nautilus/Makefile | 1 + src/nautilus/env.c | 414 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 473 insertions(+) create mode 100644 include/nautilus/env.h create mode 100644 src/nautilus/env.c diff --git a/include/nautilus/env.h b/include/nautilus/env.h new file mode 100644 index 000000000..6f84ab684 --- /dev/null +++ b/include/nautilus/env.h @@ -0,0 +1,58 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The V3VEE Project + * The Hobbes Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + +#ifndef __NK_ENV +#define __NK_ENV + + +#define NK_ENV_MAX_NAME 32 + +struct nk_env *nk_env_create(char *name, + uint64_t numkeys, + uint64_t maxkeysize, + uint64_t maxvaluesize); + +struct nk_env *nk_env_find(char *name); + +int nk_env_destroy(struct nk_env *env); + +// the following apply to the global environmnet +#define NK_ENV_GLOBAL_NAME "global" +#define NK_ENV_GLOBAL_MAX_NUM_KEYS 64 +#define NK_ENV_GLOBAL_MAX_KEY_SIZE 256 +#define NK_ENV_GLOBAL_MAX_VAL_SIZE 256 + +// the global environment is constructed on first use +extern struct nk_env *nk_env_global; + +int nk_env_search(struct nk_env *env, char *key, char **value); +int nk_env_insert(struct nk_env *env, char *key, char *val); +int nk_env_update(struct nk_env *env, char *key, char *val); +int nk_env_delete(struct nk_env *env, char *key); + +// print list of environments, also their contents if indicated +void nk_env_dump_envs(int contents); +// print contents of an environment +void nk_env_dump_env(struct nk_env *env); + +#endif diff --git a/src/nautilus/Makefile b/src/nautilus/Makefile index 23f42d83c..07acf2325 100644 --- a/src/nautilus/Makefile +++ b/src/nautilus/Makefile @@ -39,6 +39,7 @@ obj-y += \ numa.o \ libccompat.o \ libccompat_nomacro.o \ + env.o \ nemo.o \ pmc.o \ setjmp.o \ diff --git a/src/nautilus/env.c b/src/nautilus/env.c new file mode 100644 index 000000000..f0c0599f7 --- /dev/null +++ b/src/nautilus/env.c @@ -0,0 +1,414 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2020, Peter Dinda + * Copyright (c) 2020, The V3VEE Project + * The Hobbes Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + +#include +#include +#include +#include + + + +#if 0 +#define DEBUG(fmt, args...) DEBUG_PRINT("env: " fmt, ##args) +#else +#define DEBUG(fmt, args...) +#endif +#define INFO(fmt, args...) INFO_PRINT("env: " fmt, ##args) +#define ERROR(fmt, args...) ERROR_PRINT("env: " fmt, ##args) +#define WARN(fmt, args...) WARN_PRINT("env: " fmt, ##args) + + +#define STATE_LOCK_CONF uint8_t _state_lock_flags +#define STATE_LOCK() _state_lock_flags = spin_lock_irq_save(&state_lock) +#define STATE_UNLOCK() spin_unlock_irq_restore(&state_lock, _state_lock_flags); + +#define ENV_LOCK_CONF uint8_t _env_lock_flags +#define ENV_LOCK(env) _env_lock_flags = spin_lock_irq_save(&env->lock) +#define ENV_UNLOCK(env) spin_unlock_irq_restore(&env->lock, _env_lock_flags); + + +// the algorithm is stupid and can be fixed later if this +// is ever a performance issue +struct nk_env { + spinlock_t lock; + char name[NK_ENV_MAX_NAME]; + struct list_head node; + uint64_t num_keys; + uint64_t key_size; + uint64_t val_size; + char data[0]; +}; + +static spinlock_t state_lock; +static struct list_head env_list = LIST_HEAD_INIT(env_list); + + +#define UNINITED_GLOBAL ((struct nk_env*)0xdeadb000b000b000UL) + +// char [NUM_KEYS][MAX_KEY_SIZE+MAX_VAL_SIZE]; +struct nk_env *nk_env_global = UNINITED_GLOBAL; + +#define KEY(e,i) (env->data + ((env->key_size + env->val_size) * (i))) +#define VAL(e,i) (env->data + ((env->key_size + env->val_size) * (i) + env->key_size)) + +static inline struct nk_env *check_global(struct nk_env *env) +{ + if (env==UNINITED_GLOBAL) { + nk_env_global = nk_env_create(NK_ENV_GLOBAL_NAME, + NK_ENV_GLOBAL_MAX_NUM_KEYS, + NK_ENV_GLOBAL_MAX_KEY_SIZE, + NK_ENV_GLOBAL_MAX_VAL_SIZE); + if (!nk_env_global) { + ERROR("failed to allocate global environment\n"); + return 0; + } else { + DEBUG("created global environment\n"); + return nk_env_global; + } + } else { + return env; + } +} + + +struct nk_env *nk_env_create(char *name, + uint64_t maxnumkeys, + uint64_t maxkeysize, + uint64_t maxvaluesize) +{ + struct nk_env *e; + + e = malloc(sizeof(struct nk_env) + maxnumkeys * (maxkeysize + maxvaluesize)); + + if (!e) { + ERROR("failed to allocate environment\n"); + return 0; + } + + memset(e,0,sizeof(struct nk_env) + maxnumkeys * (maxkeysize + maxvaluesize)); + + strncpy(e->name,name,NK_ENV_MAX_NAME); e->name[NK_ENV_MAX_NAME-1]=0; + e->num_keys = maxnumkeys; + e->key_size = maxkeysize; + e->val_size = maxvaluesize; + + spinlock_init(&e->lock); + INIT_LIST_HEAD(&e->node); + + STATE_LOCK_CONF; + + STATE_LOCK(); + list_add(&e->node,&env_list); + STATE_UNLOCK(); + + DEBUG("created environment %s\n",e->name); + + return e; +} + + +struct nk_env *nk_env_find(char *name) +{ + struct list_head *cur; + struct nk_env *target=0; + DEBUG("finding environment %s\n",name); + STATE_LOCK_CONF; + STATE_LOCK(); + list_for_each(cur,&env_list) { + if (!strncasecmp(list_entry(cur,struct nk_env,node)->name,name,NK_ENV_MAX_NAME)) { + target = list_entry(cur,struct nk_env, node); + break; + } + } + STATE_UNLOCK(); + return target; +} + + +int nk_env_destroy(struct nk_env *env) +{ + if (env==nk_env_global) { + ERROR("Cannot destroy global environment\n"); + return -1; + } + DEBUG("destroying environment %s\n",env->name); + STATE_LOCK_CONF; + STATE_LOCK(); + list_del_init(&env->node); + STATE_UNLOCK(); + free(env); + return 0; +} + +// assumes lock is held +static int env_search(struct nk_env *env, char *key, char **keyptr, char **valptr) +{ + uint64_t i; + + for (i=0;inum_keys;i++) { + if (!strncmp(KEY(env,i),key,env->key_size)) { + *keyptr = KEY(env,i); + *valptr = VAL(env,i); + return 0; + } + } + + return -1; +} + +// assumes lock is held +static int env_alloc(struct nk_env *env, char *key, char **keyptr, char **valptr) +{ + uint64_t i; + + for (i=0;inum_keys;i++) { + if (!(KEY(env,i)[0])) { + *keyptr = KEY(env,i); + *valptr = VAL(env,i); + return 0; + } + } + + return -1; +} + +int nk_env_search(struct nk_env *env, char *key, char **valptr) +{ + env = check_global(env); + + if (!env) { + return -1; + } + + char *keyptr; + int rc; + + ENV_LOCK_CONF; + + ENV_LOCK(env); + + rc = env_search(env,key,&keyptr,valptr); + + ENV_UNLOCK(env); + + DEBUG("searched environment %s for %s %s %s\n",env->name, + key, !rc ? "found" : "", !rc ? *valptr : ""); + + return rc; +} + +int nk_env_insert(struct nk_env *env, char *key, char *val) +{ + env = check_global(env); + + if (!env) { + return -1; + } + + char *keyptr; + char *valptr; + int rc; + + ENV_LOCK_CONF; + + ENV_LOCK(env); + + rc = env_search(env,key,&keyptr,&valptr); + + + if (!rc) { + ENV_UNLOCK(env); + ERROR("attempting to overwrite key %s in %s\n",key,env->name); + return -1; + } + + if (env_alloc(env,key,&keyptr,&valptr)) { + ENV_UNLOCK(env); + ERROR("out of space for inserting key %s in %s\n",key,env->name); + return -1; + } + + strncpy(keyptr,key,env->key_size); keyptr[env->key_size-1]=0; + strncpy(valptr,val,env->val_size); valptr[env->val_size-1]=0; + + ENV_UNLOCK(env); + + DEBUG("inserted (%s,%s) into %s\n", key,val,env->name); + + return 0; +} + +int nk_env_update(struct nk_env *env, char *key, char *val) +{ + env = check_global(env); + + if (!env) { + return -1; + } + + char *keyptr; + char *valptr; + int rc; + + ENV_LOCK_CONF; + + ENV_LOCK(env); + + rc = env_search(env,key,&keyptr,&valptr); + + + if (rc) { + ENV_UNLOCK(env); + ERROR("attempting to update nonexistent key %s in %s\n",key, env->name); + return -1; + } + + strncpy(keyptr,key,env->key_size); keyptr[env->key_size-1]=0; + strncpy(valptr,val,env->val_size); valptr[env->val_size-1]=0; + + ENV_UNLOCK(env); + + DEBUG("updated (%s,%s) on %s\n", key,val,env->name); + + return 0; +} + + +int nk_env_delete(struct nk_env *env, char *key) +{ + env = check_global(env); + + if (!env) { + return -1; + } + + char *keyptr; + char *valptr; + int rc; + + ENV_LOCK_CONF; + + ENV_LOCK(env); + + rc = env_search(env,key,&keyptr,&valptr); + + + if (rc) { + ENV_UNLOCK(env); + ERROR("attempting to delete nonexistent key %s in %s\n",key, env->name); + return -1; + } + + keyptr[0]=0; + valptr[0]=0; + + ENV_UNLOCK(env); + + DEBUG("deleted %s from %s\n", key,env->name); + + return 0; +} + + +void nk_env_dump_env(struct nk_env *env) +{ + uint64_t i; + ENV_LOCK_CONF; + + ENV_LOCK(env); + + for (i=0;inum_keys;i++) { + if (KEY(env,i)) { + nk_vc_printf(" %s = %s\n", KEY(env,i), VAL(env,i)); + } + } + + ENV_UNLOCK(env); + +} + + +void nk_env_dump_envs(int contents) +{ + struct list_head *cur; + STATE_LOCK_CONF; + STATE_LOCK(); + list_for_each(cur,&env_list) { + struct nk_env *e = list_entry(cur,struct nk_env, node); + if (contents) { + nk_vc_printf("%s contains:\n", e->name); + nk_env_dump_env(e); + } else { + nk_vc_printf("%s\n", e->name); + } + } + STATE_UNLOCK(); +} + + +static int handle_envs (char * buf, void * priv) +{ + char temp[256]; + if (sscanf(buf,"envs %s",temp)==1) { + nk_env_dump_envs(1); + return 0; + } else { + nk_env_dump_envs(0); + return 0; + } +} + + +static struct shell_cmd_impl envs_impl = { + .cmd = "envs", + .help_str = "envs [detail]", + .handler = handle_envs, +}; +nk_register_shell_cmd(envs_impl); + +static int handle_env (char * buf, void * priv) +{ + char temp[256]; + if (sscanf(buf,"env %s",temp)==1) { + struct nk_env *e = nk_env_find(temp); + if (!e) { + nk_vc_printf("cannot find environment %s\n",temp); + return 0; + } else{ + nk_env_dump_env(e); + return 0; + } + } else { + nk_vc_printf("env name\n"); + return 0; + } +} + + +static struct shell_cmd_impl env_impl = { + .cmd = "env", + .help_str = "env name", + .handler = handle_env, +}; +nk_register_shell_cmd(env_impl); + From 0957eb3df2ca1f79a1e27811c38252e94ceb13e0 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Wed, 20 May 2020 16:48:04 -0500 Subject: [PATCH 15/36] Start gluing in pthread embedded library --- src/Makefile | 2 +- src/pthread/ANNOUNCE | 476 + src/pthread/CONTRIBUTORS.ptw32 | 129 + src/pthread/COPYING | 150 + src/pthread/COPYING.LIB | 504 + src/pthread/Makefile | 158 + src/pthread/Makefile.PSP | 194 + src/pthread/Makefile~ | 194 + src/pthread/cleanup.c | 154 + src/pthread/create.c | 259 + src/pthread/doc/Doxyfile | 281 + src/pthread/doc/doxygen.css | 358 + src/pthread/doc/pte_dspbios.html | 108 + src/pthread/doc/pte_main.html | 12 + src/pthread/doc/pte_osal_api.html | 1190 +++ src/pthread/doc/pte_porting_guide.html | 267 + src/pthread/doc/pte_psp.html | 88 + src/pthread/doc/pte_users_guide.html | 33 + src/pthread/global.c | 98 + src/pthread/implement.h | 516 + src/pthread/nautilus_osal.c | 1 + src/pthread/nautilus_osal.h | 63 + src/pthread/need_errno.h | 90 + src/pthread/platform/dspbios/dspbios-config.h | 26 + src/pthread/platform/dspbios/dspbios-osal.c | 923 ++ src/pthread/platform/dspbios/dspbios-osal.h | 102 + src/pthread/platform/dspbios/main.c | 46 + .../platform/dspbios/pte_lib/pte_lib.pjt | 156 + src/pthread/platform/dspbios/pte_osal.h | 12 + .../dspbios/pte_test/Configuration1.cdb | 8974 +++++++++++++++++ .../dspbios/pte_test/Configuration1.tcf | 47 + .../dspbios/pte_test/Configuration1.tco | 6 + .../platform/dspbios/pte_test/pte_test.pjt | 188 + src/pthread/platform/dspbios/pte_types.h | 27 + src/pthread/platform/helper/tls-helper.c | 185 + src/pthread/platform/helper/tls-helper.h | 47 + src/pthread/platform/nautilus/Makefile | 195 + src/pthread/platform/nautilus/Makefile.tests | 212 + src/pthread/platform/nautilus/Makefile~ | 194 + src/pthread/platform/nautilus/main.c | 76 + src/pthread/platform/nautilus/nautilus_osal.c | 1 + src/pthread/platform/nautilus/nautilus_osal.h | 63 + .../platform/nautilus/nautilus_osal.h~ | 66 + src/pthread/platform/nautilus/psp_osal.c | 1 + src/pthread/platform/nautilus/psp_osal.h | 66 + src/pthread/platform/nautilus/pte_osal.h | 15 + src/pthread/platform/nautilus/pte_osal.h~ | 12 + src/pthread/platform/nautilus/pte_types.h | 12 + src/pthread/platform/psp/Makefile | 194 + src/pthread/platform/psp/Makefile.tests | 212 + src/pthread/platform/psp/main.c | 76 + src/pthread/platform/psp/psp_osal.c | 1 + src/pthread/platform/psp/psp_osal.h | 66 + src/pthread/platform/psp/pte_osal.h | 12 + src/pthread/platform/psp/pte_types.h | 12 + src/pthread/pte_callUserDestroyRoutines.c | 229 + src/pthread/pte_cancellable_wait.c | 130 + src/pthread/pte_cond_check_need_init.c | 103 + src/pthread/pte_detach.c | 106 + src/pthread/pte_generic_osal.h | 449 + src/pthread/pte_getprocessors.c | 69 + src/pthread/pte_is_attr.c | 53 + src/pthread/pte_mutex_check_need_init.c | 129 + src/pthread/pte_new.c | 93 + src/pthread/pte_osal.h | 15 + src/pthread/pte_relmillisecs.c | 97 + src/pthread/pte_reuse.c | 158 + src/pthread/pte_rwlock_cancelwrwait.c | 56 + src/pthread/pte_rwlock_check_need_init.c | 102 + src/pthread/pte_spinlock_check_need_init.c | 89 + src/pthread/pte_threadDestroy.c | 101 + src/pthread/pte_threadStart.c | 248 + src/pthread/pte_throw.c | 142 + src/pthread/pte_tkAssocCreate.c | 126 + src/pthread/pte_tkAssocDestroy.c | 122 + src/pthread/pte_types.h | 12 + src/pthread/pthread.h | 1010 ++ src/pthread/pthread_attr_destroy.c | 87 + src/pthread/pthread_attr_getdetachstate.c | 93 + src/pthread/pthread_attr_getinheritsched.c | 57 + src/pthread/pthread_attr_getschedparam.c | 61 + src/pthread/pthread_attr_getschedpolicy.c | 67 + src/pthread/pthread_attr_getscope.c | 56 + src/pthread/pthread_attr_getstackaddr.c | 99 + src/pthread/pthread_attr_getstacksize.c | 102 + src/pthread/pthread_attr_init.c | 119 + src/pthread/pthread_attr_setdetachstate.c | 97 + src/pthread/pthread_attr_setinheritsched.c | 63 + src/pthread/pthread_attr_setschedparam.c | 72 + src/pthread/pthread_attr_setschedpolicy.c | 61 + src/pthread/pthread_attr_setscope.c | 64 + src/pthread/pthread_attr_setstackaddr.c | 103 + src/pthread/pthread_attr_setstacksize.c | 116 + src/pthread/pthread_barrier_destroy.c | 75 + src/pthread/pthread_barrier_init.c | 89 + src/pthread/pthread_barrier_wait.c | 101 + src/pthread/pthread_barrierattr_destroy.c | 91 + src/pthread/pthread_barrierattr_getpshared.c | 101 + src/pthread/pthread_barrierattr_init.c | 93 + src/pthread/pthread_barrierattr_setpshared.c | 125 + src/pthread/pthread_cancel.c | 173 + src/pthread/pthread_cond_destroy.c | 256 + src/pthread/pthread_cond_init.c | 174 + src/pthread/pthread_cond_signal.c | 238 + src/pthread/pthread_cond_wait.c | 568 ++ src/pthread/pthread_condattr_destroy.c | 94 + src/pthread/pthread_condattr_getpshared.c | 103 + src/pthread/pthread_condattr_init.c | 95 + src/pthread/pthread_condattr_setpshared.c | 123 + src/pthread/pthread_delay_np.c | 166 + src/pthread/pthread_detach.c | 142 + src/pthread/pthread_equal.c | 82 + src/pthread/pthread_exit.c | 101 + src/pthread/pthread_getconcurrency.c | 51 + src/pthread/pthread_getschedparam.c | 81 + src/pthread/pthread_getspecific.c | 86 + src/pthread/pthread_init.c | 91 + src/pthread/pthread_join.c | 164 + src/pthread/pthread_key_create.c | 119 + src/pthread/pthread_key_delete.c | 140 + src/pthread/pthread_kill.c | 107 + src/pthread/pthread_mutex_destroy.c | 154 + src/pthread/pthread_mutex_init.c | 83 + src/pthread/pthread_mutex_lock.c | 140 + src/pthread/pthread_mutex_timedlock.c | 189 + src/pthread/pthread_mutex_trylock.c | 95 + src/pthread/pthread_mutex_unlock.c | 130 + src/pthread/pthread_mutexattr_destroy.c | 91 + src/pthread/pthread_mutexattr_getkind_np.c | 50 + src/pthread/pthread_mutexattr_getpshared.c | 101 + src/pthread/pthread_mutexattr_gettype.c | 62 + src/pthread/pthread_mutexattr_init.c | 94 + src/pthread/pthread_mutexattr_setkind_np.c | 50 + src/pthread/pthread_mutexattr_setpshared.c | 125 + src/pthread/pthread_mutexattr_settype.c | 149 + src/pthread/pthread_num_processors_np.c | 62 + src/pthread/pthread_once.c | 186 + src/pthread/pthread_rwlock_destroy.c | 152 + src/pthread/pthread_rwlock_init.c | 117 + src/pthread/pthread_rwlock_rdlock.c | 109 + src/pthread/pthread_rwlock_timedrdlock.c | 116 + src/pthread/pthread_rwlock_timedwrlock.c | 140 + src/pthread/pthread_rwlock_tryrdlock.c | 109 + src/pthread/pthread_rwlock_trywrlock.c | 129 + src/pthread/pthread_rwlock_unlock.c | 100 + src/pthread/pthread_rwlock_wrlock.c | 134 + src/pthread/pthread_rwlockattr_destroy.c | 92 + src/pthread/pthread_rwlockattr_getpshared.c | 104 + src/pthread/pthread_rwlockattr_init.c | 91 + src/pthread/pthread_rwlockattr_setpshared.c | 127 + src/pthread/pthread_self.c | 117 + src/pthread/pthread_setcancelstate.c | 129 + src/pthread/pthread_setcanceltype.c | 142 + src/pthread/pthread_setconcurrency.c | 59 + src/pthread/pthread_setschedparam.c | 115 + src/pthread/pthread_setspecific.c | 178 + src/pthread/pthread_spin_destroy.c | 120 + src/pthread/pthread_spin_init.c | 131 + src/pthread/pthread_spin_lock.c | 86 + src/pthread/pthread_spin_trylock.c | 84 + src/pthread/pthread_spin_unlock.c | 78 + src/pthread/pthread_terminate.c | 92 + src/pthread/pthread_testcancel.c | 107 + src/pthread/pthread_timechange_handler_np.c | 114 + src/pthread/sched.h | 137 + src/pthread/sched_get_priority_max.c | 51 + src/pthread/sched_get_priority_min.c | 51 + src/pthread/sched_setscheduler.c | 52 + src/pthread/sched_yield.c | 82 + src/pthread/sem_close.c | 60 + src/pthread/sem_destroy.c | 156 + src/pthread/sem_getvalue.c | 116 + src/pthread/sem_init.c | 153 + src/pthread/sem_open.c | 60 + src/pthread/sem_post.c | 131 + src/pthread/sem_post_multiple.c | 141 + src/pthread/sem_timedwait.c | 216 + src/pthread/sem_trywait.c | 123 + src/pthread/sem_unlink.c | 60 + src/pthread/sem_wait.c | 254 + src/pthread/semaphore.h | 114 + src/pthread/tests/ChangeLog | 894 ++ src/pthread/tests/barrier1.c | 63 + src/pthread/tests/barrier2.c | 60 + src/pthread/tests/barrier3.c | 77 + src/pthread/tests/barrier4.c | 119 + src/pthread/tests/barrier5.c | 133 + src/pthread/tests/benchlib.c | 75 + src/pthread/tests/benchtest.h | 52 + src/pthread/tests/benchtest1.c | 226 + src/pthread/tests/benchtest2.c | 200 + src/pthread/tests/benchtest3.c | 164 + src/pthread/tests/benchtest4.c | 150 + src/pthread/tests/benchtest5.c | 179 + src/pthread/tests/cancel1.c | 188 + src/pthread/tests/cancel2.c | 235 + src/pthread/tests/cancel3.c | 219 + src/pthread/tests/cancel4.c | 202 + src/pthread/tests/cancel5.c | 210 + src/pthread/tests/cancel6a.c | 203 + src/pthread/tests/cancel6d.c | 189 + src/pthread/tests/cleanup0.c | 225 + src/pthread/tests/cleanup1.c | 240 + src/pthread/tests/cleanup2.c | 215 + src/pthread/tests/cleanup3.c | 226 + src/pthread/tests/condvar1.c | 104 + src/pthread/tests/condvar1_1.c | 122 + src/pthread/tests/condvar1_2.c | 130 + src/pthread/tests/condvar2.c | 129 + src/pthread/tests/condvar2_1.c | 154 + src/pthread/tests/condvar3.c | 152 + src/pthread/tests/condvar3_1.c | 206 + src/pthread/tests/condvar3_2.c | 201 + src/pthread/tests/condvar3_3.c | 145 + src/pthread/tests/condvar4.c | 181 + src/pthread/tests/condvar5.c | 182 + src/pthread/tests/condvar6.c | 260 + src/pthread/tests/condvar7.c | 263 + src/pthread/tests/condvar8.c | 265 + src/pthread/tests/condvar9.c | 271 + src/pthread/tests/count1.c | 105 + src/pthread/tests/create1.c | 77 + src/pthread/tests/create2.c | 117 + src/pthread/tests/create3.c | 127 + src/pthread/tests/delay1.c | 61 + src/pthread/tests/delay2.c | 88 + src/pthread/tests/detach1.c | 103 + src/pthread/tests/equal1.c | 70 + src/pthread/tests/errno1.c | 179 + src/pthread/tests/exception1.c | 221 + src/pthread/tests/exception2.c | 150 + src/pthread/tests/exception3.c | 161 + src/pthread/tests/exit1.c | 69 + src/pthread/tests/exit2.c | 71 + src/pthread/tests/exit3.c | 80 + src/pthread/tests/exit4.c | 201 + src/pthread/tests/exit5.c | 207 + src/pthread/tests/inherit1.c | 145 + src/pthread/tests/join0.c | 75 + src/pthread/tests/join1.c | 83 + src/pthread/tests/join2.c | 74 + src/pthread/tests/join3.c | 80 + src/pthread/tests/join4.c | 83 + src/pthread/tests/kill1.c | 88 + src/pthread/tests/mutex1.c | 79 + src/pthread/tests/mutex1e.c | 83 + src/pthread/tests/mutex1n.c | 82 + src/pthread/tests/mutex1r.c | 83 + src/pthread/tests/mutex2.c | 77 + src/pthread/tests/mutex2e.c | 77 + src/pthread/tests/mutex2r.c | 77 + src/pthread/tests/mutex3.c | 88 + src/pthread/tests/mutex3e.c | 89 + src/pthread/tests/mutex3r.c | 88 + src/pthread/tests/mutex4.c | 125 + src/pthread/tests/mutex5.c | 76 + src/pthread/tests/mutex6.c | 108 + src/pthread/tests/mutex6e.c | 109 + src/pthread/tests/mutex6es.c | 104 + src/pthread/tests/mutex6n.c | 121 + src/pthread/tests/mutex6r.c | 108 + src/pthread/tests/mutex6rs.c | 101 + src/pthread/tests/mutex6s.c | 108 + src/pthread/tests/mutex7.c | 95 + src/pthread/tests/mutex7e.c | 111 + src/pthread/tests/mutex7n.c | 105 + src/pthread/tests/mutex7r.c | 108 + src/pthread/tests/mutex8.c | 100 + src/pthread/tests/mutex8e.c | 114 + src/pthread/tests/mutex8n.c | 114 + src/pthread/tests/mutex8r.c | 114 + src/pthread/tests/once1.c | 90 + src/pthread/tests/once2.c | 134 + src/pthread/tests/once3.c | 151 + src/pthread/tests/once4.c | 188 + src/pthread/tests/priority1.c | 131 + src/pthread/tests/priority2.c | 156 + src/pthread/tests/reuse1.c | 130 + src/pthread/tests/reuse2.c | 170 + src/pthread/tests/rwlock1.c | 68 + src/pthread/tests/rwlock2.c | 73 + src/pthread/tests/rwlock2_t.c | 87 + src/pthread/tests/rwlock3.c | 87 + src/pthread/tests/rwlock3_t.c | 100 + src/pthread/tests/rwlock4.c | 87 + src/pthread/tests/rwlock4_t.c | 100 + src/pthread/tests/rwlock5.c | 89 + src/pthread/tests/rwlock5_t.c | 105 + src/pthread/tests/rwlock6.c | 110 + src/pthread/tests/rwlock6_t.c | 137 + src/pthread/tests/rwlock6_t2.c | 131 + src/pthread/tests/rwlock7.c | 188 + src/pthread/tests/rwlock8.c | 178 + src/pthread/tests/self1.c | 76 + src/pthread/tests/self2.c | 83 + src/pthread/tests/semaphore1.c | 139 + src/pthread/tests/semaphore2.c | 112 + src/pthread/tests/semaphore3.c | 129 + src/pthread/tests/semaphore4.c | 162 + src/pthread/tests/semaphore4t.c | 151 + src/pthread/tests/semaphore5.c | 111 + src/pthread/tests/semaphore6.c | 121 + src/pthread/tests/spin1.c | 64 + src/pthread/tests/spin2.c | 80 + src/pthread/tests/spin3.c | 77 + src/pthread/tests/spin4.c | 106 + src/pthread/tests/stress1.c | 288 + src/pthread/tests/test.h | 283 + src/pthread/tests/test_main.c | 488 + src/pthread/tests/tsd1.c | 227 + src/pthread/tests/tsd2.c | 225 + src/pthread/tests/valid1.c | 109 + src/pthread/tests/valid2.c | 89 + src/pthread/tls-helper.c | 185 + src/pthread/tls-helper.h | 47 + 315 files changed, 52034 insertions(+), 1 deletion(-) create mode 100644 src/pthread/ANNOUNCE create mode 100644 src/pthread/CONTRIBUTORS.ptw32 create mode 100644 src/pthread/COPYING create mode 100644 src/pthread/COPYING.LIB create mode 100644 src/pthread/Makefile create mode 100644 src/pthread/Makefile.PSP create mode 100644 src/pthread/Makefile~ create mode 100644 src/pthread/cleanup.c create mode 100644 src/pthread/create.c create mode 100644 src/pthread/doc/Doxyfile create mode 100644 src/pthread/doc/doxygen.css create mode 100644 src/pthread/doc/pte_dspbios.html create mode 100644 src/pthread/doc/pte_main.html create mode 100644 src/pthread/doc/pte_osal_api.html create mode 100644 src/pthread/doc/pte_porting_guide.html create mode 100644 src/pthread/doc/pte_psp.html create mode 100644 src/pthread/doc/pte_users_guide.html create mode 100644 src/pthread/global.c create mode 100644 src/pthread/implement.h create mode 100644 src/pthread/nautilus_osal.c create mode 100644 src/pthread/nautilus_osal.h create mode 100644 src/pthread/need_errno.h create mode 100644 src/pthread/platform/dspbios/dspbios-config.h create mode 100644 src/pthread/platform/dspbios/dspbios-osal.c create mode 100644 src/pthread/platform/dspbios/dspbios-osal.h create mode 100644 src/pthread/platform/dspbios/main.c create mode 100644 src/pthread/platform/dspbios/pte_lib/pte_lib.pjt create mode 100644 src/pthread/platform/dspbios/pte_osal.h create mode 100644 src/pthread/platform/dspbios/pte_test/Configuration1.cdb create mode 100644 src/pthread/platform/dspbios/pte_test/Configuration1.tcf create mode 100644 src/pthread/platform/dspbios/pte_test/Configuration1.tco create mode 100644 src/pthread/platform/dspbios/pte_test/pte_test.pjt create mode 100644 src/pthread/platform/dspbios/pte_types.h create mode 100644 src/pthread/platform/helper/tls-helper.c create mode 100644 src/pthread/platform/helper/tls-helper.h create mode 100644 src/pthread/platform/nautilus/Makefile create mode 100644 src/pthread/platform/nautilus/Makefile.tests create mode 100644 src/pthread/platform/nautilus/Makefile~ create mode 100644 src/pthread/platform/nautilus/main.c create mode 100644 src/pthread/platform/nautilus/nautilus_osal.c create mode 100644 src/pthread/platform/nautilus/nautilus_osal.h create mode 100644 src/pthread/platform/nautilus/nautilus_osal.h~ create mode 100644 src/pthread/platform/nautilus/psp_osal.c create mode 100644 src/pthread/platform/nautilus/psp_osal.h create mode 100644 src/pthread/platform/nautilus/pte_osal.h create mode 100644 src/pthread/platform/nautilus/pte_osal.h~ create mode 100644 src/pthread/platform/nautilus/pte_types.h create mode 100644 src/pthread/platform/psp/Makefile create mode 100644 src/pthread/platform/psp/Makefile.tests create mode 100644 src/pthread/platform/psp/main.c create mode 100644 src/pthread/platform/psp/psp_osal.c create mode 100644 src/pthread/platform/psp/psp_osal.h create mode 100644 src/pthread/platform/psp/pte_osal.h create mode 100644 src/pthread/platform/psp/pte_types.h create mode 100644 src/pthread/pte_callUserDestroyRoutines.c create mode 100644 src/pthread/pte_cancellable_wait.c create mode 100644 src/pthread/pte_cond_check_need_init.c create mode 100644 src/pthread/pte_detach.c create mode 100644 src/pthread/pte_generic_osal.h create mode 100644 src/pthread/pte_getprocessors.c create mode 100644 src/pthread/pte_is_attr.c create mode 100644 src/pthread/pte_mutex_check_need_init.c create mode 100644 src/pthread/pte_new.c create mode 100644 src/pthread/pte_osal.h create mode 100644 src/pthread/pte_relmillisecs.c create mode 100644 src/pthread/pte_reuse.c create mode 100644 src/pthread/pte_rwlock_cancelwrwait.c create mode 100644 src/pthread/pte_rwlock_check_need_init.c create mode 100644 src/pthread/pte_spinlock_check_need_init.c create mode 100644 src/pthread/pte_threadDestroy.c create mode 100644 src/pthread/pte_threadStart.c create mode 100644 src/pthread/pte_throw.c create mode 100644 src/pthread/pte_tkAssocCreate.c create mode 100644 src/pthread/pte_tkAssocDestroy.c create mode 100644 src/pthread/pte_types.h create mode 100644 src/pthread/pthread.h create mode 100644 src/pthread/pthread_attr_destroy.c create mode 100644 src/pthread/pthread_attr_getdetachstate.c create mode 100644 src/pthread/pthread_attr_getinheritsched.c create mode 100644 src/pthread/pthread_attr_getschedparam.c create mode 100644 src/pthread/pthread_attr_getschedpolicy.c create mode 100644 src/pthread/pthread_attr_getscope.c create mode 100644 src/pthread/pthread_attr_getstackaddr.c create mode 100644 src/pthread/pthread_attr_getstacksize.c create mode 100644 src/pthread/pthread_attr_init.c create mode 100644 src/pthread/pthread_attr_setdetachstate.c create mode 100644 src/pthread/pthread_attr_setinheritsched.c create mode 100644 src/pthread/pthread_attr_setschedparam.c create mode 100644 src/pthread/pthread_attr_setschedpolicy.c create mode 100644 src/pthread/pthread_attr_setscope.c create mode 100644 src/pthread/pthread_attr_setstackaddr.c create mode 100644 src/pthread/pthread_attr_setstacksize.c create mode 100644 src/pthread/pthread_barrier_destroy.c create mode 100644 src/pthread/pthread_barrier_init.c create mode 100644 src/pthread/pthread_barrier_wait.c create mode 100644 src/pthread/pthread_barrierattr_destroy.c create mode 100644 src/pthread/pthread_barrierattr_getpshared.c create mode 100644 src/pthread/pthread_barrierattr_init.c create mode 100644 src/pthread/pthread_barrierattr_setpshared.c create mode 100644 src/pthread/pthread_cancel.c create mode 100644 src/pthread/pthread_cond_destroy.c create mode 100644 src/pthread/pthread_cond_init.c create mode 100644 src/pthread/pthread_cond_signal.c create mode 100644 src/pthread/pthread_cond_wait.c create mode 100644 src/pthread/pthread_condattr_destroy.c create mode 100644 src/pthread/pthread_condattr_getpshared.c create mode 100644 src/pthread/pthread_condattr_init.c create mode 100644 src/pthread/pthread_condattr_setpshared.c create mode 100644 src/pthread/pthread_delay_np.c create mode 100644 src/pthread/pthread_detach.c create mode 100644 src/pthread/pthread_equal.c create mode 100644 src/pthread/pthread_exit.c create mode 100644 src/pthread/pthread_getconcurrency.c create mode 100644 src/pthread/pthread_getschedparam.c create mode 100644 src/pthread/pthread_getspecific.c create mode 100644 src/pthread/pthread_init.c create mode 100644 src/pthread/pthread_join.c create mode 100644 src/pthread/pthread_key_create.c create mode 100644 src/pthread/pthread_key_delete.c create mode 100644 src/pthread/pthread_kill.c create mode 100644 src/pthread/pthread_mutex_destroy.c create mode 100644 src/pthread/pthread_mutex_init.c create mode 100644 src/pthread/pthread_mutex_lock.c create mode 100644 src/pthread/pthread_mutex_timedlock.c create mode 100644 src/pthread/pthread_mutex_trylock.c create mode 100644 src/pthread/pthread_mutex_unlock.c create mode 100644 src/pthread/pthread_mutexattr_destroy.c create mode 100644 src/pthread/pthread_mutexattr_getkind_np.c create mode 100644 src/pthread/pthread_mutexattr_getpshared.c create mode 100644 src/pthread/pthread_mutexattr_gettype.c create mode 100644 src/pthread/pthread_mutexattr_init.c create mode 100644 src/pthread/pthread_mutexattr_setkind_np.c create mode 100644 src/pthread/pthread_mutexattr_setpshared.c create mode 100644 src/pthread/pthread_mutexattr_settype.c create mode 100644 src/pthread/pthread_num_processors_np.c create mode 100644 src/pthread/pthread_once.c create mode 100644 src/pthread/pthread_rwlock_destroy.c create mode 100644 src/pthread/pthread_rwlock_init.c create mode 100644 src/pthread/pthread_rwlock_rdlock.c create mode 100644 src/pthread/pthread_rwlock_timedrdlock.c create mode 100644 src/pthread/pthread_rwlock_timedwrlock.c create mode 100644 src/pthread/pthread_rwlock_tryrdlock.c create mode 100644 src/pthread/pthread_rwlock_trywrlock.c create mode 100644 src/pthread/pthread_rwlock_unlock.c create mode 100644 src/pthread/pthread_rwlock_wrlock.c create mode 100644 src/pthread/pthread_rwlockattr_destroy.c create mode 100644 src/pthread/pthread_rwlockattr_getpshared.c create mode 100644 src/pthread/pthread_rwlockattr_init.c create mode 100644 src/pthread/pthread_rwlockattr_setpshared.c create mode 100644 src/pthread/pthread_self.c create mode 100644 src/pthread/pthread_setcancelstate.c create mode 100644 src/pthread/pthread_setcanceltype.c create mode 100644 src/pthread/pthread_setconcurrency.c create mode 100644 src/pthread/pthread_setschedparam.c create mode 100644 src/pthread/pthread_setspecific.c create mode 100644 src/pthread/pthread_spin_destroy.c create mode 100644 src/pthread/pthread_spin_init.c create mode 100644 src/pthread/pthread_spin_lock.c create mode 100644 src/pthread/pthread_spin_trylock.c create mode 100644 src/pthread/pthread_spin_unlock.c create mode 100644 src/pthread/pthread_terminate.c create mode 100644 src/pthread/pthread_testcancel.c create mode 100644 src/pthread/pthread_timechange_handler_np.c create mode 100644 src/pthread/sched.h create mode 100644 src/pthread/sched_get_priority_max.c create mode 100644 src/pthread/sched_get_priority_min.c create mode 100644 src/pthread/sched_setscheduler.c create mode 100644 src/pthread/sched_yield.c create mode 100644 src/pthread/sem_close.c create mode 100644 src/pthread/sem_destroy.c create mode 100644 src/pthread/sem_getvalue.c create mode 100644 src/pthread/sem_init.c create mode 100644 src/pthread/sem_open.c create mode 100644 src/pthread/sem_post.c create mode 100644 src/pthread/sem_post_multiple.c create mode 100644 src/pthread/sem_timedwait.c create mode 100644 src/pthread/sem_trywait.c create mode 100644 src/pthread/sem_unlink.c create mode 100644 src/pthread/sem_wait.c create mode 100644 src/pthread/semaphore.h create mode 100644 src/pthread/tests/ChangeLog create mode 100644 src/pthread/tests/barrier1.c create mode 100644 src/pthread/tests/barrier2.c create mode 100644 src/pthread/tests/barrier3.c create mode 100644 src/pthread/tests/barrier4.c create mode 100644 src/pthread/tests/barrier5.c create mode 100644 src/pthread/tests/benchlib.c create mode 100644 src/pthread/tests/benchtest.h create mode 100644 src/pthread/tests/benchtest1.c create mode 100644 src/pthread/tests/benchtest2.c create mode 100644 src/pthread/tests/benchtest3.c create mode 100644 src/pthread/tests/benchtest4.c create mode 100644 src/pthread/tests/benchtest5.c create mode 100644 src/pthread/tests/cancel1.c create mode 100644 src/pthread/tests/cancel2.c create mode 100644 src/pthread/tests/cancel3.c create mode 100644 src/pthread/tests/cancel4.c create mode 100644 src/pthread/tests/cancel5.c create mode 100644 src/pthread/tests/cancel6a.c create mode 100644 src/pthread/tests/cancel6d.c create mode 100644 src/pthread/tests/cleanup0.c create mode 100644 src/pthread/tests/cleanup1.c create mode 100644 src/pthread/tests/cleanup2.c create mode 100644 src/pthread/tests/cleanup3.c create mode 100644 src/pthread/tests/condvar1.c create mode 100644 src/pthread/tests/condvar1_1.c create mode 100644 src/pthread/tests/condvar1_2.c create mode 100644 src/pthread/tests/condvar2.c create mode 100644 src/pthread/tests/condvar2_1.c create mode 100644 src/pthread/tests/condvar3.c create mode 100644 src/pthread/tests/condvar3_1.c create mode 100644 src/pthread/tests/condvar3_2.c create mode 100644 src/pthread/tests/condvar3_3.c create mode 100644 src/pthread/tests/condvar4.c create mode 100644 src/pthread/tests/condvar5.c create mode 100644 src/pthread/tests/condvar6.c create mode 100644 src/pthread/tests/condvar7.c create mode 100644 src/pthread/tests/condvar8.c create mode 100644 src/pthread/tests/condvar9.c create mode 100644 src/pthread/tests/count1.c create mode 100644 src/pthread/tests/create1.c create mode 100644 src/pthread/tests/create2.c create mode 100644 src/pthread/tests/create3.c create mode 100644 src/pthread/tests/delay1.c create mode 100644 src/pthread/tests/delay2.c create mode 100644 src/pthread/tests/detach1.c create mode 100644 src/pthread/tests/equal1.c create mode 100644 src/pthread/tests/errno1.c create mode 100644 src/pthread/tests/exception1.c create mode 100644 src/pthread/tests/exception2.c create mode 100644 src/pthread/tests/exception3.c create mode 100644 src/pthread/tests/exit1.c create mode 100644 src/pthread/tests/exit2.c create mode 100644 src/pthread/tests/exit3.c create mode 100644 src/pthread/tests/exit4.c create mode 100644 src/pthread/tests/exit5.c create mode 100644 src/pthread/tests/inherit1.c create mode 100644 src/pthread/tests/join0.c create mode 100644 src/pthread/tests/join1.c create mode 100644 src/pthread/tests/join2.c create mode 100644 src/pthread/tests/join3.c create mode 100644 src/pthread/tests/join4.c create mode 100644 src/pthread/tests/kill1.c create mode 100644 src/pthread/tests/mutex1.c create mode 100644 src/pthread/tests/mutex1e.c create mode 100644 src/pthread/tests/mutex1n.c create mode 100644 src/pthread/tests/mutex1r.c create mode 100644 src/pthread/tests/mutex2.c create mode 100644 src/pthread/tests/mutex2e.c create mode 100644 src/pthread/tests/mutex2r.c create mode 100644 src/pthread/tests/mutex3.c create mode 100644 src/pthread/tests/mutex3e.c create mode 100644 src/pthread/tests/mutex3r.c create mode 100644 src/pthread/tests/mutex4.c create mode 100644 src/pthread/tests/mutex5.c create mode 100644 src/pthread/tests/mutex6.c create mode 100644 src/pthread/tests/mutex6e.c create mode 100644 src/pthread/tests/mutex6es.c create mode 100644 src/pthread/tests/mutex6n.c create mode 100644 src/pthread/tests/mutex6r.c create mode 100644 src/pthread/tests/mutex6rs.c create mode 100644 src/pthread/tests/mutex6s.c create mode 100644 src/pthread/tests/mutex7.c create mode 100644 src/pthread/tests/mutex7e.c create mode 100644 src/pthread/tests/mutex7n.c create mode 100644 src/pthread/tests/mutex7r.c create mode 100644 src/pthread/tests/mutex8.c create mode 100644 src/pthread/tests/mutex8e.c create mode 100644 src/pthread/tests/mutex8n.c create mode 100644 src/pthread/tests/mutex8r.c create mode 100644 src/pthread/tests/once1.c create mode 100644 src/pthread/tests/once2.c create mode 100644 src/pthread/tests/once3.c create mode 100644 src/pthread/tests/once4.c create mode 100644 src/pthread/tests/priority1.c create mode 100644 src/pthread/tests/priority2.c create mode 100644 src/pthread/tests/reuse1.c create mode 100644 src/pthread/tests/reuse2.c create mode 100644 src/pthread/tests/rwlock1.c create mode 100644 src/pthread/tests/rwlock2.c create mode 100644 src/pthread/tests/rwlock2_t.c create mode 100644 src/pthread/tests/rwlock3.c create mode 100644 src/pthread/tests/rwlock3_t.c create mode 100644 src/pthread/tests/rwlock4.c create mode 100644 src/pthread/tests/rwlock4_t.c create mode 100644 src/pthread/tests/rwlock5.c create mode 100644 src/pthread/tests/rwlock5_t.c create mode 100644 src/pthread/tests/rwlock6.c create mode 100644 src/pthread/tests/rwlock6_t.c create mode 100644 src/pthread/tests/rwlock6_t2.c create mode 100644 src/pthread/tests/rwlock7.c create mode 100644 src/pthread/tests/rwlock8.c create mode 100644 src/pthread/tests/self1.c create mode 100644 src/pthread/tests/self2.c create mode 100644 src/pthread/tests/semaphore1.c create mode 100644 src/pthread/tests/semaphore2.c create mode 100644 src/pthread/tests/semaphore3.c create mode 100644 src/pthread/tests/semaphore4.c create mode 100644 src/pthread/tests/semaphore4t.c create mode 100644 src/pthread/tests/semaphore5.c create mode 100644 src/pthread/tests/semaphore6.c create mode 100644 src/pthread/tests/spin1.c create mode 100644 src/pthread/tests/spin2.c create mode 100644 src/pthread/tests/spin3.c create mode 100644 src/pthread/tests/spin4.c create mode 100644 src/pthread/tests/stress1.c create mode 100644 src/pthread/tests/test.h create mode 100644 src/pthread/tests/test_main.c create mode 100644 src/pthread/tests/tsd1.c create mode 100644 src/pthread/tests/tsd2.c create mode 100644 src/pthread/tests/valid1.c create mode 100644 src/pthread/tests/valid2.c create mode 100644 src/pthread/tls-helper.c create mode 100644 src/pthread/tls-helper.h diff --git a/src/Makefile b/src/Makefile index 75ecb01b6..30e204233 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ obj-y += \ rt/ \ net/ \ acpi/ \ - test/ + test/ pthread/ obj-$(NAUT_CONFIG_CXX_SUPPORT) += cxx/ obj-$(NAUT_CONFIG_LEGION_RT) += legion_runtime/ diff --git a/src/pthread/ANNOUNCE b/src/pthread/ANNOUNCE new file mode 100644 index 000000000..97d94e702 --- /dev/null +++ b/src/pthread/ANNOUNCE @@ -0,0 +1,476 @@ + PTHREADS-WIN32 RELEASE 2.8.0 (2006-12-22) + ----------------------------------------- + Web Site: http://sources.redhat.com/pthreads-win32/ + FTP Site: ftp://sources.redhat.com/pub/pthreads-win32 + Maintainer: Ross Johnson + + +We are pleased to announce the availability of a new release of +Pthreads-win32, an Open Source Software implementation of the +Threads component of the POSIX 1003.1 2001 Standard for Microsoft's +Win32 environment. Some functions from other sections of POSIX +1003.1 2001 are also supported including semaphores and scheduling +functions. + +Some common non-portable functions are also implemented for +additional compatibility, as are a few functions specific +to pthreads-win32 for easier integration with Win32 applications. + +Pthreads-win32 is free software, distributed under the GNU Lesser +General Public License (LGPL). + + +Acknowledgements +---------------- +This library is based originally on a Win32 pthreads +implementation contributed by John Bossom . + +The implementation of Condition Variables uses algorithms developed +by Alexander Terekhov and Louis Thomas. + +The implementation of POSIX mutexes has been improved by Thomas Pfaff +and later by Alexander Terekhov. + +The implementation of Spinlocks and Barriers was contributed +by Ross Johnson. + +The implementation of read/write locks was contributed by +Aurelio Medina and improved by Alexander Terekhov. + +Many others have contributed significant time and effort to solve crutial +problems in order to make the library workable, robust and reliable. + +Thanks to Xavier Leroy for granting permission to use and modify his +LinuxThreads manual pages. + +Thanks to The Open Group for making the Single Unix Specification +publicly available - many of the manual pages included in the package +were extracted from it. + +There is also a separate CONTRIBUTORS file. This file and others are +on the web site: + + http://sources.redhat.com/pthreads-win32 + +As much as possible, the ChangeLog file acknowledges contributions to the +code base in more detail. + + +Changes since the last release +------------------------------ +These are now documented in the NEWS file. +See the ChangeLog file also. + + +Known Bugs +---------- +These are now documented in the BUGS file. + + +Level of standards conformance +------------------------------ + +The following POSIX 1003.1 2001 options are defined and set to 200112L: + + _POSIX_THREADS + _POSIX_THREAD_SAFE_FUNCTIONS + _POSIX_THREAD_ATTR_STACKSIZE + _POSIX_THREAD_PRIORITY_SCHEDULING + _POSIX_SEMAPHORES + _POSIX_READER_WRITER_LOCKS + _POSIX_SPIN_LOCKS + _POSIX_BARRIERS + + +The following POSIX 1003.1 2001 options are defined and set to -1: + + _POSIX_THREAD_ATTR_STACKADDR + _POSIX_THREAD_PRIO_INHERIT + _POSIX_THREAD_PRIO_PROTECT + _POSIX_THREAD_PROCESS_SHARED + + +The following POSIX 1003.1 2001 limits are defined and set: + + _POSIX_THREAD_THREADS_MAX + _POSIX_SEM_VALUE_MAX + _POSIX_SEM_NSEMS_MAX + _POSIX_THREAD_KEYS_MAX + _POSIX_THREAD_DESTRUCTOR_ITERATIONS + PTHREAD_STACK_MIN + PTHREAD_THREADS_MAX + SEM_VALUE_MAX + SEM_NSEMS_MAX + PTHREAD_KEYS_MAX + PTHREAD_DESTRUCTOR_ITERATIONS + + +The following functions are implemented: + + --------------------------- + PThreads + --------------------------- + pthread_attr_init + pthread_attr_destroy + pthread_attr_getdetachstate + pthread_attr_getstackaddr + pthread_attr_getstacksize + pthread_attr_setdetachstate + pthread_attr_setstackaddr + pthread_attr_setstacksize + + pthread_create + pthread_detach + pthread_equal + pthread_exit + pthread_join + pthread_once + pthread_self + + pthread_cancel + pthread_cleanup_pop + pthread_cleanup_push + pthread_setcancelstate + pthread_setcanceltype + pthread_testcancel + + --------------------------- + Thread Specific Data + --------------------------- + pthread_key_create + pthread_key_delete + pthread_setspecific + pthread_getspecific + + --------------------------- + Mutexes + --------------------------- + pthread_mutexattr_init + pthread_mutexattr_destroy + pthread_mutexattr_getpshared + pthread_mutexattr_setpshared + pthread_mutexattr_gettype + pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT + PTHREAD_MUTEX_NORMAL + PTHREAD_MUTEX_ERRORCHECK + PTHREAD_MUTEX_RECURSIVE ) + pthread_mutex_init + pthread_mutex_destroy + pthread_mutex_lock + pthread_mutex_trylock + pthread_mutex_timedlock + pthread_mutex_unlock + + --------------------------- + Condition Variables + --------------------------- + pthread_condattr_init + pthread_condattr_destroy + pthread_condattr_getpshared + pthread_condattr_setpshared + + pthread_cond_init + pthread_cond_destroy + pthread_cond_wait + pthread_cond_timedwait + pthread_cond_signal + pthread_cond_broadcast + + --------------------------- + Read/Write Locks + --------------------------- + pthread_rwlock_init + pthread_rwlock_destroy + pthread_rwlock_tryrdlock + pthread_rwlock_trywrlock + pthread_rwlock_rdlock + pthread_rwlock_timedrdlock + pthread_rwlock_rwlock + pthread_rwlock_timedwrlock + pthread_rwlock_unlock + pthread_rwlockattr_init + pthread_rwlockattr_destroy + pthread_rwlockattr_getpshared + pthread_rwlockattr_setpshared + + --------------------------- + Spin Locks + --------------------------- + pthread_spin_init + pthread_spin_destroy + pthread_spin_lock + pthread_spin_unlock + pthread_spin_trylock + + --------------------------- + Barriers + --------------------------- + pthread_barrier_init + pthread_barrier_destroy + pthread_barrier_wait + pthread_barrierattr_init + pthread_barrierattr_destroy + pthread_barrierattr_getpshared + pthread_barrierattr_setpshared + + --------------------------- + Semaphores + --------------------------- + sem_init + sem_destroy + sem_post + sem_wait + sem_trywait + sem_timedwait + sem_getvalue (# free if +ve, # of waiters if -ve) + sem_open (returns an error ENOSYS) + sem_close (returns an error ENOSYS) + sem_unlink (returns an error ENOSYS) + + --------------------------- + RealTime Scheduling + --------------------------- + pthread_attr_getschedparam + pthread_attr_setschedparam + pthread_attr_getinheritsched + pthread_attr_setinheritsched + pthread_attr_getschedpolicy (only supports SCHED_OTHER) + pthread_attr_setschedpolicy (only supports SCHED_OTHER) + pthread_getschedparam + pthread_setschedparam + pthread_getconcurrency + pthread_setconcurrency + pthread_attr_getscope + pthread_attr_setscope (only supports PTHREAD_SCOPE_SYSTEM) + sched_get_priority_max + sched_get_priority_min + sched_rr_get_interval (returns an error ENOTSUP) + sched_setscheduler (only supports SCHED_OTHER) + sched_getscheduler (only supports SCHED_OTHER) + sched_yield + + --------------------------- + Signals + --------------------------- + pthread_sigmask + pthread_kill (only supports zero sig value, + for thread validity checking) + + --------------------------- + Non-portable routines (see the README.NONPORTABLE file for usage) + --------------------------- + pthread_getw32threadhandle_np + pthread_timechange_handler_np + pthread_delay_np + pthread_mutexattr_getkind_np + pthread_mutexattr_setkind_np (types: PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ADAPTIVE_NP, + PTHREAD_MUTEX_TIMED_NP) + pthread_num_processors_np + pthread_win32_process_attach_np (Required when statically linking + the library) + pthread_win32_process_detach_np (Required when statically linking + the library) + pthread_win32_thread_attach_np (Required when statically linking + the library) + pthread_win32_thread_detach_np (Required when statically linking + the library) + + --------------------------- + Static Initializers + --------------------------- + PTHREAD_ONCE_INIT + PTHREAD_MUTEX_INITIALIZER + PTHREAD_RECURSIVE_MUTEX_INITIALIZER + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP + PTHREAD_COND_INITIALIZER + PTHREAD_RWLOCK_INITIALIZER + PTHREAD_SPINLOCK_INITIALIZER + + --------------------------- + Thread-Safe C Runtime Library (macros) + --------------------------- + strtok_r + asctime_r + ctime_r + gmtime_r + localtime_r + rand_r + + +The following functions are not implemented: + + --------------------------- + RealTime Scheduling + --------------------------- + pthread_mutex_getprioceiling + pthread_mutex_setprioceiling + pthread_mutex_attr_getprioceiling + pthread_mutex_attr_getprotocol + pthread_mutex_attr_setprioceiling + pthread_mutex_attr_setprotocol + + --------------------------- + Fork Handlers + --------------------------- + pthread_atfork + + --------------------------- + Stdio + --------------------------- + flockfile + ftrylockfile + funlockfile + getc_unlocked + getchar_unlocked + putc_unlocked + putchar_unlocked + + --------------------------- + Thread-Safe C Runtime Library + --------------------------- + readdir_r + getgrgid_r + getgrnam_r + getpwuid_r + getpwnam_r + + --------------------------- + Signals + --------------------------- + sigtimedwait + sigwait + sigwaitinfo + + --------------------------- + General + --------------------------- + sysconf + +The library includes two non-API functions for creating cancellation +points in applications and libraries: + + pthreadCancelableWait + pthreadCancelableTimedWait + + +Availability +------------ + +The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header +files (pthread.h, semaphore.h, sched.h) are available along with the +complete source code. + +The source code can be found at: + + ftp://sources.redhat.com/pub/pthreads-win32 + +and as individual source code files at + + ftp://sources.redhat.com/pub/pthreads-win32/source + +The pre-built DLL, export libraries and include files can be found at: + + ftp://sources.redhat.com/pub/pthreads-win32/dll-latest + + + +Mailing List +------------ + +There is a mailing list for discussing pthreads on Win32. To join, +send email to: + + pthreads-win32-subscribe@sourceware.cygnus.com + + +Application Development Environments +------------------------------------ + +See the README file for more information. + +MSVC: +MSVC using SEH works. Distribute pthreadVSE.dll with your application. +MSVC using C++ EH works. Distribute pthreadVCE.dll with your application. +MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application. + + +Mingw32: +See the FAQ, Questions 6 and 10. + +Mingw using C++ EH works. Distribute pthreadGCE.dll with your application. +Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application. + + +Cygwin: (http://sourceware.cygnus.com/cygwin/) +Developers using Cygwin will not need pthreads-win32 since it has POSIX threads +support. Refer to its documentation for details and extent. + + +UWIN: +UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32 +doesn't currently support UWIN (and vice versa), but that may change in the +future. + +Generally: +For convenience, the following pre-built files are available on the FTP site +(see Availability above): + + pthread.h - for POSIX 1c threads + semaphore.h - for POSIX 1b semaphores + sched.h - for POSIX 1b scheduling + pthreadVCE.dll - built with MSVC++ compiler using C++ EH + pthreadVCE.lib + pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp + pthreadVC.lib + pthreadVSE.dll - built with MSVC compiler using SEH + pthreadVSE.lib + pthreadGCE.dll - built with Mingw32 G++ 2.95.2-1 + pthreadGC.dll - built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp + libpthreadGCE.a - derived from pthreadGCE.dll + libpthreadGC.a - derived from pthreadGC.dll + gcc.dll - needed if distributing applications that use + pthreadGCE.dll (but see the FAQ Q 10 for the latest + related information) + +These are the only files you need in order to build POSIX threads +applications for Win32 using either MSVC or Mingw32. + +See the FAQ file in the source tree for additional information. + + +Documentation +------------- + +For the authoritative reference, see the online POSIX +standard reference at: + + http://www.OpenGroup.org + +For POSIX Thread API programming, several reference books are +available: + + Programming with POSIX Threads + David R. Butenhof + Addison-Wesley (pub) + + Pthreads Programming + By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell + O'Reilly (pub) + +On the web: see the links at the bottom of the pthreads-win32 site: + + http://sources.redhat.com/pthreads-win32/ + + Currently, there is no documentation included in the package apart + from the copious comments in the source code. + + + +Enjoy! + +Ross Johnson diff --git a/src/pthread/CONTRIBUTORS.ptw32 b/src/pthread/CONTRIBUTORS.ptw32 new file mode 100644 index 000000000..e5b7325d1 --- /dev/null +++ b/src/pthread/CONTRIBUTORS.ptw32 @@ -0,0 +1,129 @@ +Contributors (in approximate order of appearance) + +[See also the ChangeLog file where individuals are +attributed in log entries. Likewise in the FAQ file.] + +Ben Elliston bje at cygnus dot com + Initiated the project; + setup the project infrastructure (CVS, web page, etc.); + early prototype routines. +Ross Johnson rpj at callisto dot canberra dot edu dot au + early prototype routines; + ongoing project coordination/maintenance; + implementation of spin locks and barriers; + various enhancements; + bug fixes; + documentation; + testsuite. +Robert Colquhoun rjc at trump dot net dot au + Early bug fixes. +John E. Bossom John dot Bossom at cognos dot com + Contributed substantial original working implementation; + bug fixes; + ongoing guidance and standards interpretation. +Anders Norlander anorland at hem2 dot passagen dot se + Early enhancements and runtime checking for supported + Win32 routines. +Tor Lillqvist tml at iki dot fi + General enhancements; + early bug fixes to condition variables. +Scott Lightner scott at curriculum dot com + Bug fix. +Kevin Ruland Kevin dot Ruland at anheuser-busch dot com + Various bug fixes. +Mike Russo miker at eai dot com + Bug fix. +Mark E. Armstrong avail at pacbell dot net + Bug fixes. +Lorin Hochstein lmh at xiphos dot ca + general bug fixes; bug fixes to condition variables. +Peter Slacik Peter dot Slacik at tatramed dot sk + Bug fixes. +Mumit Khan khan at xraylith dot wisc dot edu + Fixes to work with Mingw32. +Milan Gardian mg at tatramed dot sk + Bug fixes and reports/analyses of obscure problems. +Aurelio Medina aureliom at crt dot com + First implementation of read-write locks. +Graham Dumpleton Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au + Bug fix in condition variables. +Tristan Savatier tristan at mpegtv dot com + WinCE port. +Erik Hensema erik at hensema dot xs4all dot nl + Bug fixes. +Rich Peters rpeters at micro-magic dot com +Todd Owen towen at lucidcalm dot dropbear dot id dot au + Bug fixes to dll loading. +Jason Nye jnye at nbnet dot nb dot ca + Implementation of async cancelation. +Fred Forester fforest at eticomm dot net +Kevin D. Clark kclark at cabletron dot com +David Baggett dmb at itasoftware dot com + Bug fixes. +Paul Redondo paul at matchvision dot com +Scott McCaskill scott at 3dfx dot com + Bug fixes. +Jef Gearhart jgearhart at tpssys dot com + Bug fix. +Arthur Kantor akantor at bexusa dot com + Mutex enhancements. +Steven Reddie smr at essemer dot com dot au + Bug fix. +Alexander Terekhov TEREKHOV at de dot ibm dot com + Re-implemented and improved read-write locks; + (with Louis Thomas) re-implemented and improved + condition variables; + enhancements to semaphores; + enhancements to mutexes; + new mutex implementation in 'futex' style; + suggested a robust implementation of pthread_once + similar to that implemented by V.Kliathcko; + system clock change handling re CV timeouts; + bug fixes. +Thomas Pfaff tpfaff at gmx dot net + Changes to make C version usable with C++ applications; + re-implemented mutex routines to avoid Win32 mutexes + and TryEnterCriticalSection; + procedure to fix Mingw32 thread-safety issues. +Franco Bez franco dot bez at gmx dot de + procedure to fix Mingw32 thread-safety issues. +Louis Thomas lthomas at arbitrade dot com + (with Alexander Terekhov) re-implemented and improved + condition variables. +David Korn dgk at research dot att dot com + Ported to UWIN. +Phil Frisbie, Jr. phil at hawksoft dot com + Bug fix. +Ralf Brese Ralf dot Brese at pdb4 dot siemens dot de + Bug fix. +prionx at juno dot com prionx at juno dot com + Bug fixes. +Max Woodbury mtew at cds dot duke dot edu + POSIX versioning conditionals; + reduced namespace pollution; + idea to separate routines to reduce statically + linked image sizes. +Rob Fanner rfanner at stonethree dot com + Bug fix. +Michael Johnson michaelj at maine dot rr dot com + Bug fix. +Nicolas Barry boozai at yahoo dot com + Bug fixes. +Piet van Bruggen pietvb at newbridges dot nl + Bug fix. +Makoto Kato raven at oldskool dot jp + AMD64 port. +Panagiotis E. Hadjidoukas peh at hpclab dot ceid dot upatras dot gr + Contributed the QueueUserAPCEx package which + makes preemptive async cancelation possible. +Will Bryant will dot bryant at ecosm dot com + Borland compiler patch and makefile. +Anuj Goyal anuj dot goyal at gmail dot com + Port to Digital Mars compiler. +Gottlob Frege gottlobfrege at gmail dot com + re-implemented pthread_once (version 2) + (pthread_once cancellation added by rpj). +Vladimir Kliatchko vladimir at kliatchko dot com + reimplemented pthread_once with the same form + as described by A.Terekhov (later version 2); + implementation of MCS (Mellor-Crummey/Scott) locks. diff --git a/src/pthread/COPYING b/src/pthread/COPYING new file mode 100644 index 000000000..5cfea0d0e --- /dev/null +++ b/src/pthread/COPYING @@ -0,0 +1,150 @@ + pthreads-win32 - a POSIX threads library for Microsoft Windows + + +This file is Copyrighted +------------------------ + + This file is covered under the following Copyright: + + Copyright (C) 2001,2006 Ross P. Johnson + All rights reserved. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Pthreads-win32 is covered by the GNU Lesser General Public License +------------------------------------------------------------------ + + Pthreads-win32 is open software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation version 2.1 of the + License. + + Pthreads-win32 is several binary link libraries, several modules, + associated interface definition files and scripts used to control + its compilation and installation. + + Pthreads-win32 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + A copy of the GNU Lesser General Public License is distributed with + pthreads-win32 under the filename: + + COPYING.LIB + + You should have received a copy of the version 2.1 GNU Lesser General + Public License with pthreads-win32; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place + Suite 330 + Boston, MA 02111-1307 + USA + + The contact addresses for pthreads-win32 is as follows: + + Web: http://sources.redhat.com/pthreads-win32 + Email: Ross Johnson + Please use: Firstname.Lastname@homemail.com.au + + + +Pthreads-win32 copyrights and exception files +--------------------------------------------- + + With the exception of the files listed below, Pthreads-win32 + is covered under the following GNU Lesser General Public License + Copyrights: + + Pthreads-win32 - POSIX Threads Library for Win32 + Copyright(C) 1998 John E. Bossom + Copyright(C) 1999,2006 Pthreads-win32 contributors + + The current list of contributors is contained + in the file CONTRIBUTORS included with the source + code distribution. The current list of CONTRIBUTORS + can also be seen at the following WWW location: + http://sources.redhat.com/pthreads-win32/contributors.html + + Contact Email: Ross Johnson + Please use: Firstname.Lastname@homemail.com.au + + These files are not covered under one of the Copyrights listed above: + + COPYING + COPYING.LIB + tests/rwlock7.c + + This file, COPYING, is distributed under the Copyright found at the + top of this file. It is important to note that you may distribute + verbatim copies of this file but you may not modify this file. + + The file COPYING.LIB, which contains a copy of the version 2.1 + GNU Lesser General Public License, is itself copyrighted by the + Free Software Foundation, Inc. Please note that the Free Software + Foundation, Inc. does NOT have a copyright over Pthreads-win32, + only the COPYING.LIB that is supplied with pthreads-win32. + + The file tests/rwlock7.c is derived from code written by + Dave Butenhof for his book 'Programming With POSIX(R) Threads'. + The original code was obtained by free download from his website + http://home.earthlink.net/~anneart/family/Threads/source.html + and did not contain a copyright or author notice. It is assumed to + be freely distributable. + + In all cases one may use and distribute these exception files freely. + And because one may freely distribute the LGPL covered files, the + entire pthreads-win32 source may be freely used and distributed. + + + +General Copyleft and License info +--------------------------------- + + For general information on Copylefts, see: + + http://www.gnu.org/copyleft/ + + For information on GNU Lesser General Public Licenses, see: + + http://www.gnu.org/copyleft/lesser.html + http://www.gnu.org/copyleft/lesser.txt + + +Why pthreads-win32 did not use the GNU General Public License +------------------------------------------------------------- + + The goal of the pthreads-win32 project has been to + provide a quality and complete implementation of the POSIX + threads API for Microsoft Windows within the limits imposed + by virtue of it being a stand-alone library and not + linked directly to other POSIX compliant libraries. For + example, some functions and features, such as those based + on POSIX signals, are missing. + + Pthreads-win32 is a library, available in several different + versions depending on supported compilers, and may be used + as a dynamically linked module or a statically linked set of + binary modules. It is not an application on it's own. + + It was fully intended that pthreads-win32 be usable with + commercial software not covered by either the GPL or the LGPL + licenses. Pthreads-win32 has many contributors to it's + code base, many of whom have done so because they have + used the library in commercial or proprietry software + projects. + + Releasing pthreads-win32 under the LGPL ensures that the + library can be used widely, while at the same time ensures + that bug fixes and improvements to the pthreads-win32 code + itself is returned to benefit all current and future users + of the library. + + Although pthreads-win32 makes it possible for applications + that use POSIX threads to be ported to Win32 platforms, the + broader goal of the project is to encourage the use of open + standards, and in particular, to make it just a little easier + for developers writing Win32 applications to consider + widening the potential market for their products. diff --git a/src/pthread/COPYING.LIB b/src/pthread/COPYING.LIB new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/src/pthread/COPYING.LIB @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/pthread/Makefile b/src/pthread/Makefile new file mode 100644 index 000000000..46112397e --- /dev/null +++ b/src/pthread/Makefile @@ -0,0 +1,158 @@ +MUTEX_OBJS = \ + pthread_mutex_unlock.o \ + pthread_mutex_init.o \ + pthread_mutex_destroy.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_trylock.o + +MUTEXATTR_OBJS = \ + pthread_mutexattr_destroy.o \ + pthread_mutexattr_getkind_np.o \ + pthread_mutexattr_getpshared.o \ + pthread_mutexattr_gettype.o \ + pthread_mutexattr_init.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_setpshared.o \ + pthread_mutexattr_settype.o + +SUPPORT_OBJS = \ + pte_relmillisecs.o \ + pte_mutex_check_need_init.o \ + pte_threadDestroy.o \ + pte_new.o \ + pte_threadStart.o \ + global.o \ + pte_reuse.o \ + pthread_init.o \ + pthread_terminate.o + +THREAD_OBJS = \ + create.o \ + pthread_self.o \ + pthread_equal.o \ + pthread_join.o \ + pthread_detach.o \ + pte_detach.o \ + pte_callUserDestroyRoutines.o \ + pte_tkAssocDestroy.o \ + pthread_kill.o \ + pthread_attr_destroy.o \ + pthread_attr_getdetachstate.o \ + pthread_attr_getinheritsched.o \ + pthread_attr_getschedparam.o \ + pthread_attr_getschedpolicy.o \ + pthread_attr_getscope.o \ + pthread_attr_getstackaddr.o \ + pthread_attr_getstacksize.o \ + pthread_attr_init.o \ + pthread_attr_setdetachstate.o \ + pthread_attr_setinheritsched.o \ + pthread_attr_setschedparam.o \ + pthread_attr_setschedpolicy.o \ + pthread_attr_setscope.o \ + pthread_attr_setstackaddr.o \ + pthread_attr_setstacksize.o \ + pte_is_attr.o \ + pthread_exit.o \ + pthread_getschedparam.o \ + pthread_setschedparam.o \ + sched_get_priority_max.o \ + sched_get_priority_min.o + + +TLS_OBJS = \ + pthread_key_create.o \ + pthread_key_delete.o \ + pthread_getspecific.o \ + pthread_setspecific.o \ + pte_tkAssocCreate.o + +MISC_OBJS = \ + sched_yield.o \ + pthread_delay_np.o \ + pthread_testcancel.o \ + pte_throw.o \ + cleanup.o \ + pthread_once.o \ + pthread_num_processors_np.o \ + pte_getprocessors.o \ + pte_spinlock_check_need_init.o \ + global.o \ + pthread_timechange_handler_np.o \ + pte_cond_check_need_init.o \ + pthread_getconcurrency.o \ + pthread_setconcurrency.o \ + pte_cancellable_wait.o + +SEM_OBJS = \ + sem_close.o \ + sem_destroy.o \ + sem_getvalue.o \ + sem_init.o \ + sem_open.o \ + sem_post.o \ + sem_post_multiple.o \ + sem_timedwait.o \ + sem_trywait.o \ + sem_unlink.o \ + sem_wait.o + +BARRIER_OBJS = \ + pthread_barrier_init.o \ + pthread_barrier_destroy.o \ + pthread_barrier_wait.o \ + pthread_barrierattr_init.o \ + pthread_barrierattr_destroy.o \ + pthread_barrierattr_getpshared.o \ + pthread_barrierattr_setpshared.o \ + +SPIN_OBJS = \ + pthread_spin_destroy.o \ + pthread_spin_init.o \ + pthread_spin_lock.o \ + pthread_spin_trylock.o \ + pthread_spin_unlock.o + +CONDVAR_OBJS = \ + pthread_cond_destroy.o \ + pthread_cond_init.o \ + pthread_cond_signal.o \ + pthread_cond_wait.o \ + pthread_condattr_destroy.o \ + pthread_condattr_getpshared.o \ + pthread_condattr_init.o \ + pthread_condattr_setpshared.o + +RWLOCK_OBJS = \ + pthread_rwlock_init.o \ + pthread_rwlock_destroy.o \ + pthread_rwlock_rdlock.o \ + pthread_rwlock_timedrdlock.o \ + pthread_rwlock_timedwrlock.o \ + pthread_rwlock_tryrdlock.o \ + pthread_rwlock_trywrlock.o \ + pthread_rwlock_unlock.o \ + pthread_rwlock_wrlock.o \ + pthread_rwlockattr_init.o \ + pthread_rwlockattr_destroy.o \ + pthread_rwlockattr_getpshared.o \ + pthread_rwlockattr_setpshared.o \ + pte_rwlock_check_need_init.o \ + pte_rwlock_cancelwrwait.o + +CANCEL_OBJS = \ + pthread_cancel.o \ + pthread_setcanceltype.o \ + pthread_setcancelstate.o + +OS_OBJS = \ + nautilus_osal.o \ + tls-helper.o + +OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) + +CFLAGS += -I/home/pdinda/class/nautilus-pdinda/src/pthread + +obj-y := $(OBJS) + diff --git a/src/pthread/Makefile.PSP b/src/pthread/Makefile.PSP new file mode 100644 index 000000000..f9491e1f6 --- /dev/null +++ b/src/pthread/Makefile.PSP @@ -0,0 +1,194 @@ + +CLEANUP_TYPE=C +#CLEANUP_TYPE=CPP + +VPATH = ../..:../helper + +TARGET_LIB = libpthread-psp.a + + +MUTEX_OBJS = \ + pthread_mutex_unlock.o \ + pthread_mutex_init.o \ + pthread_mutex_destroy.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_trylock.o + +MUTEXATTR_OBJS = \ + pthread_mutexattr_destroy.o \ + pthread_mutexattr_getkind_np.o \ + pthread_mutexattr_getpshared.o \ + pthread_mutexattr_gettype.o \ + pthread_mutexattr_init.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_setpshared.o \ + pthread_mutexattr_settype.o + +SUPPORT_OBJS = \ + pte_relmillisecs.o \ + pte_mutex_check_need_init.o \ + pte_threadDestroy.o \ + pte_new.o \ + pte_threadStart.o \ + global.o \ + pte_reuse.o \ + pthread_init.o \ + pthread_terminate.o + +THREAD_OBJS = \ + create.o \ + pthread_self.o \ + pthread_equal.o \ + pthread_join.o \ + pthread_detach.o \ + pte_detach.o \ + pte_callUserDestroyRoutines.o \ + pte_tkAssocDestroy.o \ + pthread_kill.o \ + pthread_attr_destroy.o \ + pthread_attr_getdetachstate.o \ + pthread_attr_getinheritsched.o \ + pthread_attr_getschedparam.o \ + pthread_attr_getschedpolicy.o \ + pthread_attr_getscope.o \ + pthread_attr_getstackaddr.o \ + pthread_attr_getstacksize.o \ + pthread_attr_init.o \ + pthread_attr_setdetachstate.o \ + pthread_attr_setinheritsched.o \ + pthread_attr_setschedparam.o \ + pthread_attr_setschedpolicy.o \ + pthread_attr_setscope.o \ + pthread_attr_setstackaddr.o \ + pthread_attr_setstacksize.o \ + pte_is_attr.o \ + pthread_exit.o \ + pthread_getschedparam.o \ + pthread_setschedparam.o \ + sched_get_priority_max.o \ + sched_get_priority_min.o + + +TLS_OBJS = \ + pthread_key_create.o \ + pthread_key_delete.o \ + pthread_getspecific.o \ + pthread_setspecific.o \ + pte_tkAssocCreate.o + +MISC_OBJS = \ + sched_yield.o \ + pthread_delay_np.o \ + pthread_testcancel.o \ + pte_throw.o \ + cleanup.o \ + pthread_once.o \ + pthread_num_processors_np.o \ + pte_getprocessors.o \ + pte_spinlock_check_need_init.o \ + global.o \ + pthread_timechange_handler_np.o \ + pte_cond_check_need_init.o \ + pthread_getconcurrency.o \ + pthread_setconcurrency.o \ + pte_cancellable_wait.o + +SEM_OBJS = \ + sem_close.o \ + sem_destroy.o \ + sem_getvalue.o \ + sem_init.o \ + sem_open.o \ + sem_post.o \ + sem_post_multiple.o \ + sem_timedwait.o \ + sem_trywait.o \ + sem_unlink.o \ + sem_wait.o + +BARRIER_OBJS = \ + pthread_barrier_init.o \ + pthread_barrier_destroy.o \ + pthread_barrier_wait.o \ + pthread_barrierattr_init.o \ + pthread_barrierattr_destroy.o \ + pthread_barrierattr_getpshared.o \ + pthread_barrierattr_setpshared.o \ + +SPIN_OBJS = \ + pthread_spin_destroy.o \ + pthread_spin_init.o \ + pthread_spin_lock.o \ + pthread_spin_trylock.o \ + pthread_spin_unlock.o + +CONDVAR_OBJS = \ + pthread_cond_destroy.o \ + pthread_cond_init.o \ + pthread_cond_signal.o \ + pthread_cond_wait.o \ + pthread_condattr_destroy.o \ + pthread_condattr_getpshared.o \ + pthread_condattr_init.o \ + pthread_condattr_setpshared.o + +RWLOCK_OBJS = \ + pthread_rwlock_init.o \ + pthread_rwlock_destroy.o \ + pthread_rwlock_rdlock.o \ + pthread_rwlock_timedrdlock.o \ + pthread_rwlock_timedwrlock.o \ + pthread_rwlock_tryrdlock.o \ + pthread_rwlock_trywrlock.o \ + pthread_rwlock_unlock.o \ + pthread_rwlock_wrlock.o \ + pthread_rwlockattr_init.o \ + pthread_rwlockattr_destroy.o \ + pthread_rwlockattr_getpshared.o \ + pthread_rwlockattr_setpshared.o \ + pte_rwlock_check_need_init.o \ + pte_rwlock_cancelwrwait.o + +CANCEL_OBJS = \ + pthread_cancel.o \ + pthread_setcanceltype.o \ + pthread_setcancelstate.o + +OS_OBJS = \ + psp_osal.o \ + tls-helper.o + +OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) + +INCDIR = +CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper +CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX +ASFLAGS = $(CFLAGS) + +LDFLAGS = +LIBS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + + +ifeq ($(CLEANUP_TYPE),CPPXX) + +CC=psp-g++ + +pte_throw.o: pte_throw.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_throw.c -o pte_throw.o + +pte_threadStart.o: pte_threadStart.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_threadStart.c -o pte_threadStart.o + +endif + +install: $(TARGET_LIB) + @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib + @cp -v *.h `psp-config --psp-prefix`/include + @echo "Done." + diff --git a/src/pthread/Makefile~ b/src/pthread/Makefile~ new file mode 100644 index 000000000..f9491e1f6 --- /dev/null +++ b/src/pthread/Makefile~ @@ -0,0 +1,194 @@ + +CLEANUP_TYPE=C +#CLEANUP_TYPE=CPP + +VPATH = ../..:../helper + +TARGET_LIB = libpthread-psp.a + + +MUTEX_OBJS = \ + pthread_mutex_unlock.o \ + pthread_mutex_init.o \ + pthread_mutex_destroy.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_trylock.o + +MUTEXATTR_OBJS = \ + pthread_mutexattr_destroy.o \ + pthread_mutexattr_getkind_np.o \ + pthread_mutexattr_getpshared.o \ + pthread_mutexattr_gettype.o \ + pthread_mutexattr_init.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_setpshared.o \ + pthread_mutexattr_settype.o + +SUPPORT_OBJS = \ + pte_relmillisecs.o \ + pte_mutex_check_need_init.o \ + pte_threadDestroy.o \ + pte_new.o \ + pte_threadStart.o \ + global.o \ + pte_reuse.o \ + pthread_init.o \ + pthread_terminate.o + +THREAD_OBJS = \ + create.o \ + pthread_self.o \ + pthread_equal.o \ + pthread_join.o \ + pthread_detach.o \ + pte_detach.o \ + pte_callUserDestroyRoutines.o \ + pte_tkAssocDestroy.o \ + pthread_kill.o \ + pthread_attr_destroy.o \ + pthread_attr_getdetachstate.o \ + pthread_attr_getinheritsched.o \ + pthread_attr_getschedparam.o \ + pthread_attr_getschedpolicy.o \ + pthread_attr_getscope.o \ + pthread_attr_getstackaddr.o \ + pthread_attr_getstacksize.o \ + pthread_attr_init.o \ + pthread_attr_setdetachstate.o \ + pthread_attr_setinheritsched.o \ + pthread_attr_setschedparam.o \ + pthread_attr_setschedpolicy.o \ + pthread_attr_setscope.o \ + pthread_attr_setstackaddr.o \ + pthread_attr_setstacksize.o \ + pte_is_attr.o \ + pthread_exit.o \ + pthread_getschedparam.o \ + pthread_setschedparam.o \ + sched_get_priority_max.o \ + sched_get_priority_min.o + + +TLS_OBJS = \ + pthread_key_create.o \ + pthread_key_delete.o \ + pthread_getspecific.o \ + pthread_setspecific.o \ + pte_tkAssocCreate.o + +MISC_OBJS = \ + sched_yield.o \ + pthread_delay_np.o \ + pthread_testcancel.o \ + pte_throw.o \ + cleanup.o \ + pthread_once.o \ + pthread_num_processors_np.o \ + pte_getprocessors.o \ + pte_spinlock_check_need_init.o \ + global.o \ + pthread_timechange_handler_np.o \ + pte_cond_check_need_init.o \ + pthread_getconcurrency.o \ + pthread_setconcurrency.o \ + pte_cancellable_wait.o + +SEM_OBJS = \ + sem_close.o \ + sem_destroy.o \ + sem_getvalue.o \ + sem_init.o \ + sem_open.o \ + sem_post.o \ + sem_post_multiple.o \ + sem_timedwait.o \ + sem_trywait.o \ + sem_unlink.o \ + sem_wait.o + +BARRIER_OBJS = \ + pthread_barrier_init.o \ + pthread_barrier_destroy.o \ + pthread_barrier_wait.o \ + pthread_barrierattr_init.o \ + pthread_barrierattr_destroy.o \ + pthread_barrierattr_getpshared.o \ + pthread_barrierattr_setpshared.o \ + +SPIN_OBJS = \ + pthread_spin_destroy.o \ + pthread_spin_init.o \ + pthread_spin_lock.o \ + pthread_spin_trylock.o \ + pthread_spin_unlock.o + +CONDVAR_OBJS = \ + pthread_cond_destroy.o \ + pthread_cond_init.o \ + pthread_cond_signal.o \ + pthread_cond_wait.o \ + pthread_condattr_destroy.o \ + pthread_condattr_getpshared.o \ + pthread_condattr_init.o \ + pthread_condattr_setpshared.o + +RWLOCK_OBJS = \ + pthread_rwlock_init.o \ + pthread_rwlock_destroy.o \ + pthread_rwlock_rdlock.o \ + pthread_rwlock_timedrdlock.o \ + pthread_rwlock_timedwrlock.o \ + pthread_rwlock_tryrdlock.o \ + pthread_rwlock_trywrlock.o \ + pthread_rwlock_unlock.o \ + pthread_rwlock_wrlock.o \ + pthread_rwlockattr_init.o \ + pthread_rwlockattr_destroy.o \ + pthread_rwlockattr_getpshared.o \ + pthread_rwlockattr_setpshared.o \ + pte_rwlock_check_need_init.o \ + pte_rwlock_cancelwrwait.o + +CANCEL_OBJS = \ + pthread_cancel.o \ + pthread_setcanceltype.o \ + pthread_setcancelstate.o + +OS_OBJS = \ + psp_osal.o \ + tls-helper.o + +OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) + +INCDIR = +CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper +CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX +ASFLAGS = $(CFLAGS) + +LDFLAGS = +LIBS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + + +ifeq ($(CLEANUP_TYPE),CPPXX) + +CC=psp-g++ + +pte_throw.o: pte_throw.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_throw.c -o pte_throw.o + +pte_threadStart.o: pte_threadStart.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_threadStart.c -o pte_threadStart.o + +endif + +install: $(TARGET_LIB) + @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib + @cp -v *.h `psp-config --psp-prefix`/include + @echo "Done." + diff --git a/src/pthread/cleanup.c b/src/pthread/cleanup.c new file mode 100644 index 000000000..a0eb35d57 --- /dev/null +++ b/src/pthread/cleanup.c @@ -0,0 +1,154 @@ +/* + * cleanup.c + * + * Description: + * This translation unit implements routines associated + * with cleaning up threads. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +/* + * The functions pte_pop_cleanup and pte_push_cleanup + * are implemented here for applications written in C with no + * C++ destructor support. + */ + +pte_cleanup_t * +pte_pop_cleanup (int execute) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function pops the most recently pushed cleanup + * handler. If execute is nonzero, then the cleanup handler + * is executed if non-null. + * + * PARAMETERS + * execute + * if nonzero, execute the cleanup handler + * + * + * DESCRIPTION + * This function pops the most recently pushed cleanup + * handler. If execute is nonzero, then the cleanup handler + * is executed if non-null. + * NOTE: specify 'execute' as nonzero to avoid duplication + * of common cleanup code. + * + * RESULTS + * N/A + * + * ------------------------------------------------------ + */ +{ + pte_cleanup_t *cleanup; + + cleanup = (pte_cleanup_t *) pthread_getspecific (pte_cleanupKey); + + if (cleanup != NULL) + { + if (execute && (cleanup->routine != NULL)) + { + + (*cleanup->routine) (cleanup->arg); + + } + + pthread_setspecific (pte_cleanupKey, (void *) cleanup->prev); + + } + + return (cleanup); + +} /* pte_pop_cleanup */ + + +void +pte_push_cleanup (pte_cleanup_t * cleanup, + pte_cleanup_callback_t routine, void *arg) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function pushes a new cleanup handler onto the thread's stack + * of cleanup handlers. Each cleanup handler pushed onto the stack is + * popped and invoked with the argument 'arg' when + * a) the thread exits by calling 'pthread_exit', + * b) when the thread acts on a cancellation request, + * c) or when the thread calls pthread_cleanup_pop with a nonzero + * 'execute' argument + * + * PARAMETERS + * cleanup + * a pointer to an instance of pthread_cleanup_t, + * + * routine + * pointer to a cleanup handler, + * + * arg + * parameter to be passed to the cleanup handler + * + * + * DESCRIPTION + * This function pushes a new cleanup handler onto the thread's stack + * of cleanup handlers. Each cleanup handler pushed onto the stack is + * popped and invoked with the argument 'arg' when + * a) the thread exits by calling 'pthread_exit', + * b) when the thread acts on a cancellation request, + * c) or when the thrad calls pthread_cleanup_pop with a nonzero + * 'execute' argument + * NOTE: pthread_push_cleanup, pte_pop_cleanup must be paired + * in the same lexical scope. + * + * RESULTS + * pthread_cleanup_t * + * pointer to the previous cleanup + * + * ------------------------------------------------------ + */ +{ + cleanup->routine = routine; + cleanup->arg = arg; + + cleanup->prev = (pte_cleanup_t *) pthread_getspecific (pte_cleanupKey); + + pthread_setspecific (pte_cleanupKey, (void *) cleanup); + +} /* pte_push_cleanup */ diff --git a/src/pthread/create.c b/src/pthread/create.c new file mode 100644 index 000000000..1cb6539ab --- /dev/null +++ b/src/pthread/create.c @@ -0,0 +1,259 @@ +/* + * create.c + * + * Description: + * This translation unit implements routines associated with spawning a new + * thread. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pte_osal.h" +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), void *arg) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a thread running the start function, + * passing it the parameter value, 'arg'. The 'attr' + * argument specifies optional creation attributes. + * The identity of the new thread is returned + * via 'tid', which should not be NULL. + * + * PARAMETERS + * tid + * pointer to an instance of pthread_t + * + * attr + * optional pointer to an instance of pthread_attr_t + * + * start + * pointer to the starting routine for the new thread + * + * arg + * optional parameter passed to 'start' + * + * + * DESCRIPTION + * This function creates a thread running the start function, + * passing it the parameter value, 'arg'. The 'attr' + * argument specifies optional creation attributes. + * The identity of the new thread is returned + * via 'tid', which should not be the NULL pointer. + * + * RESULTS + * 0 successfully created thread, + * EINVAL attr invalid, + * EAGAIN insufficient resources. + * + * ------------------------------------------------------ + */ +{ + pthread_t thread; + pte_thread_t * tp; + register pthread_attr_t a; + int result = EAGAIN; + int run = PTE_TRUE; + ThreadParms *parms = NULL; + long stackSize; + int priority = 0; + pthread_t self; + pte_osResult osResult; + + /* + * Before doing anything, check that tid can be stored through + * without invoking a memory protection error (segfault). + * Make sure that the assignment below can't be optimised out by the compiler. + * This is assured by conditionally assigning *tid again at the end. + */ + if (tid != NULL) + { + tid->x = 0; + } + + if (attr != NULL) + { + a = *attr; + } + else + { + a = NULL; + } + + if ((thread = pte_new ()).p == NULL) + { + goto FAIL0; + } + + tp = (pte_thread_t *) thread.p; + + priority = tp->sched_priority; + + if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL) + { + goto FAIL0; + } + + parms->tid = thread; + parms->start = start; + parms->arg = arg; + + if (a != NULL) + { + stackSize = a->stacksize; + tp->detachState = a->detachstate; + priority = a->param.sched_priority; + + if ( (priority > pte_osThreadGetMaxPriority()) || + (priority < pte_osThreadGetMinPriority()) ) + { + result = EINVAL; + goto FAIL0; + } + + /* Everything else */ + + /* + * Thread priority must be set to a valid system level + * without altering the value set by pthread_attr_setschedparam(). + */ + + if (PTHREAD_INHERIT_SCHED == a->inheritsched) + { + /* + * If the thread that called pthread_create() is an OS thread + * then the inherited priority could be the result of a temporary + * system adjustment. This is not the case for POSIX threads. + */ + self = pthread_self (); + priority = ((pte_thread_t *) self.p)->sched_priority; + } + + + } + else + { + /* + * Default stackSize + */ + stackSize = PTHREAD_STACK_MIN; + + } + + tp->state = run ? PThreadStateInitial : PThreadStateSuspended; + + tp->keys = NULL; + + /* + * Threads must be started in suspended mode and resumed if necessary + * after _beginthreadex returns us the handle. Otherwise we set up a + * race condition between the creating and the created threads. + * Note that we also retain a local copy of the handle for use + * by us in case thread.p->threadH gets NULLed later but before we've + * finished with it here. + */ + result = pthread_mutex_lock (&tp->threadLock); + + if (0 == result) + { + /* + * Must record the thread's sched_priority as given, + * not as finally adjusted. + */ + tp->sched_priority = priority; + + (void) pthread_mutex_unlock (&tp->threadLock); + } + + osResult = pte_osThreadCreate(pte_threadStart, + stackSize, + priority, + parms, + &(tp->threadId)); + + if (osResult == PTE_OS_OK) + { + pte_osThreadStart(tp->threadId); + result = 0; + } + else + { + tp->threadId = 0; + result = EAGAIN; + goto FAIL0; + } + + /* + * Fall Through Intentionally + */ + + /* + * ------------ + * Failure Code + * ------------ + */ + +FAIL0: + if (result != 0) + { + + pte_threadDestroy (thread); + tp = NULL; + + if (parms != NULL) + { + free (parms); + } + } + else + { + if (tid != NULL) + { + *tid = thread; + } + } + + return (result); + +} /* pthread_create */ diff --git a/src/pthread/doc/Doxyfile b/src/pthread/doc/Doxyfile new file mode 100644 index 000000000..c80574b00 --- /dev/null +++ b/src/pthread/doc/Doxyfile @@ -0,0 +1,281 @@ +# Doxyfile 1.5.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = PTE +PROJECT_NUMBER = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class " \ + "The $name widget " \ + "The $name file " \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/jason/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text " +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/jason/Projects/pthreads/pte_generic_osal.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = /home/jason/Temp/header.txt +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +HTML_DYNAMIC_SECTIONS = YES +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/pthread/doc/doxygen.css b/src/pthread/doc/doxygen.css new file mode 100644 index 000000000..c7db1a8a0 --- /dev/null +++ b/src/pthread/doc/doxygen.css @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; + white-space: nowrap; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } diff --git a/src/pthread/doc/pte_dspbios.html b/src/pthread/doc/pte_dspbios.html new file mode 100644 index 000000000..488b963bc --- /dev/null +++ b/src/pthread/doc/pte_dspbios.html @@ -0,0 +1,108 @@ + +PTE on DSP/BIOS
PTE on DSP/BIOS + + + + +


+

+

The DSP/BIOS OSAL is relatively +straightforward and maps relatively cleanly to the DSP/BIOS API. For +instance, most mutex and semaphore operations are supported directly +using the LCK and SEM API's. Specific details and exceptions are +described below.

+

Threads

+

Thread creation

+

OsThreadCreate allocates a dspbiosThreadData structure that +contains semaphores used for joining to a thread, cancelling a thread +and the initial priority requested by the user. A pointer to this +structure is stored as a TLS value. +

+

OsThreadCreate must create threads in a suspended state. In +DSP/BIOS this is done by setting the initial priority to zero. The +initial priority is stored in the per thread control data. When +OsThreadStart is called, it retrieves the initial priority from the +control data attached to the thread and then sets the priority of the +thread, which starts execution.

+

Thread termination

+

In order for pthread_join to wait for a thread, OsThreadWaitForEnd +is called. Since DSP/BIOS doesn't have a explicit system call for +this, we emulate it using a semaphore that is posted to when the +thread exits. This semaphore is saved in the per thread control +structure.

+

Thread cleanup

+


+

+

The PTE library calls OsThreadDelete +to signal to the OSAL that the resources for a task can be freed. +For DSP/BIOS, this means a call to TSK_delete (task resources are not +automatically freed by DSP/BIOS when the thread exits).

+


+

+

OsThreadDelete +will be called at a number of points. For attached threads, it will +be called when pthread_join +is called and returns or when pthread_detach +is called for a terminated thread. For detached threads +OsThreadDelete +will be called when the thread exits.

+


+

+

The +problem is that TSK_delete +naturally can not be called from the same context as the thread that +we're trying to free. For the first two cases (pthread_join +and pthread_detach) +this is not a problem as these will always be called from another +thread. However, for detached threads OsThreadDelete +will be called from the same context.

+


+

+

To +work around it, the DSP/BIOS OSAL includes a low priority that will +clean up detached threads. If OsThreadDelete +detects that it is being called from the same context, it will post a +message to a mailbox that the garbage collector thread is waiting on. + The garbage collector thread will then call TSK_delete +for that thread, as well as to clean up any resources that were +allocated when the thread was created.

+


+

+

Thread Local Storage

+


+

+

TLS is implemented using the +“environment” of DSP/BIOS threads. This allows a single value to +be associated with a thread. The TLS helper routines are used to +provide full TLS functionality; these routines allocate a structure +that holds multiple TLS keys and values. The DSP/BIOS environment is +used to hold a pointer to this structure.

+


+

+

Thread Cancellation

+


+

+

Since DSP/BIOS does not natively +provide a way to break out of blocked operations, this functionality +is emulated using a cancellation semaphore that is stored in the per +thread control data. When the user requests that a thread be +canceled (i.e. OsThreadCancel +is called) this semaphore is posted to. In +OsSemaphoreCancellablePend, +the cancellation semaphore as well as the user semaphore are polled +(rather than blocking) and the routine returns if the cancellation +semaphore is posted to.

+ \ No newline at end of file diff --git a/src/pthread/doc/pte_main.html b/src/pthread/doc/pte_main.html new file mode 100644 index 000000000..5899b02f1 --- /dev/null +++ b/src/pthread/doc/pte_main.html @@ -0,0 +1,12 @@ + + +POSIX Threads for embedded systems (PTE) + + +
POSIX Threads for embedded systems (PTE)

PTE is an open source implementation of the POSIX API +for multithreaded applications (pthreads).  It is intended to be +used to provide a pthreads API for embedded operating systems that +do not natively provide a pthreads API. PTE is designed to be easily +portable to such operating systems and only relies on basic primitives +(e.g. semaphores) that are widely supported on most embedded operating +systems.

Currently, PTE has been ported to Texas Instrument's DSP/BIOS and Sony's PSP OS.

PTE is based heavily on Pthreads Win32, and implementation of pthreads for Windows.

Download
Contact

Documentation
User's Manual
Porting Guide
Notes on DSP/BIOS port
Notes on PSP OS port




\ No newline at end of file diff --git a/src/pthread/doc/pte_osal_api.html b/src/pthread/doc/pte_osal_api.html new file mode 100644 index 000000000..f80792748 --- /dev/null +++ b/src/pthread/doc/pte_osal_api.html @@ -0,0 +1,1190 @@ + + +PTE: Projects/pthreads/pte_generic_osal.h File Reference + + + + +
+ +
+

Projects/pthreads/pte_generic_osal.h File Reference

+

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Misc



enum  pte_osResult {
+  PTE_OS_OK = 0, +PTE_OS_NO_RESOURCES, +PTE_OS_GENERAL_FAILURE, +PTE_OS_TIMEOUT, +
+  PTE_OS_INTERRUPTED, +PTE_OS_INVALID_PARAM +
+ }
pte_osResult pte_osInit (void)

Threads



typedef int(* pte_osThreadEntryPoint )(void *params)
pte_osResult pte_osThreadCreate (pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle *ppte_osThreadHandle)
pte_osResult pte_osThreadStart (pte_osThreadHandle osThreadHandle)
void pte_osThreadExit ()
pte_osResult pte_osThreadWaitForEnd (pte_osThreadHandle threadHandle)
pte_osThreadHandle pte_osThreadGetHandle (void)
int pte_osThreadGetPriority (pte_osThreadHandle threadHandle)
pte_osResult pte_osThreadSetPriority (pte_osThreadHandle threadHandle, int newPriority)
pte_osResult pte_osThreadDelete (pte_osThreadHandle handle)
pte_osResult pte_osThreadExitAndDelete (pte_osThreadHandle handle)
pte_osResult pte_osThreadCancel (pte_osThreadHandle threadHandle)
pte_osResult pte_osThreadCheckCancel (pte_osThreadHandle threadHandle)
void pte_osThreadSleep (unsigned int msecs)
int pte_osThreadGetMaxPriority ()
int pte_osThreadGetMinPriority ()
int pte_osThreadGetDefaultPriority ()

Functions

Mutexes


pte_osResult pte_osMutexCreate (pte_osMutexHandle *pHandle)
pte_osResult pte_osMutexDelete (pte_osMutexHandle handle)
pte_osResult pte_osMutexLock (pte_osMutexHandle handle)
pte_osResult pte_osMutexTimedLock (pte_osMutexHandle handle, unsigned int timeoutMsecs)
pte_osResult pte_osMutexUnlock (pte_osMutexHandle handle)
Semaphores


pte_osResult pte_osSemaphoreCreate (int initialValue, pte_osSemaphoreHandle *pHandle)
pte_osResult pte_osSemaphoreDelete (pte_osSemaphoreHandle handle)
pte_osResult pte_osSemaphorePost (pte_osSemaphoreHandle handle, int count)
pte_osResult pte_osSemaphorePend (pte_osSemaphoreHandle handle, unsigned int *pTimeout)
pte_osResult pte_osSemaphoreCancellablePend (pte_osSemaphoreHandle handle, unsigned int *pTimeout)
Thread Local Storage


pte_osResult pte_osTlsSetValue (unsigned int key, void *value)
void * pte_osTlsGetValue (unsigned int key)
void pte_osTlsInit (void)
pte_osResult pte_osTlsAlloc (unsigned int *pKey)
pte_osResult pte_osTlsFree (unsigned int key)
Atomic operations


int pte_osAtomicExchange (int *pTarg, int val)
int pte_osAtomicCompareExchange (int *pdest, int exchange, int comp)
int pte_osAtomicExchangeAdd (int volatile *pdest, int value)
int pte_osAtomicDecrement (int *pdest)
+


Typedef Documentation

+ +
+
+ + + + +
typedef int(* pte_osThreadEntryPoint)(void *params)
+
+
+ +

+ +

+

+


Enumeration Type Documentation

+ +
+
+ + + + +
enum pte_osResult
+
+
+ +

+

Enumerator:
+ + + + + + + +
PTE_OS_OK  +Operation completed successfully
PTE_OS_NO_RESOURCES  +Operation failed because there insufficient resources
PTE_OS_GENERAL_FAILURE  +Operation failed due to a general failure
PTE_OS_TIMEOUT  +Operation did not complete because a user specified timeout expired.
PTE_OS_INTERRUPTED  +The operation was interrupted before it could complete.
PTE_OS_INVALID_PARAM  +An invalid parameter was specified
+
+ +
+

+


Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int pte_osAtomicCompareExchange (int *  pdest,
int  exchange,
int  comp 
)
+
+
+ +

+Performs an atomic compare-and-exchange oepration on the specified value. That is:

+

 origVal = *pdest
+ if (*pdest == comp)
+   then *pdest = exchange
+ return origVal
+

+

Parameters:
+ + + + +
pdest Pointer to the destination value.
exchange Exchange value (value to set destination to if destination == comparand)
comp The value to compare to destination.
+
+
Returns:
Original value of destination
+ +
+

+ +

+
+ + + + + + + + + +
int pte_osAtomicDecrement (int *  pdest  ) 
+
+
+ +

+Decrements the destination.

+

 origVal = *pdest
+ *pdest++
+ return origVal
+

+

Parameters:
+ + +
pdest Destination value to decrement
+
+
Returns:
Original destination value
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
int pte_osAtomicExchange (int *  pTarg,
int  val 
)
+
+
+ +

+Sets the target to the specified value as an atomic operation.

+

 origVal = *ptarg
+ *ptarg = val
+ return origVal
+

+

Parameters:
+ + + +
pTarg Pointer to the value to be exchanged.
val Value to be exchanged
+
+
Returns:
original value of destination
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
int pte_osAtomicExchangeAdd (int volatile *  pdest,
int  value 
)
+
+
+ +

+Adds the value to target as an atomic operation

+

 origVal = *pdest
+ *pAddend += value
+ return origVal
+

+

Parameters:
+ + + +
pdest Pointer to the variable to be updated.
value Value to be added to the variable.
+
+
Returns:
Original value of destination
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osInit (void   ) 
+
+
+ +

+Provides a hook for the OSAL to implement any OS specific initialization. This is guaranteed to be called before any other OSAL function. +

+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osMutexCreate (pte_osMutexHandle *  pHandle  ) 
+
+
+ +

+Creates a mutex

+

Parameters:
+ + +
pHandle Set to the handle of the newly created mutex.
+
+
Returns:
PTE_OS_OK - Mutex successfully created

+PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex

+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osMutexDelete (pte_osMutexHandle  handle  ) 
+
+
+ +

+Deletes a mutex and frees any associated resources.

+

Parameters:
+ + +
handle Handle of mutex to delete.
+
+
Returns:
PTE_OS_OK - Mutex successfully deleted.
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osMutexLock (pte_osMutexHandle  handle  ) 
+
+
+ +

+Locks the mutex

+

Parameters:
+ + +
handle Handle of mutex to lock.
+
+
Returns:
PTE_OS_OK - Mutex successfully locked.
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osMutexTimedLock (pte_osMutexHandle  handle,
unsigned int  timeoutMsecs 
)
+
+
+ +

+Locks the mutex, returning after timeoutMsecs if the resources is not available. Can be used for polling mutex by using timeoutMsecs of zero.

+

Parameters:
+ + + +
handle Handle of mutex to lock.
timeoutMsecs Number of milliseconds to wait for resource before returning.
+
+
Returns:
PTE_OS_OK - Mutex successfully locked.

+PTE_OS_TIMEOUT - Timeout expired before lock was obtained.

+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osMutexUnlock (pte_osMutexHandle  handle  ) 
+
+
+ +

+Unlocks the mutex

+

Parameters:
+ + +
handle Handle of mutex to unlock
+
+
Returns:
PTE_OS_OK - Mutex successfully unlocked.
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osSemaphoreCancellablePend (pte_osSemaphoreHandle  handle,
unsigned int *  pTimeout 
)
+
+
+ +

+Acquire a semaphore, returning after timeoutMsecs if the semaphore is not available. Can be used for polling a semaphore by using timeoutMsecs of zero. Call must return immediately if pte_osThreadCancel() is called on the thread waiting for the semaphore.

+

Parameters:
+ + + +
handle Handle of semaphore to acquire.
pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore before returning. If set to NULL, wait forever.
+
+
Returns:
PTE_OS_OK - Semaphore successfully acquired.

+PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained.

+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osSemaphoreCreate (int  initialValue,
pte_osSemaphoreHandle *  pHandle 
)
+
+
+ +

+Creates a semaphore

+

Parameters:
+ + + +
initialValue Initial value of the semaphore
pHandle Set to the handle of the newly created semaphore.
+
+
Returns:
PTE_OS_OK - Semaphore successfully created

+PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore

+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osSemaphoreDelete (pte_osSemaphoreHandle  handle  ) 
+
+
+ +

+Deletes a semaphore and frees any associated resources.

+

Parameters:
+ + +
handle Handle of semaphore to delete.
+
+
Returns:
PTE_OS_OK - Semaphore successfully deleted.
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osSemaphorePend (pte_osSemaphoreHandle  handle,
unsigned int *  pTimeout 
)
+
+
+ +

+Acquire a semaphore, returning after timeoutMsecs if the semaphore is not available. Can be used for polling a semaphore by using timeoutMsecs of zero.

+

Parameters:
+ + + +
handle Handle of semaphore to acquire.
pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore before returning. If set to NULL, wait forever.
+
+
Returns:
PTE_OS_OK - Semaphore successfully acquired.

+PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained.

+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osSemaphorePost (pte_osSemaphoreHandle  handle,
int  count 
)
+
+
+ +

+Posts to the semaphore

+

Parameters:
+ + + +
handle Semaphore to release
count Amount to increment the semaphore by.
+
+
Returns:
PTE_OS_OK - semaphore successfully released.
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadCancel (pte_osThreadHandle  threadHandle  ) 
+
+
+ +

+Cancels the specified thread. This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel() to return PTE_OS_INTERRUPTED.

+

Parameters:
+ + +
threadHandle handle to the thread to cancel.
+
+
Returns:
Thread successfully canceled.
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadCheckCancel (pte_osThreadHandle  threadHandle  ) 
+
+
+ +

+Check if pte_osThreadCancel() has been called on the specified thread.

+

Parameters:
+ + +
threadHandle handle of thread to check the state of.
+
+
Returns:
PTE_OS_OK - Thread has not been cancelled

+PTE_OS_INTERRUPTED - Thread has been cancelled.

+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pte_osResult pte_osThreadCreate (pte_osThreadEntryPoint  entryPoint,
int  stackSize,
int  initialPriority,
void *  argv,
pte_osThreadHandle *  ppte_osThreadHandle 
)
+
+
+ +

+Creates a new thread. The thread must be started in a suspended state - it will be explicitly started when pte_osThreadStart() is called.

+

Parameters:
+ + + + + + +
entryPoint Entry point to the new thread.
stackSize The initial stack size, in bytes. Note that this can be considered a minimum - for instance if the OS requires a larger stack space than what the caller specified.
initialPriority The priority that the new thread should be initially set to.
argv Parameter to pass to the new thread.
ppte_osThreadHandle set to the handle of the new thread.
+
+
Returns:
PTE_OS_OK - New thread successfully created.

+PTE_OS_NO_RESOURCESs - Insufficient resources to create thread

+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadDelete (pte_osThreadHandle  handle  ) 
+
+
+ +

+Frees resources associated with the specified thread. This is called after the thread has terminated and is no longer needed (e.g. after pthread_join returns). This call will always be made from a different context than that of the target thread. +

+

+ +

+
+ + + + + + + + +
void pte_osThreadExit (  ) 
+
+
+ +

+Causes the current thread to stop executing.

+

Returns:
Never returns (thread terminated)
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadExitAndDelete (pte_osThreadHandle  handle  ) 
+
+
+ +

+Frees resources associated with the specified thread and then causes the thread to exit. This is called after the thread has terminated and is no longer needed (e.g. after pthread_join returns). This call will always be made from the context of the target thread. +

+

+ +

+
+ + + + + + + + +
int pte_osThreadGetDefaultPriority (  ) 
+
+
+ +

+Returns the priority that should be used if the caller to pthread_create doesn't explicitly set one. +

+

+ +

+
+ + + + + + + + + +
pte_osThreadHandle pte_osThreadGetHandle (void   ) 
+
+
+ +

+Returns the handle of the currently executing thread. +

+

+ +

+
+ + + + + + + + +
int pte_osThreadGetMaxPriority (  ) 
+
+
+ +

+Returns the maximum allowable priority +

+

+ +

+
+ + + + + + + + +
int pte_osThreadGetMinPriority (  ) 
+
+
+ +

+Returns the minimum allowable priority +

+

+ +

+
+ + + + + + + + + +
int pte_osThreadGetPriority (pte_osThreadHandle  threadHandle  ) 
+
+
+ +

+Returns the priority of the specified thread. +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osThreadSetPriority (pte_osThreadHandle  threadHandle,
int  newPriority 
)
+
+
+ +

+Sets the priority of the specified thread.

+

Returns:
PTE_OS_OK - thread priority successfully set
+ +
+

+ +

+
+ + + + + + + + + +
void pte_osThreadSleep (unsigned int  msecs  ) 
+
+
+ +

+Causes the current thread to sleep for the specified number of milliseconds. +

+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadStart (pte_osThreadHandle  osThreadHandle  ) 
+
+
+ +

+Starts executing the specified thread.

+

Parameters:
+ + +
osThreadHandle handle of the thread to start.
+
+
Returns:
PTE_OS_OK - thread successfully started.
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osThreadWaitForEnd (pte_osThreadHandle  threadHandle  ) 
+
+
+ +

+Waits for the specified thread to end. If the thread has already terminated, this returns immediately.

+

Parameters:
+ + +
threadHandle Handle fo thread to wait for.
+
+
Returns:
PTE_OS_OK - specified thread terminated.
+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osTlsAlloc (unsigned int *  pKey  ) 
+
+
+ +

+Allocates a new TLS key.

+

Parameters:
+ + +
pKey On success will be set to the newly allocated key.
+
+
Returns:
PTE_OS_OK - TLS key successfully allocated.

+PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g. maximum number of keys reached).

+ +
+

+ +

+
+ + + + + + + + + +
pte_osResult pte_osTlsFree (unsigned int  key  ) 
+
+
+ +

+Frees the specified TLS key.

+

Parameters:
+ + +
index TLS key to free
+
+
Returns:
PTE_OS_OK - TLS key was successfully freed.
+ +
+

+ +

+
+ + + + + + + + + +
void* pte_osTlsGetValue (unsigned int  key  ) 
+
+
+ +

+Retrieves the thread specific value for the specified key for the currently executing thread. If a value has not been set for this key, NULL should be returned (i.e. TLS values default to NULL).

+

Parameters:
+ + +
index The TLS key for the value.
+
+
Returns:
The value associated with key for the current thread.
+ +
+

+ +

+
+ + + + + + + + + +
void pte_osTlsInit (void   ) 
+
+
+ +

+Initializes the OS TLS support. This is called by the PTE library prior to performing ANY TLS operation. +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
pte_osResult pte_osTlsSetValue (unsigned int  key,
void *  value 
)
+
+
+ +

+Sets the thread specific value for the specified key for the currently executing thread.

+

Parameters:
+ + + +
index The TLS key for the value.
value The value to save
+
+ +
+

+


Generated on Mon Apr 7 21:56:48 2008 for PTE by  + +doxygen 1.5.3
+ + diff --git a/src/pthread/doc/pte_porting_guide.html b/src/pthread/doc/pte_porting_guide.html new file mode 100644 index 000000000..d9f22be65 --- /dev/null +++ b/src/pthread/doc/pte_porting_guide.html @@ -0,0 +1,267 @@ + +PTE Porting Guide + + + + + + + + + + + +


+

+

Pthreads-Embedded (PTE) Porting +Guide

+

The PTE library consists of both a platform independent component, +which contains the bulk of the pthreads functionality, and a platform +specific component which connects the platform independent component +to the underlying OS. Naturally, the platform specific layer is the +only layer that needs to be modified when porting PTE.

+

The OS adaptation layer (OSAL) must provide the following +functionality:

+
  1. Threads

    +
  2. Semaphores

    +
  3. Mutexes

    +
  4. Atomic operations

    +
  5. Thread local storage

    +
+

The underlying OS does not necessarily have to provide all of this +functionality – it is possible for the OSAL to emulate behavior. +For instance, mutexes can be emulated using semaphores provided by +the OS. The sections below present a high level of the required +functionality as well as how it fits into a “typical” embedded +OS. Specifics such as function parameters, etc are covered in the +OSAL API reference.

+

Threads

+

Thread Initialization

+

OsThreadCreate, OsThreadStart

+

Thread initialization is separated into two steps: create and +start. When OSThreadCreate +is called, the OS should create a new thread, but it must be started +in a suspended state. The thread should not start executing until +OSThreadStart is called. +This separation in functionality is due necessary to avoid race +condFor instance, if the target OS supports TLS but only allows a +single TLS value, this single value could contain a pointer to a +structure that contains multiple TLS values. The PTE distribution +includes a helper file to implement this functionality +(/platform/helper/tls-helper.c). See the DSP/BIOS port for an +example of using tls-helper.c.itions in the PTE library.

+

Since the actual prototype of an +thread entry point varies between OS and thus will more than likely +not match that used by +OsThreadCreate, +it will usually be necessary to create a stub function that matches +your OS's entry point prototype. This stub function simply calls the +entry point specified by OsThreadCreate +(see DSP/BIOS and PSP-OS ports).

+

Typically, OsThreadCreate will also perform other initialization; +for instance to initialize TLS structures, allocate other control +resources. This of course varies depending on the target OS. +

+

Some OS's require additional parameters to start a thread. For +instance, DSP/BIOS requires the priority in order to start the +thread. Rather than pass these parameters to both OsThreadCreate +and OsThreadStart, the +OSAL should store any necessary information as thread specific values +during OsThreadCreate and +then retrieve them as necessary in OsThreadStart.

+



+

+

Thread Destruction

+

OsThreadExit, OsThreadDelete, +OsThreadExitAndDelete, OsThreadWaitForEnd

+

Thread destruction is broken into three API calls to support the +different use cases of the pthreads API. OsThreadExit +should cause the currently executing thread to stop execution; +resources should not yet be freed. This is called when a thread +exits but the thread is not detached – resource deallocation must +wait until the user calls pthread_join +(or pthread_detach) at +which point OsThreadDelete +will be called.

+

Alternatively, if a detached thread exits, thread resource +deallocation and thread termination can occur simultaneously. In +this case, OsThreadExitAndDelete +will be called.

+

OsThreadWaitForEnd +should block until the specified thread exists. For OS's that do not +directly support this functionality, a semaphore can be used to +emulate this behavior (see DSP/BIOS port). Note that this call +should be cancellable – that is, it should return (even if the +target thread has not exited) if OsThreadCancel +is called.

+

Thread Priority

+

OsThreadSetPriority, OsThreadGetPriority, +OsThreadGetMaxPriority, OsThreadGetMinPriority

+

The OSAL provides the upper and lower bounds of it's priority +range when OsThreadGetMaxPriority +and OsThreadGetMinPriority +are called. The PTE library will ensure that all priorities passed +to the OSAL (e.g. through OsThreadCreate) +are within these bounds.

+

Thread Cancellation

+

OsThreadCancel, OsThreadCheckCancel

+

Currently, the PTE library only supports deferred cancellation +(see PTE notes). While the PTE library handles most of the +complexities of cancellation, there are three hooks required from the +OSAL. When OsThreadCancel +is called, it must cause OsSemaphorePendCancellable +and OsThreadWaitForEnd to +return (this function is used by the PTE library to implement pthread +cancellation points). Since most embedded OS's do not support this +kind of functionality, it can be implemented using semaphores (see +DSP/BIOS and PSP-OS ports). OsThreadCheckCancel +simply returns whether OsThreadCancel +has been called for this thread.

+

Miscellaneous Thread Functionality

+ +

OsThreadGetHandle, OsThreadSleep, +OsThreadGetMaxPriority, OsThreadGetMinPriority, +OsThreadGetDefaultPriority

+

+

+

Semaphores

+



+

+

OsSemaphoreCreate, OsSemaphoreDelete, +OsSemaphorePend, OsSemaphorePort

+

This basic semaphore functionality should map directly to almost +all embedded OS's. +

+

OsSemaphoreCancellablePend

+

In order to implement deferred cancellation, a “cancellable” +pend (OsSemaphorePendCancellable) +must also be supported. As discussed above, +OsSemaphorePendCancellable +must return when OsThreadCancel +has been called on the thread that is currently pending, regardless +of whether the semaphore has been posted to or not. The way that this +is implemented in other ports (e.g. DSP/BIOS and PSP-OS) is to use an +additional semaphore, and then poll on both semaphores, as shown in +the pseudo-code below:

+ +

loop forever:

+

poll main semaphore

+

if semaphore was posted to, +return OK

+

else

+

check timeout

+

if timeout has expired, return +'timed out'

+

else

+

poll cancellation semaphore +

+

if cancellation semaphore has +been posted to, return 'canceled'

+

else

+

sleep for small amount of time

+

For instance, if the target OS supports TLS but only allows a +single TLS value, this single value could contain a pointer to a +structure that contains multiple TLS values. The PTE distribution +includes a helper file to implement this functionality +(/platform/helper/tls-helper.c). See the DSP/BIOS port for an +example of using tls-helper.c.

+

Mutexes

+

Mutexes are only included as an optimization as some OS's mutex +operation is much faster than semaphore operations. If the target OS +does not support mutexes, they can easily be implemented using +semaphores.

+



+

+

Atomic operations

+

OsAtomicExchange, OsAtomicCompareExchange, +OsAtomicExchangeIncrement, OsAtomicDecrement, OsAtomicIncrement

+

The PTE library requires five atomic operations to be +supplied by the OSAL. Macros are used in case the target platform +supports direct assembly instructions to perform some or all of these +operations. However, under most OS's these macros will simply refer +to functions that disable interrupts and then perform the required +operations.

+



+

+

Thread local storage

+

OsTlsInit, OsTlsAlloc, OsTlsFree, +OsTlsSetValue, OsTlsGetValue

+

The OSAL must be able to allocate and free TLS keys, and retrieve +thread specific data. If the target OS does not support this level +of TLS functionality, but does have limited TLS support, it is +possible to emulate the behavior required by the PTE library.

+

For instance, if the target OS supports TLS but only allows a +single TLS value, this single value could contain a pointer to a +structure that contains multiple TLS values. The PTE distribution +includes a helper file to implement this functionality +(/platform/helper/tls-helper.c). See the DSP/BIOS port for an +example of using tls-helper.c.

+

If the OS contains no TLS support, it might still be possible to +emulate TLS functionality. See the PSP-OS port for an example of how +this can be accomplished. Be warned – it is not a pretty solution, +but it works.

+

It is important to note that TLS functionality is required by +the PTE library – it is used for more than just the pthread TLS +functions, but is used extensively throughout the library.

+

One potentially tricky issue with TLS +is how to handle the case of when pthread TLS functions are called +from non-pthread threads (i.e. pure native threads that were not +created through pthread_create). Technically, according to the +pthread spec, this should work. However, it is problematic in that +OsTlsInit would not have been called for that thread, since it is +called in response to pthread_create(). Different ports handle this +differently – see the notes for a particular ports.

+

Miscellaneous Functionality

+

ftime

+

Since pthreads uses absolute time for timeouts, the PTE library +requires the OS to supply the current time. Note that this does not +have to be the actual world time, but can be an internal timebase +(for example, since the unit started up). However, the time source +should be the same one that the caller to pthread would use.

+

Types and Constants

+

The OSAL layer must declare a number of types and +constants. +

+

The following types must be defined to map to the +appropriate OS constructs:

+

OsThreadHandle

+

OsSemaphoreHandle

+ +

OsMutexHandle


+

+

The following constants must be defined:

+

OS_DEFAULT_PRIO +– default priority for a created thread.

+

OS_MIN_PRIO +– minimum thread priority.

+

OS_MAX_PRIO +– maximum thread priority.

+

OS_MAX_SIMUL_THREADS +– maximum number of threads that may be active simultaneously.

+



+

+

Each port must also include a file, pte_types.h, that +defines all of the following types. This may be done by explicitly +typedef'ing the structure (for OS's that do not natively support the +type) or simply by including the appropriate header file:

+

pid_t

+

struct timespec

+

mode_t

+

struct timeb

+

File structure

+

The OSAL layer must include a file named pte_osal.h. +This file must include pte_generic_osal.h as well as the platform +specific header file (e.g. dspbios_osal.h).

+ \ No newline at end of file diff --git a/src/pthread/doc/pte_psp.html b/src/pthread/doc/pte_psp.html new file mode 100644 index 000000000..50fbdc77e --- /dev/null +++ b/src/pthread/doc/pte_psp.html @@ -0,0 +1,88 @@ + +PTE on PSP OS + + + + + + + +

PTE on PSP OS


+

+

All PSP OS objects that are created +require a name to be associated with them. The name must be unique +among objects that currently exist. To accomplish this, any routines +that allocate OS objects (e.g. OsMutexCreate) +keep a static local variable that acts as a counter and is +incremented every time an object is created. This value is appended +to the name of the resource. For instance “mutex04” would be the +name of the fourth mutex created.

+


+

+

Thread creation

+

OsThreadCreate +allocates a pspThreadData +structure that contains a semaphore used for cancelling a thread, the +thread's entry point and parameters to the thread's entry point. A +pointer to this structure is stored as a TLS value.

+

OsThreadCreate +calls sceKernelCreateThread +with a entry point of pspStubThreadEntry. + The stub entry point retrieves the per thread control structure +(allocated during OsThreadCreate) +and gets the thread's real entry point and parameters and then calls +the real entry point.

+


+

+

Thread Local Storage

+

Unfortunately, PSP OS does not include +any kind of thread local storage functionality. To emulate +TLS, when a new POSIX thread is created, a structure is allocated to +contain TLS keys and values. A pointer to this structure is appended +to the thread name. For instance, a new threads name might be +“pthread10_80001234”, where 0x80001234 is the address of the TLS +structure. When a thread wants to access TLS information, it +retrieves the thread's name from the OS, parses the name to extract +the pointer and then utilizes the TLS helper library to set or get +TLS values. +

+


+

+

Unfortunately, this mechanism only +works for threads that are created through pthread_create; it does +not work for OS threads that are using pthread calls. To emulate +this (at this for one thread) we allocate a single TLS structure +(like the ones associated with each POSIX thread). This “global” +TLS structure is used when pthread is called from a non-POSIX OS +thread. This introduces the important limitation that pthread calls +can be made from ONLY ONE non-POSIX OS thread. Behavior when calling +from multiple different non-POSIX OS threads is undefined.

+


+

+

Mutexes

+

PSP OS does not supply routines for +mutexes. A counting semaphore initialized to 0 is used.

+


+

+

Thread Cancellation

+

Since PSP OS does not natively provide +a way to break out of blocked operations, this functionality is +emulated using a cancellation semaphore that is stored in the per +thread control data. When the user requests that a thread be +cancelled (i.e. OsThreadCancel +is called) this semaphore is posted to. In +OsSemaphoreCancellablePend, +the cancellation semaphore as well as the user semaphore are polled +(rather than blocking) and the routine returns if the cancellation +semaphore is posted to. A similar technique is used for +OsThreadWaitForEnd.

+ \ No newline at end of file diff --git a/src/pthread/doc/pte_users_guide.html b/src/pthread/doc/pte_users_guide.html new file mode 100644 index 000000000..3d878d008 --- /dev/null +++ b/src/pthread/doc/pte_users_guide.html @@ -0,0 +1,33 @@ + +PTE User's Guide
PTE Users Guide

Since +PTE is designed to be cross platform, and embedded OS's vary widely in +their build methodology, there is no "high level" build structure +included.  Rather, each port is responsible for providing this. + The sections below describe using PTE for a specific platform.

While +pthreads is strictly speaking a C API, PTE does include limited support +for C++ specific features, specifically exceptions.  This +functionality was primarily inherited from the original code base +(Pthreads-win32) and has been only preliminarily tested.

An +important component of PTE is the test library that is included. + Each platform contains build files as described below to build +the test suite.

DSP/BIOS

Texas +Instruments provides DSP/BIOS as a RTOS to be used on their series of +digital signal processors.  Two project files are included: one +for the library itself and one for the test suite.  These projects +(and CDB/TCF files) were targeted towards the C6000 simulator, as this +is where I did all of the development.  When building applications +that use the PTE library, you will need to include pthreads.h and will +also need to provide a path to pte-types.h (originally located in +platforms/dspbios/pte-types.h).  This file contains definitions of +structures and types (e.g. pid_t) that are required by pthreads but not +supplied by DSP/BIOS

PSP OS

This +is the operating system used by the Sony PSP.  The PSP toolchain +is gcc based and thus shares many similarities with a "typical" UNIX +system, including the build system.  PTE includes Makefiles for +the library itself as well as the test suite.  Note that these +Makefiles are pretty rudimentary as I am not anywhere close to being a +Makefile expert.  Thus, once the library is built it will be +necessary to copy the library itself, pthread.h and pte-types.h to the +appropriate places in your projects build structure.  The PSP +toolchain includes a pthread.h header in the base distribution (why, +I'm not sure) - it is important that you use the pthread.hsupplied with PTE rather than the one in the toolchain.

\ No newline at end of file diff --git a/src/pthread/global.c b/src/pthread/global.c new file mode 100644 index 000000000..8c62e17cb --- /dev/null +++ b/src/pthread/global.c @@ -0,0 +1,98 @@ +/* + * global.c + * + * Description: + * This translation unit instantiates data associated with the implementation + * as a whole. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int pte_processInitialized = PTE_FALSE; +pte_thread_t * pte_threadReuseTop = PTE_THREAD_REUSE_EMPTY; +pte_thread_t * pte_threadReuseBottom = PTE_THREAD_REUSE_EMPTY; +pthread_key_t pte_selfThreadKey = NULL; +pthread_key_t pte_cleanupKey = NULL; +pthread_cond_t pte_cond_list_head = NULL; +pthread_cond_t pte_cond_list_tail = NULL; + +int pte_concurrency = 0; + +/* What features have been auto-detaected */ +int pte_features = 0; + +unsigned char pte_smp_system = PTE_TRUE; /* Safer if assumed true initially. */ + +/* + * Global lock for managing pthread_t struct reuse. + */ +pte_osMutexHandle pte_thread_reuse_lock; + +/* + * Global lock for testing internal state of statically declared mutexes. + */ +pte_osMutexHandle pte_mutex_test_init_lock; + +/* + * Global lock for testing internal state of PTHREAD_COND_INITIALIZER + * created condition variables. + */ +pte_osMutexHandle pte_cond_test_init_lock; + +/* + * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER + * created read/write locks. + */ +pte_osMutexHandle pte_rwlock_test_init_lock; + +/* + * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER + * created spin locks. + */ +pte_osMutexHandle pte_spinlock_test_init_lock; + +/* + * Global lock for condition variable linked list. The list exists + * to wake up CVs when a WM_TIMECHANGE message arrives. See + * w32_TimeChangeHandler.c. + */ +pte_osMutexHandle pte_cond_list_lock; + + diff --git a/src/pthread/implement.h b/src/pthread/implement.h new file mode 100644 index 000000000..25ae4f181 --- /dev/null +++ b/src/pthread/implement.h @@ -0,0 +1,516 @@ +/* + * implement.h + * + * Definitions that don't need to be public. + * + * Keeps all the internals out of pthread.h + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef _IMPLEMENT_H +#define _IMPLEMENT_H + +#include "pte_osal.h" + +/* use local include files during development */ +#include "semaphore.h" +#include "sched.h" + + +typedef enum +{ + /* + * This enumeration represents the state of the thread; + * The thread is still "alive" if the numeric value of the + * state is greater or equal "PThreadStateRunning". + */ + PThreadStateInitial = 0, /* Thread not running */ + PThreadStateRunning, /* Thread alive & kicking */ + PThreadStateSuspended, /* Thread alive but suspended */ + PThreadStateCancelPending, /* Thread alive but is */ + /* has cancelation pending. */ + PThreadStateCanceling, /* Thread alive but is */ + /* in the process of terminating */ + /* due to a cancellation request */ + PThreadStateException, /* Thread alive but exiting */ + /* due to an exception */ + PThreadStateLast +} +PThreadState; + + +typedef struct pte_thread_t_ pte_thread_t; + +struct pte_thread_t_ + { + pte_osThreadHandle threadId; /* OS specific thread handle */ + pthread_t ptHandle; /* This thread's permanent pthread_t handle */ + pte_thread_t * prevReuse; /* Links threads on reuse stack */ + volatile PThreadState state; + void *exitStatus; + void *parms; + int ptErrno; + int detachState; + pthread_mutex_t threadLock; /* Used for serialised access to public thread state */ + int sched_priority; /* As set, not as currently is */ + pthread_mutex_t cancelLock; /* Used for async-cancel safety */ + int cancelState; + int cancelType; + int cancelEvent; +#ifdef PTE_CLEANUP_C + jmp_buf start_mark; +#endif /* PTE_CLEANUP_C */ +int implicit: + 1; + void *keys; + void *nextAssoc; + }; + + +/* + * Special value to mark attribute objects as valid. + */ +#define PTE_ATTR_VALID ((unsigned long) 0xC4C0FFEE) + +struct pthread_attr_t_ + { + unsigned long valid; + void *stackaddr; + size_t stacksize; + int detachstate; + struct sched_param param; + int inheritsched; + int contentionscope; + }; + + +/* + * ==================== + * ==================== + * Semaphores, Mutexes and Condition Variables + * ==================== + * ==================== + */ + +struct sem_t_ + { + int value; + pthread_mutex_t lock; + pte_osSemaphoreHandle sem; + }; + +#define PTE_OBJECT_AUTO_INIT ((void *) -1) +#define PTE_OBJECT_INVALID 0 + +struct pthread_mutex_t_ + { + pte_osSemaphoreHandle handle; + int lock_idx; + /* Provides exclusive access to mutex state + via the Interlocked* mechanism. + 0: unlocked/free. + 1: locked - no other waiters. + -1: locked - with possible other waiters. + */ + int recursive_count; /* Number of unlocks a thread needs to perform + before the lock is released (recursive + mutexes only). */ + int kind; /* Mutex type. */ + pthread_t ownerThread; + }; + +struct pthread_mutexattr_t_ + { + int pshared; + int kind; + }; + +/* + * Possible values, other than PTE_OBJECT_INVALID, + * for the "interlock" element in a spinlock. + * + * In this implementation, when a spinlock is initialised, + * the number of cpus available to the process is checked. + * If there is only one cpu then "interlock" is set equal to + * PTE_SPIN_USE_MUTEX and u.mutex is a initialised mutex. + * If the number of cpus is greater than 1 then "interlock" + * is set equal to PTE_SPIN_UNLOCKED and the number is + * stored in u.cpus. This arrangement allows the spinlock + * routines to attempt an InterlockedCompareExchange on "interlock" + * immediately and, if that fails, to try the inferior mutex. + * + * "u.cpus" isn't used for anything yet, but could be used at + * some point to optimise spinlock behaviour. + */ +#define PTE_SPIN_UNLOCKED (1) +#define PTE_SPIN_LOCKED (2) +#define PTE_SPIN_USE_MUTEX (3) + +struct pthread_spinlock_t_ + { + int interlock; /* Locking element for multi-cpus. */ + union + { + int cpus; /* No. of cpus if multi cpus, or */ + pthread_mutex_t mutex; /* mutex if single cpu. */ + } u; + }; + +struct pthread_barrier_t_ + { + unsigned int nCurrentBarrierHeight; + unsigned int nInitialBarrierHeight; + int iStep; + int pshared; + sem_t semBarrierBreeched[2]; + }; + +struct pthread_barrierattr_t_ + { + int pshared; + }; + +struct pthread_key_t_ + { + unsigned key; + void (*destructor) (void *); + pthread_mutex_t keyLock; + void *threads; + }; + + +typedef struct ThreadParms ThreadParms; +typedef struct ThreadKeyAssoc ThreadKeyAssoc; + +struct ThreadParms + { + pthread_t tid; + void *(*start) (void *); + void *arg; + }; + +struct pthread_cond_t_ + { + long nWaitersBlocked; /* Number of threads blocked */ + long nWaitersGone; /* Number of threads timed out */ + long nWaitersToUnblock; /* Number of threads to unblock */ + sem_t semBlockQueue; /* Queue up threads waiting for the */ + /* condition to become signalled */ + sem_t semBlockLock; /* Semaphore that guards access to */ + /* | waiters blocked count/block queue */ + /* +-> Mandatory Sync.LEVEL-1 */ + pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */ + /* | waiters (to)unblock(ed) counts */ + /* +-> Optional* Sync.LEVEL-2 */ + pthread_cond_t next; /* Doubly linked list */ + pthread_cond_t prev; + }; + + +struct pthread_condattr_t_ + { + int pshared; + }; + +#define PTE_RWLOCK_MAGIC 0xfacade2 + +struct pthread_rwlock_t_ + { + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; + }; + +struct pthread_rwlockattr_t_ + { + int pshared; + }; + +/* + * MCS lock queue node - see pte_MCS_lock.c + */ +struct pte_mcs_node_t_ + { + struct pte_mcs_node_t_ **lock; /* ptr to tail of queue */ + struct pte_mcs_node_t_ *next; /* ptr to successor in queue */ + unsigned int readyFlag; /* set after lock is released by + predecessor */ + unsigned int nextFlag; /* set after 'next' ptr is set by + successor */ + }; + +typedef struct pte_mcs_node_t_ pte_mcs_local_node_t; +typedef struct pte_mcs_node_t_ *pte_mcs_lock_t; + + +struct ThreadKeyAssoc + { + /* + * Purpose: + * This structure creates an association between a thread and a key. + * It is used to implement the implicit invocation of a user defined + * destroy routine for thread specific data registered by a user upon + * exiting a thread. + * + * Graphically, the arrangement is as follows, where: + * + * K - Key with destructor + * (head of chain is key->threads) + * T - Thread that has called pthread_setspecific(Kn) + * (head of chain is thread->keys) + * A - Association. Each association is a node at the + * intersection of two doubly-linked lists. + * + * T1 T2 T3 + * | | | + * | | | + * K1 -----+-----A-----A-----> + * | | | + * | | | + * K2 -----A-----A-----+-----> + * | | | + * | | | + * K3 -----A-----+-----A-----> + * | | | + * | | | + * V V V + * + * Access to the association is guarded by two locks: the key's + * general lock (guarding the row) and the thread's general + * lock (guarding the column). This avoids the need for a + * dedicated lock for each association, which not only consumes + * more handles but requires that: before the lock handle can + * be released - both the key must be deleted and the thread + * must have called the destructor. The two-lock arrangement + * allows the resources to be freed as soon as either thread or + * key is concluded. + * + * To avoid deadlock: whenever both locks are required, the key + * and thread locks are always acquired in the order: key lock + * then thread lock. An exception to this exists when a thread + * calls the destructors, however this is done carefully to + * avoid deadlock. + * + * An association is created when a thread first calls + * pthread_setspecific() on a key that has a specified + * destructor. + * + * An association is destroyed either immediately after the + * thread calls the key destructor function on thread exit, or + * when the key is deleted. + * + * Attributes: + * thread + * reference to the thread that owns the + * association. This is actually the pointer to the + * thread struct itself. Since the association is + * destroyed before the thread exits, this can never + * point to a different logical thread to the one that + * created the assoc, i.e. after thread struct reuse. + * + * key + * reference to the key that owns the association. + * + * nextKey + * The pthread_t->keys attribute is the head of a + * chain of associations that runs through the nextKey + * link. This chain provides the 1 to many relationship + * between a pthread_t and all pthread_key_t on which + * it called pthread_setspecific. + * + * prevKey + * Similarly. + * + * nextThread + * The pthread_key_t->threads attribute is the head of + * a chain of assoctiations that runs through the + * nextThreads link. This chain provides the 1 to many + * relationship between a pthread_key_t and all the + * PThreads that have called pthread_setspecific for + * this pthread_key_t. + * + * prevThread + * Similarly. + * + * Notes: + * 1) As soon as either the key or the thread is no longer + * referencing the association, it can be destroyed. The + * association will be removed from both chains. + * + * 2) An association is only created by + * pthread_setspecific if the user provided a + * destroyRoutine when they created the key. + * + * + */ + pte_thread_t * thread; + pthread_key_t key; + ThreadKeyAssoc *nextKey; + ThreadKeyAssoc *nextThread; + ThreadKeyAssoc *prevKey; + ThreadKeyAssoc *prevThread; + }; + +/* + * Services available through EXCEPTION_PTE_SERVICES + * and also used [as parameters to pte_throw()] as + * generic exception selectors. + */ + +#define PTE_EPS_EXIT (1) +#define PTE_EPS_CANCEL (2) + + +/* Useful macros */ +#define PTE_MAX(a,b) ((a)<(b)?(b):(a)) +#define PTE_MIN(a,b) ((a)>(b)?(b):(a)) + + +/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ +#define PTE_THREAD_REUSE_EMPTY ((pte_thread_t *) 1) + +extern int pte_processInitialized; +extern pte_thread_t * pte_threadReuseTop; +extern pte_thread_t * pte_threadReuseBottom; +extern pthread_key_t pte_selfThreadKey; +extern pthread_key_t pte_cleanupKey; +extern pthread_cond_t pte_cond_list_head; +extern pthread_cond_t pte_cond_list_tail; + +extern int pte_mutex_default_kind; + +extern int pte_concurrency; + +extern int pte_features; + +extern pte_osMutexHandle pte_thread_reuse_lock; +extern pte_osMutexHandle pte_mutex_test_init_lock; +extern pte_osMutexHandle pte_cond_list_lock; +extern pte_osMutexHandle pte_cond_test_init_lock; +extern pte_osMutexHandle pte_rwlock_test_init_lock; +extern pte_osMutexHandle pte_spinlock_test_init_lock; + + +#ifdef __cplusplus +extern "C" + { +#endif /* __cplusplus */ + + /* + * ===================== + * ===================== + * Forward Declarations + * ===================== + * ===================== + */ + + int pte_is_attr (const pthread_attr_t * attr); + + int pte_cond_check_need_init (pthread_cond_t * cond); + int pte_mutex_check_need_init (pthread_mutex_t * mutex); + int pte_rwlock_check_need_init (pthread_rwlock_t * rwlock); + int pte_spinlock_check_need_init (pthread_spinlock_t * lock); + + int pte_processInitialize (void); + + void pte_processTerminate (void); + + void pte_threadDestroy (pthread_t tid); + void pte_threadExitAndDestroy (pthread_t tid); + + void pte_pop_cleanup_all (int execute); + + pthread_t pte_new (void); + + pthread_t pte_threadReusePop (void); + + void pte_threadReusePush (pthread_t thread); + + int pte_getprocessors (int *count); + + int pte_setthreadpriority (pthread_t thread, int policy, int priority); + + void pte_rwlock_cancelwrwait (void *arg); + + int pte_threadStart (void *vthreadParms); + + void pte_callUserDestroyRoutines (pthread_t thread); + + int pte_tkAssocCreate (pte_thread_t * thread, pthread_key_t key); + + void pte_tkAssocDestroy (ThreadKeyAssoc * assoc); + + int sem_wait_nocancel (sem_t * sem); + + unsigned int pte_relmillisecs (const struct timespec * abstime); + + void pte_mcs_lock_acquire (pte_mcs_lock_t * lock, pte_mcs_local_node_t * node); + + void pte_mcs_lock_release (pte_mcs_local_node_t * node); + + /* Declared in private.c */ + void pte_throw (unsigned int exception); + + int pte_cancellable_wait (pte_osSemaphoreHandle semHandle, unsigned int* timeout); + +#define PTE_ATOMIC_EXCHANGE pte_osAtomicExchange +#define PTE_ATOMIC_EXCHANGE_ADD pte_osAtomicExchangeAdd +#define PTE_ATOMIC_COMPARE_EXCHANGE pte_osAtomicCompareExchange +#define PTE_ATOMIC_DECREMENT pte_osAtomicDecrement +#define PTE_ATOMIC_INCREMENT pte_osAtomicIncrement + + int pte_thread_detach_np(); + int pte_thread_detach_and_exit_np(); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* _IMPLEMENT_H */ diff --git a/src/pthread/nautilus_osal.c b/src/pthread/nautilus_osal.c new file mode 100644 index 000000000..a3887a609 --- /dev/null +++ b/src/pthread/nautilus_osal.c @@ -0,0 +1 @@ +/* * psp_osal.c * * Description: * * -------------------------------------------------------------------------- * * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems * Copyright(C) 2008 Jason Schmidlapp * * Contact Email: jschmidlapp@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "pte_osal.h" #include "pthread.h" #include "tls-helper.h" /* For ftime */ #include #include #include #define MAX_PSP_UID 2048 // SWAG #define DEFAULT_STACK_SIZE_BYTES 4096 #define PSP_MAX_TLS 32 #if 1 #define PSP_DEBUG(x) printf(x) #else #define PSP_DEBUG(x) #endif /* TLS key used to access pspThreadData struct for reach thread. */ static unsigned int threadDataKey; /* * Data stored on a per-thread basis - allocated in pte_osThreadCreate * and freed in pte_osThreadDelete. */ typedef struct pspThreadData { /* Entry point and parameters to thread's main function */ pte_osThreadEntryPoint entryPoint; void * argv; /* Semaphore used for cancellation. Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */ SceUID cancelSem; } pspThreadData; /* Structure used to emulate TLS on non-POSIX threads. * This limits us to one non-POSIX thread that can * call pthread functions. */ static void *globalTls; /* Helper functions */ static pspThreadData *getThreadData(SceUID threadHandle); static void *getTlsStructFromThread(SceUID thid); /* A new thread's stub entry point. It retrieves the real entry point from the per thread control * data as well as any parameters to this function, and then calls the entry point. */ int pspStubThreadEntry (unsigned int argc, void *argv) { int result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); result = (*(pThreadData->entryPoint))(pThreadData->argv); return result; } /**************************************************************************** * * Initialization * ***************************************************************************/ pte_osResult pte_osInit(void) { pte_osResult result; pspThreadData *pThreadData; char cancelSemName[64]; /* Allocate and initialize TLS support */ result = pteTlsGlobalInit(PSP_MAX_TLS); if (result == PTE_OS_OK) { /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */ result = pteTlsAlloc(&threadDataKey); if (result == PTE_OS_OK) { /* Initialize the structure used to emulate TLS for * non-POSIX threads */ globalTls = pteTlsThreadInit(); /* Also create a "thread data" structure for a single non-POSIX thread. */ /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { result = PTE_OS_NO_RESOURCES; } else { /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(globalTls, threadDataKey, pThreadData); /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSemGlobal"); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ result = PTE_OS_OK; } } } return result; } /**************************************************************************** * * Threads * ***************************************************************************/ pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle) { char threadName[64]; char cancelSemName[64]; static int threadNum = 1; int pspAttr; void *pTls; SceUID threadId; pte_osResult result; pspThreadData *pThreadData; if (threadNum++ > MAX_PSP_UID) { threadNum = 0; } /* Make sure that the stack we're going to allocate is big enough */ if (stackSize < DEFAULT_STACK_SIZE_BYTES) { stackSize = DEFAULT_STACK_SIZE_BYTES; } /* Allocate TLS structure for this thread. */ pTls = pteTlsThreadInit(); if (pTls == NULL) { PSP_DEBUG("pteTlsThreadInit: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { pteTlsThreadDestroy(pTls); PSP_DEBUG("malloc(pspThreadData): PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(pTls, threadDataKey, pThreadData); pThreadData->entryPoint = entryPoint; pThreadData->argv = argv; /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSem%04d", threadNum); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ /* In order to emulate TLS functionality, we append the address of the TLS structure that we * allocated above to the thread's name. To set or get TLS values for this thread, the user * needs to get the name of the thread from the OS and then parse the name to extract * a pointer to the TLS structure. */ snprintf(threadName, sizeof(threadName), "pthread%04d__%x", threadNum, (unsigned int) pTls); pspAttr = 0; // printf("%s %p %d %d %d\n",threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr); threadId = sceKernelCreateThread(threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr, NULL); if (threadId == (SceUID) SCE_KERNEL_ERROR_NO_MEMORY) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; } else if (threadId < 0) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_GENERAL_FAILURE\n"); result = PTE_OS_GENERAL_FAILURE; } else { *ppte_osThreadHandle = threadId; result = PTE_OS_OK; } FAIL0: return result; } pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle) { sceKernelStartThread(osThreadHandle, 0, NULL); return PTE_OS_OK; } pte_osResult pte_osThreadDelete(pte_osThreadHandle handle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(handle); pThreadData = getThreadData(handle); sceKernelDeleteSema(pThreadData->cancelSem); free(pThreadData); pteTlsThreadDestroy(pTls); sceKernelDeleteThread(handle); return PTE_OS_OK; } pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle) { pte_osThreadDelete(handle); sceKernelExitDeleteThread(0); return PTE_OS_OK; } void pte_osThreadExit() { sceKernelExitThread(0); } /* * This has to be cancellable, so we can't just call sceKernelWaitThreadEnd. * Instead, poll on this in a loop, like we do for a cancellable semaphore. */ pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle) { pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); while (1) { SceKernelThreadRunStatus info; /* Poll task to see if it has ended */ memset(&info,0,sizeof(info)); info.size = sizeof(info); sceKernelReferThreadRunStatus(threadHandle, &info); if (info.status == PSP_THREAD_STOPPED) { /* Thread has ended */ result = PTE_OS_OK; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } pte_osThreadHandle pte_osThreadGetHandle(void) { return sceKernelGetThreadId(); } int pte_osThreadGetPriority(pte_osThreadHandle threadHandle) { SceKernelThreadInfo thinfo; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(threadHandle, &thinfo); return thinfo.currentPriority; } pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority) { sceKernelChangeThreadPriority(threadHandle, newPriority); return PTE_OS_OK; } pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle) { SceUID osResult; pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(threadHandle); osResult = sceKernelSignalSema(pThreadData->cancelSem, 1); if (osResult == SCE_KERNEL_ERROR_OK) { result = PTE_OS_OK; } else { result = PTE_OS_GENERAL_FAILURE; } return result; } pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle) { pspThreadData *pThreadData; SceKernelSemaInfo semInfo; SceUID osResult; pte_osResult result; pThreadData = getThreadData(threadHandle); if (pThreadData != NULL) { osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; } else { result = PTE_OS_OK; } } else { /* sceKernelReferSemaStatus returned an error */ result = PTE_OS_GENERAL_FAILURE; } } else { /* For some reason, we couldn't get thread data */ result = PTE_OS_GENERAL_FAILURE; } return result; } void pte_osThreadSleep(unsigned int msecs) { sceKernelDelayThread(msecs*1000); } int pte_osThreadGetMinPriority() { return 17; } int pte_osThreadGetMaxPriority() { return 30; } int pte_osThreadGetDefaultPriority() { return 18; } /**************************************************************************** * * Mutexes * ****************************************************************************/ pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle) { static int mutexCtr = 0; char mutexName[32]; pte_osMutexHandle handle; if (mutexCtr++ > MAX_PSP_UID) { mutexCtr = 0; } snprintf(mutexName,sizeof(mutexName),"mutex%d",mutexCtr); handle = sceKernelCreateSema(mutexName, 0, /* attributes (default) */ 1, /* initial value */ 1, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osMutexDelete(pte_osMutexHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osMutexLock(pte_osMutexHandle handle) { sceKernelWaitSema(handle, 1, NULL); return PTE_OS_OK; } pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs) { pte_osResult result; SceUInt timeoutUsecs = timeoutMsecs*1000; int status = sceKernelWaitSema(handle, 1, &timeoutUsecs); if (status < 0) { // Assume that any error from sceKernelWaitSema was due to a timeout result = PTE_OS_TIMEOUT; } else { result = PTE_OS_OK; } return result; } pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) { sceKernelSignalSema(handle, 1); return PTE_OS_OK; } /**************************************************************************** * * Semaphores * ***************************************************************************/ pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle) { pte_osSemaphoreHandle handle; static int semCtr = 0; char semName[32]; if (semCtr++ > MAX_PSP_UID) { semCtr = 0; } snprintf(semName,sizeof(semName),"pthread_sem%d",semCtr); handle = sceKernelCreateSema(semName, 0, /* attributes (default) */ initialValue, /* initial value */ SEM_VALUE_MAX, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count) { sceKernelSignalSema(handle, count); return PTE_OS_OK; } pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs) { unsigned int timeoutUsecs; unsigned int *pTimeoutUsecs; SceUInt result; pte_osResult osResult; if (pTimeoutMsecs == NULL) { pTimeoutUsecs = NULL; } else { timeoutUsecs = *pTimeoutMsecs * 1000; pTimeoutUsecs = &timeoutUsecs; } result = sceKernelWaitSema(handle, 1, pTimeoutUsecs); if (result == SCE_KERNEL_ERROR_OK) { osResult = PTE_OS_OK; } else if (result == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { osResult = PTE_OS_TIMEOUT; } else { osResult = PTE_OS_GENERAL_FAILURE; } return osResult; } /* * Pend on a semaphore- and allow the pend to be cancelled. * * PSP OS provides no functionality to asynchronously interrupt a blocked call. We simulte * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout) { pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); clock_t start_time; pte_osResult result = PTE_OS_OK; unsigned int timeout; unsigned char timeoutEnabled; start_time = clock(); // clock() is in microseconds, timeout as passed in was in milliseconds if (pTimeout == NULL) { timeout = 0; timeoutEnabled = 0; } else { timeout = *pTimeout * 1000; timeoutEnabled = 1; } while (1) { SceUInt semTimeout; int status; /* Poll semaphore */ semTimeout = 0; status = sceKernelWaitSema(semHandle, 1, &semTimeout); if (status == SCE_KERNEL_ERROR_OK) { /* User semaphore posted to */ result = PTE_OS_OK; break; } else if ((timeoutEnabled) && ((clock() - start_time) > timeout)) { /* Timeout expired */ result = PTE_OS_TIMEOUT; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } /**************************************************************************** * * Atomic Operations * ***************************************************************************/ int pte_osAtomicExchange(int *ptarg, int val) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *ptarg; *ptarg = val; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *pdest; if (*pdest == comp) { *pdest = exchange; } pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicExchangeAdd(int volatile* pAddend, int value) { int origVal; int intc = pspSdkDisableInterrupts(); origVal = *pAddend; *pAddend += value; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicDecrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)--; val = *pdest; pspSdkEnableInterrupts(intc); return val; } int pte_osAtomicIncrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)++; val = *pdest; pspSdkEnableInterrupts(intc); return val; } /**************************************************************************** * * Helper functions * ***************************************************************************/ static pspThreadData *getThreadData(SceUID threadHandle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(threadHandle); pThreadData = (pspThreadData *) pteTlsGetValue(pTls, threadDataKey); return pThreadData; } static void *getTlsStructFromThread(SceUID thid) { SceKernelThreadInfo thinfo; unsigned int ptr; unsigned int thrNum; void *pTls; int numMatches; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(thid, &thinfo); numMatches = sscanf(thinfo.name,"pthread%04d__%x", &thrNum, &ptr); /* If we were called from a pthread, use the TLS allocated when the thread * was created. Otherwise, we were called from a non-pthread, so use the * "global". This is a pretty bad hack, but necessary due to lack of TLS on PSP. */ if (numMatches == 2) { pTls = (void *) ptr; } else { pTls = globalTls; } return pTls; } /**************************************************************************** * * Thread Local Storage * ***************************************************************************/ pte_osResult pte_osTlsSetValue(unsigned int key, void * value) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsSetValue(pTls, key, value); } void * pte_osTlsGetValue(unsigned int index) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return (void *) pteTlsGetValue(pTls, index); } pte_osResult pte_osTlsAlloc(unsigned int *pKey) { void * pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsAlloc(pKey); } pte_osResult pte_osTlsFree(unsigned int index) { return pteTlsFree(index); } /**************************************************************************** * * Miscellaneous * ***************************************************************************/ int ftime(struct timeb *tb) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); tb->time = tv.tv_sec; tb->millitm = tv.tv_usec / 1000; tb->timezone = tz.tz_minuteswest; tb->dstflag = tz.tz_dsttime; return 0; } \ No newline at end of file diff --git a/src/pthread/nautilus_osal.h b/src/pthread/nautilus_osal.h new file mode 100644 index 000000000..d92e20b31 --- /dev/null +++ b/src/pthread/nautilus_osal.h @@ -0,0 +1,63 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include + +typedef nk_thread_id_t pte_osThreadHandle; + +typedef struct nk_semaphore *pte_osSemaphoreHandle; + +typedef spinlock_t *pte_osMutexHandle; + + +#define OS_IS_HANDLE_VALID(x) ((x) > 0) + + + + +#define OS_MAX_SIMUL_THREADS 1000 + +#define OS_DEFAULT_PRIO 11 + +#define OS_MIN_PRIO 17 +#define OS_MAX_PRIO 32 + +//#define HAVE_THREAD_SAFE_ERRNO + +#define POLLING_DELAY_IN_us 100 + + + +#define OS_MAX_SEM_VALUE 254 + + + + diff --git a/src/pthread/need_errno.h b/src/pthread/need_errno.h new file mode 100644 index 000000000..d5b50d5d0 --- /dev/null +++ b/src/pthread/need_errno.h @@ -0,0 +1,90 @@ +/*** +* errno.h - system wide error numbers (set by system calls) +* +* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +* Purpose: +* This file defines the system-wide error numbers (set by +* system calls). Conforms to the XENIX standard. Extended +* for compatibility with Uniforum standard. +* [System V] +* +* [Public] +* +****/ + +#ifndef _INC_ERRNO +#define _INC_ERRNO + +#ifdef __cplusplus +extern "C" + { +#endif + + + + /* declare reference to errno */ + + extern int errno; + + /* Error Codes */ + +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 36 + + /* defined differently in winsock.h on WinCE */ +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 38 +#endif + +#define ENOLCK 39 +#define ENOSYS 40 + + /* defined differently in winsock.h on WinCE */ +#ifndef ENOTEMPTY +#define ENOTEMPTY 41 +#endif + +#define EILSEQ 42 + + /* + * Support EDEADLOCK for compatibiity with older MS-C versions. + */ +#define EDEADLOCK EDEADLK + +#ifdef __cplusplus + } +#endif + +#endif /* _INC_ERRNO */ diff --git a/src/pthread/platform/dspbios/dspbios-config.h b/src/pthread/platform/dspbios/dspbios-config.h new file mode 100644 index 000000000..11921c83d --- /dev/null +++ b/src/pthread/platform/dspbios/dspbios-config.h @@ -0,0 +1,26 @@ +/* config.h */ + +#ifndef PTE_CONFIG_H +#define PTE_CONFIG_H + +#define PTE_STATIC_LIB + +/********************************************************************* + * Defaults: see target specific redefinitions below. + *********************************************************************/ + +/* We're building the pthreads-win32 library */ +#define PTE_BUILD + +/* Define if you don't have Win32 errno. (eg. WinCE) */ +#undef NEED_ERRNO +#define NEED_ERRNO + +/* Do we know about type mode_t? */ +#undef HAVE_MODE_T + +/* Define if you have the timespec struct */ +#undef HAVE_STRUCT_TIMESPEC +//#define HAVE_STRUCT_TIMESPEC + +#endif diff --git a/src/pthread/platform/dspbios/dspbios-osal.c b/src/pthread/platform/dspbios/dspbios-osal.c new file mode 100644 index 000000000..e23c073a2 --- /dev/null +++ b/src/pthread/platform/dspbios/dspbios-osal.c @@ -0,0 +1,923 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "tls-helper.h" +#include "pte_osal.h" + +#define POLLING_DELAY_IN_ticks 10 + +#define DSPBIOS_MAX_TLS 32 + +#define DEFAULT_STACK_SIZE_BYTES 4096 + +/* + * Data stored on a per-thread basis - allocated in pte_osThreadCreate + * and freed in pte_osThreadDelete. + */ +typedef struct dspbiosThreadData + { + /* Semaphore used to wait for threads to end. Posted to in pte_osThreadExit() */ + SEM_Handle joinSem; + + /* Semaphore used for cancellation. Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */ + SEM_Handle cancelSem; + + /* Initial priority of the thread. */ + int priority; + + } dspbiosThreadData; + + +/* Task and mailbox used for cleaning up detached threads */ +static TSK_Handle gcTaskHandle; +static MBX_Handle gcMailbox; + +/* TLS key used to access dspbiosThreadData struct for reach thread. */ +static unsigned int threadDataKey; + + +/* + * + * Helper functions + * + */ + +/* Returns a pointer to the per thread control info */ +static dspbiosThreadData * getThreadData(TSK_Handle threadHandle) +{ + + dspbiosThreadData *pThreadData; + void * pTls; + + pTls = (void *) TSK_getenv(threadHandle); + + pThreadData = (dspbiosThreadData *) pteTlsGetValue(pTls, threadDataKey); + + return pThreadData; +} + +/* Converts milliseconds to system ticks (for TSK_sleep, SEM_pend, etc) */ +static int msecsToSysTicks(int msecs) +{ + int ticks = CLK_countspms() / CLK_getprd() * msecs; + + ticks = ticks / 100; // sim only + + return ticks; +} + +/* Garbage collector thread to free resources from detached threads */ +void dspbiosGarbageCollectorMain() +{ + + gcMailbox = MBX_create(sizeof(void*), 10, NULL); + + while (1) + { + Bool status; + void * pTask; + + /* Wait for dying threads to post their handles to our mailbox */ + status = MBX_pend(gcMailbox, &pTask, SYS_FOREVER); + + if (status) + { + TSK_delete((TSK_Handle) pTask); + } + } + + /* Never returns */ +} + +/**************************************************************************** + * + * Initialization + * + ***************************************************************************/ + +/* + * Initializes the OSAL. + * + * 1. Initialize TLS support. + * 2. Allocate control data TLS key. + * 3. Start garbage collector thread. + */ +pte_osResult pte_osInit(void) +{ + pte_osResult result; + TSK_Attrs attrs; + + /* Allocate and initialize TLS support */ + result = pteTlsGlobalInit(DSPBIOS_MAX_TLS); + + if (result == PTE_OS_OK) + { + /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */ + result = pteTlsAlloc(&threadDataKey); + + if (result == PTE_OS_OK) + { + /* Create a low priority task to free resources for detached threads */ + attrs = TSK_ATTRS; + attrs.priority = 1; /* just above idle task */ + attrs.name = "pthread-gc"; + + gcTaskHandle = TSK_create((Fxn) dspbiosGarbageCollectorMain, &attrs); + + /* Give the garbage collector task a chance to run and create the mailbox */ + TSK_sleep(1); + + if (gcTaskHandle == NULL) + { + result = PTE_OS_NO_RESOURCES; + } + } + } + + return result; +} + +/**************************************************************************** + * + * Threads + * + ***************************************************************************/ + + +/* Entry point for new threads */ +void dspbiosStubThreadEntry (void *argv, pte_osThreadEntryPoint entryPoint) +{ + (*(entryPoint))(argv); + return; +} + +/* + * Creates a new thread, allocates resources, etc. + * + * The thread is created in a suspended state; execution will actually start + * when pte_osThreadStart() is called. Setting the priority to a -1 will start the + * thread in a suspended state. pte_osThreadStart then sets the real priority which + * will start the thread executing. + * + * In order for dynamic tasks to work, you must set up a heap for DSP/BIOS to allocate their + * stacks from. This should be done in the projects tcf or cdb file. + * + */ +pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, + int stackSize, + int initialPriority, + void *argv, + pte_osThreadHandle* ppte_osThreadHandle) +{ + TSK_Handle handle; + TSK_Attrs attrs; + void *pTls; + pte_osResult result; + dspbiosThreadData *pThreadData; + + /* Make sure that the stack we're going to allocate is big enough */ + if (stackSize < DEFAULT_STACK_SIZE_BYTES) + { + stackSize = DEFAULT_STACK_SIZE_BYTES; + } + + /* Allocate TLS structure for this thread. */ + pTls = pteTlsThreadInit(); + if (pTls == NULL) + { + result = PTE_OS_NO_RESOURCES; + goto FAIL0; + } + + + /* Allocate some memory for our per-thread control data. We use this for: + * 1. join semaphore (used to wait for thread termination) + * 2. cancellation semaphore (used to signal a thread to cancel) + * 3. initial priority (used in stub entry point) + */ + pThreadData = (dspbiosThreadData*) malloc(sizeof(dspbiosThreadData)); + + if (pThreadData == NULL) + { + pteTlsThreadDestroy(pTls); + + result = PTE_OS_NO_RESOURCES; + goto FAIL0; + } + + /* Save a pointer to our per-thread control data as a TLS value */ + pteTlsSetValue(pTls, threadDataKey, pThreadData); + + /* Create semaphores and save handles */ + pThreadData->joinSem = SEM_create(0, NULL); + pThreadData->cancelSem = SEM_create(0, NULL); + + /* Save the initial priority - we need it when we + * actually start the thread */ + pThreadData->priority = initialPriority; + + /* + * Fill out parameters for TSK_create: + */ + attrs = TSK_ATTRS; + + /* Use value specified by user */ + attrs.stacksize = stackSize; + + attrs.priority = -1; + + /* Save our TLS structure as the task's environment. */ + attrs.environ = pTls; + + handle = TSK_create((Fxn) dspbiosStubThreadEntry, &attrs, argv, entryPoint); + + if (handle != NULL) + { + /* Everything worked, return handle to caller */ + *ppte_osThreadHandle = handle; + result = PTE_OS_OK; + } + else + { + /* Something went wrong - assume that it was due to lack of resources. */ + free(pThreadData); + pteTlsThreadDestroy(pTls); + + result = PTE_OS_NO_RESOURCES; + } + +FAIL0: + return result; +} + +/* Start executing a thread. + * + * Get the priority that the user specified when they called + * pte_osThreadCreate and set the priority of the thread. This + * will start the thread executing. + */ +pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle) +{ + + dspbiosThreadData *pThreadData; + + pThreadData = getThreadData(osThreadHandle); + + TSK_setpri(osThreadHandle, pThreadData->priority); + + return PTE_OS_OK; + +} + + +/* + * Exit from a thread. + * + * Post to the join semaphore in case a pthread_join is + * waiting for us to exit. + */ +void pte_osThreadExit() +{ + TSK_Handle thisTask; + dspbiosThreadData *pThreadData; + + thisTask = TSK_self(); + + pThreadData = getThreadData(thisTask); + + if (pThreadData != NULL) + { + SEM_post(pThreadData->joinSem); + } + + TSK_exit(); + +} + +pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle) +{ + dspbiosThreadData *pThreadData; + void * pTls; + + pThreadData = getThreadData(handle); + + pTls = (void *) TSK_getenv(handle); + + /* Free the per thread data (join & cancel semaphores, etc) */ + SEM_delete(pThreadData->joinSem); + SEM_delete(pThreadData->cancelSem); + + free(pThreadData); + + /* Free the TLS data structure */ + pteTlsThreadDestroy(pTls); + + /* Send thread handle to garbage collector task so it can free + * resources from a different context */ + MBX_post(gcMailbox, &handle, SYS_FOREVER); + + TSK_exit(); + + return PTE_OS_OK; +} + +/* Clean up a thread. + * + * If this is called from the thread itself, instead of actually freeing up + * resources, post the thread handle to a mailbox which will be picked + * up by the garbage collector thread. Resources will be freed from there. + * This is necessary because DSP/BIOS does not free resources when a + * thread exits. + */ +pte_osResult pte_osThreadDelete(pte_osThreadHandle handle) +{ + + dspbiosThreadData *pThreadData; + void * pTls; + + pThreadData = getThreadData(handle); + + pTls = (void *) TSK_getenv(handle); + + /* Free the per thread data (join & cancel semaphores, etc) */ + SEM_delete(pThreadData->joinSem); + SEM_delete(pThreadData->cancelSem); + + free(pThreadData); + + /* Free the TLS data structure */ + pteTlsThreadDestroy(pTls); + + TSK_delete(handle); + + return PTE_OS_OK; +} + +/* Wait for a thread to exit. + * + * Since DSP/BIOS doesn't have a explicit system call for this, we + * emulate it using a semaphore that is posted to when the thread + * exits. + */ +pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle) +{ + TSK_Stat taskStats; + pte_osResult result; + + /* Prevent context switches to prevent the thread from + * changing states */ + TSK_disable(); + + /* First, check if the thread has already terminated. */ + TSK_stat(threadHandle, &taskStats); + + if (taskStats.mode != TSK_TERMINATED) + { + dspbiosThreadData *pThreadData; + dspbiosThreadData *pSelfThreadData; + + pThreadData = getThreadData(threadHandle); + pSelfThreadData = getThreadData(TSK_self()); + + TSK_enable(); + + /* This needs to be cancellable, so poll instead of block, + * similar to what we do for pte_OsSemaphoreCancellablePend. */ + while (1) + { + if (SEM_count(pThreadData->joinSem) > 0) + { + /* The thread has exited. */ + result = PTE_OS_OK; + break; + } + else if ((pSelfThreadData != NULL) && SEM_count(pSelfThreadData->cancelSem) > 0) + { + /* The thread was cancelled */ + result = PTE_OS_INTERRUPTED; + break; + } + else + { + /* Nothing found and not timed out yet; let's yield so we're not + * in busy loop. */ + TSK_sleep(POLLING_DELAY_IN_ticks); + } + } + + } + else + { + /* Thread is already terminated, just return OK */ + TSK_enable(); + result = PTE_OS_OK; + } + + return result; +} + +/* Cancels the specified thread. This will 1) make pte_osSemaphoreCancellablePend return if it is currently + * blocked and will make pte_osThreadCheckCancel return TRUE. + * + * To accomplish this, we post to the cancellation semaphore for the specified thread. + */ +pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle) +{ + dspbiosThreadData *pThreadData; + + pThreadData = getThreadData(threadHandle); + + if (pThreadData != NULL) + { + SEM_post(pThreadData->cancelSem); + } + + return PTE_OS_OK; +} + + +/* + * Checks to see if pte_osThreadCancel has been called for the specified thread. Just check the + * value of the cancellation semaphore associated with the thread. + */ +pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle) +{ + + dspbiosThreadData *pThreadData; + + pThreadData = getThreadData(threadHandle); + + if (pThreadData != NULL) + { + if (SEM_count(pThreadData->cancelSem) > 0) + { + return PTE_OS_INTERRUPTED; + } + else + { + return PTE_OS_OK; + } + } + else + { + /* We're being called from a pure OS thread which can't be cancelled. */ + return PTE_OS_OK; + } + + +} + +void pte_osThreadSleep(unsigned int msecs) +{ + int ticks = msecsToSysTicks(msecs); + + TSK_sleep(ticks); +} + +pte_osThreadHandle pte_osThreadGetHandle(void) +{ + return TSK_self(); +} + +int pte_osThreadGetPriority(pte_osThreadHandle threadHandle) +{ + return TSK_getpri(threadHandle); +} + +pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority) +{ + TSK_setpri(threadHandle, newPriority); + + return PTE_OS_OK; +} + +int pte_osThreadGetMinPriority() +{ + return TSK_MINPRI; +} + +int pte_osThreadGetMaxPriority() +{ + return TSK_MAXPRI; +} + +int pte_osThreadGetDefaultPriority() +{ + /* Pick something in the middle */ + return ((TSK_MINPRI + TSK_MAXPRI) / 2); +} + +/**************************************************************************** + * + * Mutexes + * + ***************************************************************************/ + +pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle) +{ + + *pHandle = LCK_create(NULL); + + if (*pHandle == NULL) + { + return PTE_OS_NO_RESOURCES; + } + else + { + return PTE_OS_OK; + } +} + +pte_osResult pte_osMutexDelete(pte_osMutexHandle handle) +{ + LCK_delete(handle); + + return PTE_OS_OK; +} + +pte_osResult pte_osMutexLock(pte_osMutexHandle handle) +{ + LCK_pend(handle, SYS_FOREVER); + + return PTE_OS_OK; +} + +pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) +{ + + LCK_post(handle); + + return PTE_OS_OK; +} + +/**************************************************************************** + * + * Semaphores + * + ***************************************************************************/ + +pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle) +{ + + *pHandle = SEM_create(initialValue, NULL); + + if (*pHandle == NULL) + { + return PTE_OS_NO_RESOURCES; + } + else + { + return PTE_OS_OK; + } + +} + +pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle) +{ + SEM_delete(handle); + + return PTE_OS_OK; +} + + +pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count) +{ + int i; + + for (i=0;i timeout)) + { + /* The timeout expired */ + result = PTE_OS_TIMEOUT; + break; + } + else + { + if ((pThreadData != NULL) && SEM_count(pThreadData->cancelSem) > 0) + { + /* The thread was cancelled */ + result = PTE_OS_INTERRUPTED; + break; + } + else + { + /* Nothing found and not timed out yet; let's yield so we're not + * in busy loop. */ + TSK_sleep(POLLING_DELAY_IN_ticks); + } + } + + } + + return result; + +} + + +/**************************************************************************** + * + * Atomic Operations + * + ***************************************************************************/ +int pte_osAtomicExchange(int *ptarg, int val) +{ + + long origVal; + Uns oldCSR; + + oldCSR = HWI_disable(); + + origVal = *ptarg; + + *ptarg = val; + + HWI_restore(oldCSR); + + return origVal; + +} + +int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp) +{ + + int origVal; + Uns oldCSR; + + oldCSR = HWI_disable(); + + + origVal = *pdest; + + if (*pdest == comp) + { + *pdest = exchange; + } + + HWI_restore(oldCSR); + + + return origVal; + +} + +int pte_osAtomicExchangeAddInt(int volatile* pAddend, int value) +{ + + int origVal; + Uns oldCSR; + + oldCSR = HWI_disable(); + + + origVal = *pAddend; + + *pAddend += value; + + HWI_restore(oldCSR); + + + return origVal; + +} + +int pte_osAtomicExchangeAdd(int volatile* pAddend, int value) +{ + + int origVal; + Uns oldCSR; + + oldCSR = HWI_disable(); + + + origVal = *pAddend; + + *pAddend += value; + + HWI_restore(oldCSR); + + + return origVal; +} + +int pte_osAtomicDecrement(int *pdest) +{ + int val; + Uns oldCSR; + + oldCSR = HWI_disable(); + + + (*pdest)--; + val = *pdest; + + HWI_restore(oldCSR); + + return val; + +} + +int pte_osAtomicIncrement(int *pdest) +{ + int val; + Uns oldCSR; + + oldCSR = HWI_disable(); + + (*pdest)++; + + val = *pdest; + + HWI_restore(oldCSR); + + + return val; +} + +/**************************************************************************** + * + * Thread Local Storage + * + ***************************************************************************/ + +pte_osResult pte_osTlsSetValue(unsigned int index, void * value) +{ + void *pTls; + + pTls = (void *) TSK_getenv(TSK_self()); + + if (pTls == NULL) + { + // Apparently no TLS structure has been allocated for this thread + // Probably because this is a native OS thread + pTls = pteTlsThreadInit(); + + + TSK_setenv(TSK_self(), pTls); + } + + return pteTlsSetValue(pTls, index, value); +} + + + +void * pte_osTlsGetValue(unsigned int index) +{ + void *pTls; + + pTls = (void *) TSK_getenv(TSK_self()); + + return (void *) pteTlsGetValue(pTls, index); + +} + + +// Note that key value must be > 0 +pte_osResult pte_osTlsAlloc(unsigned int *pKey) +{ + return pteTlsAlloc(pKey); +} + + +pte_osResult pte_osTlsFree(unsigned int index) +{ + return pteTlsFree(index); + +} + + +int ftime(struct timeb *tp) +{ + int ltime = (CLK_getltime() * CLK_cpuCyclesPerLtime()) / CLK_cpuCyclesPerLtime(); + int secs = ltime / 1000; + int msecs = ltime % 1000; + + tp->dstflag = 0; + tp->timezone = 0; + tp->time = secs; + tp->millitm = msecs; + + return 0; +} + + diff --git a/src/pthread/platform/dspbios/dspbios-osal.h b/src/pthread/platform/dspbios/dspbios-osal.h new file mode 100644 index 000000000..ca53dff52 --- /dev/null +++ b/src/pthread/platform/dspbios/dspbios-osal.h @@ -0,0 +1,102 @@ +/* + * dspbios-osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include + +typedef TSK_Handle pte_osThreadHandle; + +typedef SEM_Handle pte_osSemaphoreHandle; + +typedef LCK_Handle pte_osMutexHandle; + +#define OS_DEFAULT_PRIO 11 + +#define OS_MAX_SIMUL_THREADS 10 + + + + +#ifndef EPERM +#define EPERM 1 +#endif // EPERM + +#ifndef ESRCH +#define ESRCH 3 +#endif // ESRCH + +#ifndef EINTR +#define EINTR 4 +#endif // EINTR + +#ifndef EIO +#define EIO 5 +#endif // EIO + +#ifndef EAGAIN +#define EAGAIN 11 +#endif // EAGAIN + +#ifndef ENOMEM +#define ENOMEM 12 +#endif // ENOMEM + +#ifndef EBUSY +#define EBUSY 16 +#endif // EBUSY + +#ifndef EINVAL +#define EINVAL 22 +#endif // EINVAL + +#ifndef ENOSPC +#define ENOSPC 28 +#endif // ENOSPC + +#ifndef EDEADLK +#define EDEADLK 35 +#endif /* EDEADLK */ + +#ifndef ENOSYS +#define ENOSYS 38 +#endif /* ENOSYS */ + +#ifndef ENOTSUP +#define ENOTSUP 95 +#endif /* ENOTSUP */ + +#ifndef ETIMEDOUT +#define ETIMEDOUT 116 +#endif // ETIMEDOUT + + + + diff --git a/src/pthread/platform/dspbios/main.c b/src/pthread/platform/dspbios/main.c new file mode 100644 index 000000000..ca5129f70 --- /dev/null +++ b/src/pthread/platform/dspbios/main.c @@ -0,0 +1,46 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +extern void pte_test_main(); + +int main(void) +{ + + // Start tests from a task as most DSP/BIOS API calls cannot + // be made from main + struct TSK_Attrs attrs; + + attrs = TSK_ATTRS; + + attrs.stacksize = 4*1024; + + TSK_create((Fxn)pte_test_main,&attrs); +} diff --git a/src/pthread/platform/dspbios/pte_lib/pte_lib.pjt b/src/pthread/platform/dspbios/pte_lib/pte_lib.pjt new file mode 100644 index 000000000..d904677e4 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_lib/pte_lib.pjt @@ -0,0 +1,156 @@ +; Code Composer Project File, Version 2.0 (do not modify or remove this line) + +[Project Settings] +ProjectDir="Z:\pthread\platform\dspbios\pte_lib\" +ProjectType=Library +CPUFamily=TMS320C64XX +Tool="Archiver" +Tool="Compiler" +Tool="CustomBuilder" +Tool="DspBiosBuilder" +Config="C" +Config="CPP" + +[Source Files] +Source="..\..\..\cleanup.c" +Source="..\..\..\create.c" +Source="..\..\..\global.c" +Source="..\..\..\pte_callUserDestroyRoutines.c" +Source="..\..\..\pte_cancellable_wait.c" +Source="..\..\..\pte_cond_check_need_init.c" +Source="..\..\..\pte_detach.c" +Source="..\..\..\pte_getprocessors.c" +Source="..\..\..\pte_is_attr.c" +Source="..\..\..\pte_mutex_check_need_init.c" +Source="..\..\..\pte_new.c" +Source="..\..\..\pte_relmillisecs.c" +Source="..\..\..\pte_reuse.c" +Source="..\..\..\pte_rwlock_cancelwrwait.c" +Source="..\..\..\pte_rwlock_check_need_init.c" +Source="..\..\..\pte_spinlock_check_need_init.c" +Source="..\..\..\pte_threadDestroy.c" +Source="..\..\..\pte_threadStart.c" +Source="..\..\..\pte_throw.c" +Source="..\..\..\pte_tkAssocCreate.c" +Source="..\..\..\pte_tkAssocDestroy.c" +Source="..\..\..\pthread_attr_destroy.c" +Source="..\..\..\pthread_attr_getdetachstate.c" +Source="..\..\..\pthread_attr_getinheritsched.c" +Source="..\..\..\pthread_attr_getschedparam.c" +Source="..\..\..\pthread_attr_getschedpolicy.c" +Source="..\..\..\pthread_attr_getscope.c" +Source="..\..\..\pthread_attr_getstackaddr.c" +Source="..\..\..\pthread_attr_getstacksize.c" +Source="..\..\..\pthread_attr_init.c" +Source="..\..\..\pthread_attr_setdetachstate.c" +Source="..\..\..\pthread_attr_setinheritsched.c" +Source="..\..\..\pthread_attr_setschedparam.c" +Source="..\..\..\pthread_attr_setschedpolicy.c" +Source="..\..\..\pthread_attr_setscope.c" +Source="..\..\..\pthread_attr_setstackaddr.c" +Source="..\..\..\pthread_attr_setstacksize.c" +Source="..\..\..\pthread_barrier_destroy.c" +Source="..\..\..\pthread_barrier_init.c" +Source="..\..\..\pthread_barrier_wait.c" +Source="..\..\..\pthread_barrierattr_destroy.c" +Source="..\..\..\pthread_barrierattr_getpshared.c" +Source="..\..\..\pthread_barrierattr_init.c" +Source="..\..\..\pthread_barrierattr_setpshared.c" +Source="..\..\..\pthread_cancel.c" +Source="..\..\..\pthread_cond_destroy.c" +Source="..\..\..\pthread_cond_init.c" +Source="..\..\..\pthread_cond_signal.c" +Source="..\..\..\pthread_cond_wait.c" +Source="..\..\..\pthread_condattr_destroy.c" +Source="..\..\..\pthread_condattr_getpshared.c" +Source="..\..\..\pthread_condattr_init.c" +Source="..\..\..\pthread_condattr_setpshared.c" +Source="..\..\..\pthread_delay_np.c" +Source="..\..\..\pthread_detach.c" +Source="..\..\..\pthread_equal.c" +Source="..\..\..\pthread_exit.c" +Source="..\..\..\pthread_getconcurrency.c" +Source="..\..\..\pthread_getschedparam.c" +Source="..\..\..\pthread_getspecific.c" +Source="..\..\..\pthread_init.c" +Source="..\..\..\pthread_join.c" +Source="..\..\..\pthread_key_create.c" +Source="..\..\..\pthread_key_delete.c" +Source="..\..\..\pthread_kill.c" +Source="..\..\..\pthread_mutex_destroy.c" +Source="..\..\..\pthread_mutex_init.c" +Source="..\..\..\pthread_mutex_lock.c" +Source="..\..\..\pthread_mutex_timedlock.c" +Source="..\..\..\pthread_mutex_trylock.c" +Source="..\..\..\pthread_mutex_unlock.c" +Source="..\..\..\pthread_mutexattr_destroy.c" +Source="..\..\..\pthread_mutexattr_getkind_np.c" +Source="..\..\..\pthread_mutexattr_getpshared.c" +Source="..\..\..\pthread_mutexattr_gettype.c" +Source="..\..\..\pthread_mutexattr_init.c" +Source="..\..\..\pthread_mutexattr_setkind_np.c" +Source="..\..\..\pthread_mutexattr_setpshared.c" +Source="..\..\..\pthread_mutexattr_settype.c" +Source="..\..\..\pthread_num_processors_np.c" +Source="..\..\..\pthread_once.c" +Source="..\..\..\pthread_rwlock_destroy.c" +Source="..\..\..\pthread_rwlock_init.c" +Source="..\..\..\pthread_rwlock_rdlock.c" +Source="..\..\..\pthread_rwlock_timedrdlock.c" +Source="..\..\..\pthread_rwlock_timedwrlock.c" +Source="..\..\..\pthread_rwlock_tryrdlock.c" +Source="..\..\..\pthread_rwlock_trywrlock.c" +Source="..\..\..\pthread_rwlock_unlock.c" +Source="..\..\..\pthread_rwlock_wrlock.c" +Source="..\..\..\pthread_rwlockattr_destroy.c" +Source="..\..\..\pthread_rwlockattr_getpshared.c" +Source="..\..\..\pthread_rwlockattr_init.c" +Source="..\..\..\pthread_rwlockattr_setpshared.c" +Source="..\..\..\pthread_self.c" +Source="..\..\..\pthread_setcancelstate.c" +Source="..\..\..\pthread_setcanceltype.c" +Source="..\..\..\pthread_setconcurrency.c" +Source="..\..\..\pthread_setschedparam.c" +Source="..\..\..\pthread_setspecific.c" +Source="..\..\..\pthread_spin_destroy.c" +Source="..\..\..\pthread_spin_init.c" +Source="..\..\..\pthread_spin_lock.c" +Source="..\..\..\pthread_spin_trylock.c" +Source="..\..\..\pthread_spin_unlock.c" +Source="..\..\..\pthread_terminate.c" +Source="..\..\..\pthread_testcancel.c" +Source="..\..\..\pthread_timechange_handler_np.c" +Source="..\..\..\sched_get_priority_max.c" +Source="..\..\..\sched_get_priority_min.c" +Source="..\..\..\sched_setscheduler.c" +Source="..\..\..\sched_yield.c" +Source="..\..\..\sem_close.c" +Source="..\..\..\sem_destroy.c" +Source="..\..\..\sem_getvalue.c" +Source="..\..\..\sem_init.c" +Source="..\..\..\sem_open.c" +Source="..\..\..\sem_post.c" +Source="..\..\..\sem_post_multiple.c" +Source="..\..\..\sem_timedwait.c" +Source="..\..\..\sem_trywait.c" +Source="..\..\..\sem_unlink.c" +Source="..\..\..\sem_wait.c" + +["Archiver" Settings: "C"] +Options=-r -o".\C\pte_lib.lib" + +["Archiver" Settings: "CPP"] +Options=-r -o".\CPP\pte_lib.lib" + +["Compiler" Settings: "C"] +Options=-g -fr"$(Proj_dir)\C" -i".\platform\dspbios" -i"." -d"_DEBUG" -mv6400 + +["Compiler" Settings: "CPP"] +Options=-g -fg -fr"$(Proj_dir)\CPP" -i".\platform\dspbios" -i"." -d"_DEBUG" -d"__CLEANUP_CXX" -mv6400 --exceptions + +["..\..\..\pte_threadStart.c" Settings: "CPP"] +Options="Compiler" +{-fg} + +["..\..\..\pte_throw.c" Settings: "CPP"] +Options="Compiler" +{-fg} + diff --git a/src/pthread/platform/dspbios/pte_osal.h b/src/pthread/platform/dspbios/pte_osal.h new file mode 100644 index 000000000..46ca6baa4 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_osal.h @@ -0,0 +1,12 @@ + +#ifndef _OS_SUPPORT_H_ +#define _OS_SUPPORT_H_ + +// Platform specific one must be included first +#include "dspbios-osal.h" + +#include "pte_generic_osal.h" + + + +#endif // _OS_SUPPORT_H diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.cdb b/src/pthread/platform/dspbios/pte_test/Configuration1.cdb new file mode 100644 index 000000000..f9ab9e893 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_test/Configuration1.cdb @@ -0,0 +1,8974 @@ +//! +//# c64xx.cdb 5.23.14 + +object CACHE_L2 :: MEM { + param iComment :: "Do not delete, in use by cache" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param base :: 1048576 + param len :: 0 + param iAllocHeap :: 0 + param iHeapSize :: 32768 + param iUserHeapId :: 0 + param iHeapId :: @segment_name + param iReqHeapCount :: 0 + param space :: "Cache" + param dynamicLoading :: 0 + param iIsModifiable :: 1 +} + +class Module { + prop Visible :: 1 + prop Writable :: 1 + prop IsConfMod :: (if self.gNumOf > 0 {1} else {0}) + prop NoGen :: 0 + prop IsDirty :: ($a = self.gDirty, self.gDirty = 0, $a) + prop dataSize :: 0 + prop error :: # ("Error: ", self.name, $1) + prop warning :: ("Warning ...", self.name, $1) + prop minBit :: ($a = 0, while (($1 & (1 << $a)) && $a < 32) {++$a}, $a) + prop name :: ("") + prop numBit :: ($a = $b = 0, while ($a < 32) {if ($1 & (1 << $a)) {++$b} }, $b) +} + +class ObjectMgr { + isa Module + prop CanCreate :: (if (self.gNumOf < self.maxObjs()) {self.localCanCreate()} else {self.warning("Maximum number of objects already created")}) + prop CanDelete :: (if (self.iDelMsg == "ok" || (self.iDelUser == self.gUser)) {if (self.iId >= 0 && self.iIsUsed) {self.localCanDelete()} else {self.warning("Object already deleted")}} else {self.warning(self.iDelMsg)}) + prop Create :: ((self.gUser = (if $0 > 0 {$1} else {"USER"})), if (($a = self.CanCreate()) == "ok") {if (($a = self.localCreate()) == "ok") {if (self.iIsUsed == 0) {self.mkId(if $0 > 1 {$2} else {-1}), self.iIsUsed = 1, GlobalStatus.gDirty = 1, self.gDirty = 1} } } , (self.gUser = "USER"), $a) + prop Delete :: ((self.gUser = (if $0 > 0 {$1} else {"USER"})), if (($a = self.CanDelete()) == "ok") {if (($a = self.localDelete()) == "ok") {self.rmId(self.iId), self.iIsUsed = 0, GlobalStatus.gDirty = 1, self.gDirty = 1} } , (self.gUser = "USER"), $a) + prop GetSetOf :: (self.gSetOf) + prop GetNumOf :: (self.gNumOf) + prop GetObjId :: (self.iId) + prop GetPriority :: (self.iId) + prop SetPriority :: (self.iId = $1) + prop IsConfObj :: (self.iIsUsed) + prop localCanCreate :: ("ok") + prop localCanDelete :: ("ok") + prop localCreate :: ("ok") + prop localDelete :: ("ok") + prop localInit :: (0) + prop isFinite :: (if self.maxObjs() <= GBL.DSPWORDSIZE {1} else {0}) + prop mkId :: (if (self.isFinite()) {if ($1 < 0) {self.iId = self.minBit(self.gSetOf)} else {self.iId = $1}, (self.gSetOf |= (1 << self.iId))} else {self.iId = 0}, ++self.gNumOf, self.iId) + prop rmId :: (if (self.isFinite()) {self.gSetOf &= ~(1 << self.iId)} , --self.gNumOf) + prop maxObjs :: (GBL.DSPWORDSIZE) + prop isDriver :: (0) + prop SortChildHierView :: (1) +} + +type GlobalStatus { + prop NoGen :: 1 + prop Visible :: 0 + prop Writable :: 0 + prop Label :: "Current Configuration Status" + prop GlobalIcon :: 101 + prop InstanceIcon :: 101 + prop GlobalHelpTopic :: (100) + prop GlobalPropertyPage :: ("{9D3AD931-847B-11d0-A621-0000C070F3E9}") + prop Status :: (# self.SeedVersion, # self.MinStackSize, # self.SysDataSize) + global GENLIB :: "bioscfg.dll" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Generation Library" + prop NoGen :: 1 + prop Visible :: 0 + prop Writable :: 1 + } + global DATE :: "Fri Apr 04 15:41:02 2008" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global GCONFVERS :: "@(#)*** xdc-m66" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global SysDataSize :: = ($a = 0, scan ($i; nil) {if ($i.dataSize() != nil) {$a = $a + $i.dataSize()} }, $a) { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "Estimated Data Size: %d" + prop StatusField :: 1 + prop NoGen :: 1 + } + global MinStackSize :: = ($a = ((2 * (2)) * 4), $a = $a + ((2 * (5)) * 4), $a = $a + ((0) * 4), $b = 0, scan ($i; CLK) {if ($i.IsConfObj()) {$b |= 1} }, $a = $a + (((2 * (2)) * 4) * $b), $b = 0, scan ($i; HWI) {if ($i.IsConfObj()) {if ($i != HWI_NMI && $i != HWI_RESET) {if (($i.function != @HWI_unused) && ($i.function != @RESERVED)) {$b++} } } }, $a = $a + (((12 + 14 + 2) * 4) * $b), $b = 0, scan ($i; SWI) {if ($i.IsConfObj()) {if ($i.priority > $b) {$b = $i.priority} } }, $a = $a + ((((2 * 2) + 18 + (2 * 4)) * 4) * $b), $b = 0, scan ($i; PRD) {if ($i.IsConfObj()) {$b |= 1} }, $a = $a + (((2 * (3)) * 4) * $b), $a) { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "Est. Min. Stack Size (MAUs): %d" + prop StatusField :: 1 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global ConfigWarnings :: = (if (self.MinStackSize > MEM.STACKSIZE) {"Application stack size is too small; decrease the number of SWI priorities or increase the stack in MEM."} else {"None"}) { + prop Label :: "Warnings" + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global SeedVersion :: = "@(#)*** cuda-r14x" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +class EModule { + isa Module + prop IsXMod :: (1) + prop Vendor :: ("") + prop Version :: ("") +} + +class EObjectMgr { + isa ObjectMgr + prop IsXMod :: (1) + prop Vendor :: ("") + prop Version :: ("") +} + +class ModuleFolder { + isa Module + prop NoGen :: 1 +} + +type SYSTEM { + isa ModuleFolder + prop Label :: "System" + prop GlobalIcon :: 151 + prop GlobalHelpTopic :: (500) + prop GlobalPropertyPage :: ("{B936FB91-52A5-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type INS { + isa ModuleFolder + prop Label :: "Instrumentation" + prop GlobalIcon :: 152 + prop GlobalHelpTopic :: (501) + prop GlobalPropertyPage :: ("{053C8F90-52A6-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type SCH { + isa ModuleFolder + prop Label :: "Scheduling" + prop GlobalIcon :: 153 + prop GlobalHelpTopic :: (502) + prop GlobalPropertyPage :: ("{053C8F91-52A6-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type SYN { + isa ModuleFolder + prop Label :: "Synchronization" + prop GlobalIcon :: 154 + prop GlobalHelpTopic :: (503) + prop GlobalPropertyPage :: ("{053C8F92-52A6-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type IOF { + isa ModuleFolder + prop Label :: "Input/Output" + prop GlobalIcon :: 155 + prop GlobalHelpTopic :: (504) + prop GlobalPropertyPage :: ("{053C8F93-52A6-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type SIODRIVER { + isa ModuleFolder + prop Label :: "Device Drivers" + prop IsContainedIn :: IOF + prop GlobalIcon :: 127 + prop GlobalHelpTopic :: (505) + prop GlobalPropertyPage :: ("{A2BCEC70-5365-11d4-947C-0050048381B7}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type PROJ { + isa ObjectMgr + prop name :: "PROJ" + prop maxObjs :: 0 + prop Label :: "Project Manager" + prop GlobalIcon :: 121 + prop InstanceIcon :: 122 + prop InstanceHelpTopic :: (201) + prop GlobalHelpTopic :: (101) + prop InstancePropertyPage :: ("{AC3C77D1-890B-11d0-A621-0000C070F3E9}") + prop GlobalPropertyPage :: ("{AC3C77D2-890B-11d0-A621-0000C070F3E9}") + prop NoGen :: 1 + prop Visible :: 0 + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global ALIASALL :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Generate C Names for All Objects" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global IGNOREWARNING :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Ignore Warnings" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global LIBPATH :: ".;../../lib;$(BIOSROOT)/lib" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Library Search Path" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global INCPATH :: ".;../../include;$(BIOSROOT)/include" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Include File Search Path" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global OBJDIR :: "." { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Object file directory" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXTEXE :: "out" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Executable File Extension" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXTLIB :: "lib" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Library File Extension" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXTASM :: "asm" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Assembly Language Source File Extension" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXTOBJ :: "obj" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Object File Extension" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst projType :: "Executable" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Executable,Library" + prop Label :: "Target Type" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst projName :: "$(PROG)" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Target File Name" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst useRpt :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use RPT Instruction" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst minimizeSpace :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Optimize for Space over Time" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst tmx :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Avoid TMX Silicon Bugs" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } +} + +type PROJ_FILE { + isa ObjectMgr + prop Visible :: 0 + prop Label :: "Project File Manager" + prop InstanceHelpTopic :: (BIOSHELP_PROJ_FILE_INSTANCE) + prop GlobalHelpTopic :: (BIOSHELP_PROJ_FILE_GLOBAL) + prop InstancePropertyPage :: ("{AC3C77D3-890B-11d0-A621-0000C070F3E9}") + prop GlobalPropertyPage :: ("{AC3C77D4-890B-11d0-A621-0000C070F3E9}") + prop NoGen :: 1 + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst elemType :: "C Source" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "C Source,ASM Source,Library,Linker Command File" + prop Label :: "Input File Type" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst elemName :: "$(PROG)" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Input File Name" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst optLevel :: "register+local+global" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "register,register+local,register+local+global,register+local+global+file" + prop Label :: "Optimization Level" + prop Visible :: 0 + prop Writable :: if self.elemType == "C Source" {1} else {0} + prop NoGen :: 1 + } + inst inline :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Inline Expansion" + prop Visible :: 0 + prop Writable :: if self.elemType == "C Source" {1} else {0} + prop NoGen :: 1 + } + inst definitions :: "" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Additional Definitions" + prop Visible :: 0 + prop Writable :: if self.elemType == "C Source" {1} else {0} + prop NoGen :: 1 + } + inst iParent :: 0 { + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } +} + +type GBL { + isa Module + prop name :: "GBL" + prop Label :: "Global Settings" + prop IsContainedIn :: SYSTEM + prop cGen :: 0 + prop GenLinkPrologue :: ("%10S\nSECTIONS {%4t\n.vers (COPY): {} /* version information */%0t\n}\n\n-priority\n--trampolines\n%25S%1S%22S-l%2S%23S%3S\n%24S%15S%4S%16S%18S%5S%6S%12S%7S%17S\0, _autoInitStr, _board, _librarySuffix, _devLibStr, _biosLibStr, _rtdxLibStr, _rtsLibStr, _librarySuffix, _compilerModel, _lnkCmdStr, _lnkCmdFile, _cslLibStr, _chipType, _librarySuffix, _chipStr, _sioLibStr, _mpcLibStr, _bios6xLibStr, _bios6xClkType, _instStr, _rtsNameStr, _romStr, _biosRomStr, _logLibStr, _SKLibStr") + prop poolStr :: (if (self.LINKWITHROM == 0) {""} else {if POOL.USEPOOL {""} else {"_POOL_config=0;\n"}}) + prop msgqStr :: (if (self.LINKWITHROM == 0) {""} else {if MSGQ.USEMSGQ {""} else {"_MSGQ_config=0;\n"}}) + prop GenLinkEpilogue :: ("%0t_GBL_CACHE = GBL_CACHE;\n%1S%2S\0, poolStr, msgqStr") + prop ConfigurationClass :: "{2779A121-92CC-11d1-A63D-0000C070F3E9}" + prop GlobalIcon :: 105 + prop InstanceIcon :: 106 + prop GlobalHelpTopic :: (103) + prop InstanceHelpTopic :: (103) + prop InstancePropertyPage :: ("{B7240DE4-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DE5-AA51-11cf-9BFE-0000C0AC14C7}") + prop localInit :: (RTA_toHost.Create("HST"), RTA_fromHost.Create("HST"), RTA_dispatcher.Create("HST"), IDL_busyObj.Create("IDL"), IDL.USEIDLBUSYOBJ = 1, IDL_cpuLoad.Create("IDL")) + prop chipcall :: ("ok") + prop IsConfMod :: 1 + prop ucompare :: ($e = "ok", $a = ($1 >> 31) & 0x00000001, $b = ($2 >> 31) & 0x00000001, $c = $1 & 0x7fffffff, $d = $2 & 0x7fffffff, if ($a > $b) {$e = "gt"} else {if ($a == $b) {if ($c > $d) {$e = "gt"} else {if ($c == $d) {$e = "eq"} else {$e = "lt"}}} else {$e = "lt"}}, $e) + prop L2Check :: (if (self.DSPSUBTYPE == 6211 || self.DSPSUBTYPE == 6711) {self.PCC = "mapped", if (self.C641XL2CONFIGURE == 1) {self.C641XL2CONFIGURE = 0, self.L2CONFIGALLOC = 0} , self.L2CacheSizeCheck()} else {if (self.DSPSUBTYPE == 6400) {self.PCC = "mapped", if (self.C621XL2CONFIGURE == 1) {self.C621XL2CONFIGURE = 0} , self.L2CacheSizeCheck()} else {if (self.C621XL2CONFIGURE == 1) {self.C621XL2CONFIGURE = 0, self.L2CacheSizeCheck()} else {if (self.C641XL2CONFIGURE == 1) {self.C641XL2CONFIGURE = 0, self.L2CONFIGALLOC = 0, self.L2CacheSizeCheck()} }}}) + prop C621xL2CacheSizeCheck :: ($e = "ok", $a = CACHE_L2.base, $b = CACHE_L2.len, if (self.C621XL2CONFIGURE == 0) {CACHE_L2.Delete("MEM")} else {if (self.L2MODEOPTS == "SRAM") {CACHE_L2.base = CACHE_L2.base + CACHE_L2.len, CACHE_L2.len = 0x0, CACHE_L2.Delete("MEM")} else {if (self.L2MODEOPTS == "1-way cache") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x4000, CACHE_L2.len = 0x4000} else {if (self.L2MODEOPTS == "2-way cache") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x8000, CACHE_L2.len = 0x8000} else {if (self.L2MODEOPTS == "3-way cache") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0xc000, CACHE_L2.len = 0xc000} else {if (self.L2MODEOPTS == "4-way cache") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x10000, CACHE_L2.len = 0x10000} }}}}}, $e) + prop C641xL2CacheSizeCheck :: ($e = "ok", $a = CACHE_L2.base, $b = CACHE_L2.len, if (self.C641XL2CONFIGURE == 0) {CACHE_L2.Delete("MEM")} else {if (self.C641XL2MODEOPTS == "4-way cache (0k)") {CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x0, CACHE_L2.len = 0x0, CACHE_L2.Delete("MEM")} else {if (self.C641XL2MODEOPTS == "4-way cache (32k)") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x8000, CACHE_L2.len = 0x8000} else {if (self.C641XL2MODEOPTS == "4-way cache (64k)") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x10000, CACHE_L2.len = 0x10000} else {if (self.C641XL2MODEOPTS == "4-way cache (128k)") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x20000, CACHE_L2.len = 0x20000} else {if (self.C641XL2MODEOPTS == "4-way cache (256k)") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x40000, CACHE_L2.len = 0x40000} }}}}}, $e) + prop C64PL1PCacheSizeCheck :: ($e = "ok", if (self.C64PL2CONFIGURE == 0) {self.C64PL1PCFG = "32k", CACHE_L1P.Create("MEM"), CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x8000, CACHE_L1P.len = 0x8000} else {if (self.C64PL1PCFG == "0k") {CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x0, CACHE_L1P.len = 0x0, CACHE_L1P.Delete("MEM")} else {if (self.C64PL1PCFG == "4k") {CACHE_L1P.Create("MEM"), CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x1000, CACHE_L1P.len = 0x1000} else {if (self.C64PL1PCFG == "8k") {CACHE_L1P.Create("MEM"), CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x2000, CACHE_L1P.len = 0x2000} else {if (self.C64PL1PCFG == "16k") {CACHE_L1P.Create("MEM"), CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x4000, CACHE_L1P.len = 0x4000} else {if (self.C64PL1PCFG == "32k") {CACHE_L1P.Create("MEM"), CACHE_L1P.base = CACHE_L1P.base + CACHE_L1P.len - 0x8000, CACHE_L1P.len = 0x8000} else {$e = self.error("Unknown cache size")}}}}}}, $e) + prop C64PL1DCacheSizeCheck :: ($e = "ok", if (self.C64PL2CONFIGURE == 0) {self.C64PL1DCFG = "32k", CACHE_L1D.Create("MEM"), CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x8000, CACHE_L1D.len = 0x8000} else {if (self.C64PL1DCFG == "0k") {CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x0, CACHE_L1D.len = 0x0, CACHE_L1D.Delete("MEM")} else {if (self.C64PL1DCFG == "4k") {CACHE_L1D.Create("MEM"), CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x1000, CACHE_L1D.len = 0x1000} else {if (self.C64PL1DCFG == "8k") {CACHE_L1D.Create("MEM"), CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x2000, CACHE_L1D.len = 0x2000} else {if (self.C64PL1DCFG == "16k") {CACHE_L1D.Create("MEM"), CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x4000, CACHE_L1D.len = 0x4000} else {if (self.C64PL1DCFG == "32k") {CACHE_L1D.Create("MEM"), CACHE_L1D.base = CACHE_L1D.base + CACHE_L1D.len - 0x8000, CACHE_L1D.len = 0x8000} else {$e = self.error("Unknown cache size")}}}}}}, $e) + prop C64PL2CacheSizeCheck :: ($e = "ok", if (self.C64PL2CONFIGURE == 0) {CACHE_L2.Delete("MEM")} else {if (self.C64PL2MODEOPTS == "0k") {CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x0, CACHE_L2.len = 0x0, CACHE_L2.Delete("MEM")} else {if (self.C64PL2MODEOPTS == "32k") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x8000, CACHE_L2.len = 0x8000} else {if (self.C64PL2MODEOPTS == "64k") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x10000, CACHE_L2.len = 0x10000} else {if (self.C64PL2MODEOPTS == "128k") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x20000, CACHE_L2.len = 0x20000} else {if (self.C64PL2MODEOPTS == "256k") {CACHE_L2.Create("MEM"), CACHE_L2.base = CACHE_L2.base + CACHE_L2.len - 0x40000, CACHE_L2.len = 0x40000} else {$e = self.error("Unknown cache size")}}}}}}, $e) + prop L2CacheSizeCheck :: ($e = "ok", scan ($i; MEM) {if ($i == CACHE_L2) {if self.C621XL2CONFIGURE {$e = self.C621xL2CacheSizeCheck()} else {if self.C641XL2CONFIGURE {$e = self.C641xL2CacheSizeCheck()} else {if self.DSPSUBTYPE == 6211 || self.DSPSUBTYPE == 6711 {$e = self.C621xL2CacheSizeCheck()} else {if self.DSPSUBTYPE == 6400 {$e = self.C641xL2CacheSizeCheck()} else {{CACHE_L2.base = 0x0, CACHE_L2.len = 0x0, CACHE_L2.Delete("MEM")}}}}}} }, $e) + prop setCPUClock :: ($e = "ok", if ($1 != self.CPUCLOCK) {$a = self.CPUCLOCK, self.CPUCLOCK = $1, if (GBL.CALLBACKOBJ != nil) {$e = GBL.CALLBACKOBJ.call()} , if ($e != "ok") {self.CPUCLOCK = $a, GBL.CALLBACKOBJ.call()} } , if ($e == "ok") {"ok"} else {self.error($e)}) + prop setL2MODE :: (if (self.L2MODEOPTS == "SRAM") {0x0} else {if (self.L2MODEOPTS == "1-way cache") {0x1} else {if (self.L2MODEOPTS == "2-way cache") {0x2} else {if (self.L2MODEOPTS == "3-way cache") {0x3} else {0x7}}}}) + prop setC641XL2MODE :: (if (self.C641XL2MODEOPTS == "4-way cache (0k)") {0x0} else {if (self.C641XL2MODEOPTS == "4-way cache (32k)") {0x1} else {if (self.C641XL2MODEOPTS == "4-way cache (64k)") {0x2} else {if (self.C641XL2MODEOPTS == "4-way cache (128k)") {0x3} else {0x7}}}}) + prop _cint00Str :: "-u_c_int00 %24t/* link with alternate boot.obj */%0t\n" + prop _autoInitStr :: "" + prop _board :: (if (HST.RTDX == 1) {"lnkrtdx"} else {if (HST.DSM == 1) {"lnkdsm"} else {if (HST.EVM54 == 1) {"lnkevm54"} else {if (HST.BIOSLINK == 1) {"lnkbioslink"} else {"lnknone"}}}}) + prop _dsptype :: GBL.DSPTYPE + prop _instStr :: if self.INSTRUMENTED {""} else {"_NONINST"} + prop _rtsNameStr :: (self.RTSLIB) + prop _biosLibStr :: "-lbios%20S%23S%8S %24t/* DSP/BIOS support */%0t\n" + prop _compilerModel :: if self.ENDIAN == "big" {"e"} else {""} + prop _librarySuffix :: (if (self.DSPSUBTYPE == 6700 || self.DSPSUBTYPE == 6711 || self.DSPSUBTYPE == 6712 || self.DSPSUBTYPE == 6713) {if (self.ENDIAN == "big") {".a67e"} else {".a67"}} else {if (self.DSPSUBTYPE == 6400) {if (self.ENDIAN == "big") {".a64e"} else {".a64"}} else {if (self.DSPSUBTYPE == 6499) {if (self.ENDIAN == "big") {".a64Pe"} else {".a64P"}} else {if (self.DSPSUBTYPE == 6799) {if (self.ENDIAN == "big") {".a67Pe"} else {".a67P"}} else {if (self.ENDIAN == "big") {".a62e"} else {".a62"}}}}}) + prop _rtdxLibStr :: if RTDX.USERTDX == 0 {""} else {if RTDX.RTDXTYPE == "JTAG" {"-lrtdx64xx%9S.lib %24t/* RTDX support */%0t\n"} else {if RTDX.RTDXTYPE == "Simulator" {"-lrtdxsim%9S.lib %24t/* RTDX support */%0t\n"} else {"-lrtdxhs%9S.lib %24t/* RTDX support */%0t\n"}}} + prop _rtsLibStr :: (if self.SPECIFYRTSLIB {"-l%21S%24t/* C and C++ run-time library support */%0t\n"} else {if self.DSPSUBTYPE == 6700 || self.DSPSUBTYPE == 6711 || self.DSPSUBTYPE == 6712 || self.DSPSUBTYPE == 6713 {"-lrts6700%9S.lib%24t/* C and C++ run-time library support */%0t\n"} else {if self.DSPSUBTYPE == 6400 {"-lrts6400%9S.lib%24t/* C and C++ run-time library support */%0t\n"} else {if self.DSPSUBTYPE == 6799 {"-lrts67plus%9S.lib%24t/* C and C++ run-time library support */%0t\n"} else {if self.DSPSUBTYPE == 6499 {"-lrts64plus%9S.lib%24t/* C and C++ run-time library support */%0t\n"} else {"-lrts6200%9S.lib%24t/* C and C++ run-time library support */%0t\n"}}}}}) + prop _bios6xClkType :: (if self.CLKTYPE == 6000 {"C6000"} else {if self.CLKTYPE == 700 {"DA700"} else {if (self.CLKTYPE == 420 || self.CLKTYPE == 6424) {if self.USEIDMA0DISPATCHER {"DM420IDMA0"} else {"DM420"}} else {if self.CLKTYPE == 2430 {"2430"} else {if self.CLKTYPE == 6482 {"TCI6482"} else {if self.CLKTYPE == 6486 {"TCI6486"} else {if self.CLKTYPE == 6488 {"TCI6488"} else {if self.CLKTYPE == 442 {"DRA442"} else {if self.CLKTYPE == 3430 {"3430"} else {""}}}}}}}}}) + prop _bios6xLibStr :: ("-lbios%19S%23S%8S%24t/* BIOS clock specific library */%0t\n") + prop _chipStr :: "" + prop _mpcLibStr :: "" + prop _lnkCmdFile :: MEM.LNKCMDFILE + prop _lnkCmdStr :: (if (MEM.LNKCMDFILE == "") {""} else {"-l%11S %24t/* User Specified Linker cmd file */%0t\n"}) + prop _sioLibStr :: if SIO.USEISSUERECLAIM == 1 {"-lsioir%23S%8S %24t/* supports SIO Issue/Reclaim model only */%0t\n"} else {"-lsioboth%23S%8S %24t/* supports both SIO models */%0t\n"} + prop _devLibStr :: "-ldrivers%23S%14S %24t/* device drivers support */%0t\n" + prop _cslLibStr :: "" + prop _chipType :: "" + prop _logLibStr :: if LOG.TS {"-llog8%3S\n"} else {""} + prop _romStr :: if self.LINKWITHROM {"-lromC672x.out\n-lromC672x.cmd\n"} else {""} + prop _biosRomStr :: if self.LINKWITHROM {"_BIOSROM"} else {""} + prop _SKLibStr :: "" + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global PRODUCT :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + prop Visible :: 0 + prop Writable :: 1 + prop EnvField :: 1 + } + global CALLBACKOBJ :: CLK { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CHIPCHAIN :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global TRACE :: "CD-01234567" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Trace Mask" + prop NoGen :: 1 + prop Visible :: 0 + prop Writable :: 0 + } + global BOARD :: "c64xx" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Target Board Name" + prop JSName :: "BOARDNAME" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global ROM :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Link to ROM Library" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global CPUCLOCK :: 720.000000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global PROCID :: = 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Label :: "Processor ID (PROCID)" + prop JSName :: "PROCID" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global CLKIN :: = 20000 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Label :: "Board Clock in KHz (Informational Only)" + prop JSName :: "CLKIN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global FREQ :: 720000 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global MIPS :: 720.000000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: 0x04 + prop Format :: "%.4f" + prop Label :: "DSP Speed In MHz (CLKOUT)" + prop JSName :: "CLKOUT" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: ($a = self.MIPS, $b = if (GBL.DSPTYPE == 62) {$1} else {$1 * 2}, $e = "ok", self.MIPS = $1, self.FREQ = int(self.MIPS * 1000), if (($e = self.setCPUClock($b)) != "ok") {self.MIPS = $a} , $e) + } + global OSTYPE :: "BIOS" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "BIOS" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DSPTYPE :: 62 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "DSP Major Type" + prop JSName :: "DSPTYPE" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global SPECIFYRTSLIB :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Specify RTS library" + prop JSName :: "SPECIFYRTSLIB" + prop NoGen :: 1 + prop Visible :: 1 + prop Writable :: 1 + } + global RTSLIB :: "rts6400_eh.lib" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Run-Time Support Library" + prop JSName :: "RTSLIB" + prop NoGen :: 1 + prop Visible :: 1 + prop Writable :: self.SPECIFYRTSLIB + } + global DSPSUBTYPE :: 6400 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "6400" + prop Label :: "DSP Type" + prop Visible :: 0 + prop Writable :: 1 + prop Set :: (self.DSPSUBTYPE = $1, self.L2Check(), "ok") + prop NoGen :: 0 + } + global CLKTYPE :: 6000 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "CLK Type" + prop JSName :: "CLKTYPE" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global CHIPTYPE :: "6416" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "DM642,6410,6412,6413,6414,6415,6416,custom,other" + prop Label :: "Chip Support Library (CSL)" + prop JSName :: "CHIPTYPE" + prop NoGen :: 1 + prop Visible :: 0 + prop Writable :: 1 + prop Set :: (if ($1 == "6201" || $1 == "6202" || $1 == "6203" || $1 == "6204" || $1 == "6205") {self.DSPSUBTYPE = 6200} else {if ($1 == "6701") {self.DSPSUBTYPE = 6700} else {if ($1 == "6211") {self.DSPSUBTYPE = 6211} else {if ($1 == "6711" || $1 == "6712" || $1 == "6713" || $1 == "DA610") {if ($1 == "6711") {self.DSPSUBTYPE = 6711} , if ($1 == "6712") {self.DSPSUBTYPE = 6712} , if ($1 == "6713") {self.DSPSUBTYPE = 6713} } else {if ($1 == "DM642" || $1 == "6412" || $1 == "6414" || $1 == "6415" || $1 == "6416" || $1 == "6410" || $1 == "6413") {self.DSPSUBTYPE = 6400} }}}}, self.CHIPTYPE = $1, self.L2Check(), $e = "ok", if (GBL.CHIPCHAIN != nil) {$e = GBL.CHIPCHAIN.chipcall()} , $e) + } + global DISPCALLCSLCFGINIT :: = (self.CHIPTYPE != "other" && self.CHIPTYPE != "custom") { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call CSL_cfgInit Initialization routine" + prop Visible :: 0 + prop Writable :: self.SUPPORTCSL + prop NoGen :: 1 + } + global DSPNAME :: "TMS320C62XX" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DSPARITHMETIC :: = (if (GBL.DSPTYPE == 62 && (GBL.DSPSUBTYPE / 100) == 67) {"FLOAT"} else {"FIXED"}) { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "FIXED,FLOAT" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DSPWORDSIZE :: = (if (GBL.DSPTYPE == 30 || GBL.DSPTYPE == 40 || GBL.DSPTYPE == 62) {32} else {16}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "DSP Word Size" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DSPCHARSIZE :: = (if GBL.DSPTYPE == 62 {8} else {if GBL.DSPSUBTYPE == 5599 {8} else {GBL.DSPWORDSIZE}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "DSP Byte Size" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DATAPTRSIZE :: = (if (GBL.DSPTYPE == 62) {32} else {if (GBL.DSPTYPE == 54) {16} else {if (GBL.DSPTYPE == 55) {if (GBL.MEMORYMODEL == "SMALL") {16} else {23}} else {if (GBL.DSPTYPE == 28) {22} else {0}}}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop iComment :: "Size of the Data Pointer" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CODEPTRSIZE :: = (if (GBL.DSPTYPE == 62) {32} else {if (GBL.DSPTYPE == 54) {if (GBL.CALLMODEL == "near") {16} else {24}} else {if (GBL.DSPTYPE == 55) {24} else {if (GBL.DSPTYPE == 28) {22} else {0}}}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop iComment :: "Size of Code Pointer" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global ENDIAN :: "little" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "little,big" + prop Label :: "DSP Endian Mode" + prop JSName :: "ENDIANMODE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (self.ENDIAN = $1, "ok") + } + global BIGENDIAN :: = if self.ENDIAN == "little" {0} else {1} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global AUTOINIT :: "ROM" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "ROM,RAM" + prop Label :: "C Autoinitialization Model" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global USERINIT :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call User Init Function" + prop JSName :: "CALLUSERINITFXN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 == 0) {self.USERINITFXN = @_FXN_F_nop, self.USERINIT = $1} else {self.USERINIT = $1}, "ok") + } + global USERINITFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "User Init Function" + prop JSName :: "USERINITFXN" + prop Visible :: 1 + prop Writable :: self.USERINIT + prop NoGen :: 0 + } + global OLDAUTOCALCULATE :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "previous value for autocalculate" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global ENABLEINST :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Real Time Analysis" + prop JSName :: "ENABLEINST" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 != self.ENABLEINST) {if ($1) {RTA_toHost.Create("HST"), RTA_fromHost.Create("HST"), RTA_dispatcher.Create("HST"), IDL_busyObj.Create("IDL"), IDL.USEIDLBUSYOBJ = 1, IDL_cpuLoad.Create("IDL"), IDL.AUTOCALCULATE = self.OLDAUTOCALCULATE} else {if (self.LINKWITHROM) {self.LINKWITHROM = 0} , RTA_toHost.Delete("HST"), RTA_fromHost.Delete("HST"), RTA_dispatcher.Delete("HST"), IDL_busyObj.Delete("IDL"), IDL.USEIDLBUSYOBJ = 0, IDL_cpuLoad.Delete("IDL"), self.OLDAUTOCALCULATE = IDL.AUTOCALCULATE, IDL.AUTOCALCULATE = 0}, self.ENABLEINST = $1} , "ok") + } + global INSTRUMENTED :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use Instrumented BIOS library" + prop JSName :: "INSTRUMENTED" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global CGENERATE :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Do C Generation" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global ENABLEDLL :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Dynamic Loading" + prop JSName :: "ENABLEDLL" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global PCC :: "mapped" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "mapped,cache enable,cache freeze,cache bypass" + prop Label :: "Program Cache Control - CSR(PCC) " + prop JSName :: "CSRPCC" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6400) {0} else {1} + prop NoGen :: 1 + prop TabName :: "620x/670x" + } + global DCC :: "mapped" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "mapped,cache enable,cache freeze,cache bypass" + prop Label :: "Data Cache Control" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "620x/670x" + } + global PCACHE :: = (if (self.PCC == "mapped") {0x0000} else {if (self.PCC == "cache enable") {0x0040} else {if (self.PCC == "cache freeze") {0x0060} else {0x0080}}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global DCACHE :: = (if (self.DCC == "mapped") {0x0000} else {if (self.DCC == "cache enable") {0x0008} else {if (self.DCC == "cache freeze") {0x000c} else {0x0010}}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CACHE :: = (self.PCACHE | self.DCACHE) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global C621XL2CONFIGURE :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "621x/671x - Configure L2 Memory Settings" + prop JSName :: "C621XCONFIGUREL2" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6712 || GBL.DSPSUBTYPE == 6713) {1} else {0} + prop TabName :: "621x/671x" + prop Set :: ($e = "ok", self.C621XL2CONFIGURE = $1, self.PCC = "mapped", $e = self.L2CacheSizeCheck(), $e) + prop NoGen :: 1 + } + global C641XL2CONFIGURE :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "641x - Configure L2 Memory Settings" + prop JSName :: "C641XCONFIGUREL2" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6400) {1} else {0} + prop TabName :: "641x" + prop Set :: ($e = "ok", self.C641XL2CONFIGURE = $1, self.PCC = "mapped", $e = self.L2CacheSizeCheck(), $e) + prop NoGen :: 1 + } + global L2CONFIGURE :: = (if GBL.DSPSUBTYPE == 6400 {self.C641XL2CONFIGURE} else {self.C621XL2CONFIGURE}) { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Configure L2 Cache Control (c6x1x support)" + prop Visible :: 0 + prop NoGen :: 0 + } + global C621XPCC :: "Cache Enabled - Direct Mapped" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Cache Enabled - Direct Mapped" + prop Label :: "Program Cache Control - CSR(PCC) " + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + prop TabName :: "621x/671x" + } + global C641XPCC :: "Cache Enabled - Direct Mapped" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Cache Enabled - Direct Mapped" + prop Label :: "641x - Program Cache Control - CSR(PCC)" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + prop TabName :: "641x" + } + global L2MODEOPTS :: = "SRAM" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "L2 Mode - CCFG(L2MODE)" + prop JSName :: "C621XCCFGL2MODE" + prop Enum :: "SRAM,1-way cache,2-way cache,3-way cache,4-way cache" + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6712 || GBL.DSPSUBTYPE == 6713) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "621x/671x" + prop Set :: ($i = self.L2MODEOPTS, self.L2MODEOPTS = $1, $e = self.L2CacheSizeCheck(), if ($e != "ok") {self.L2MODEOPTS = $i} , $e) + } + global C641XL2MODEOPTS :: "4-way cache (0k)" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "641x L2 Mode - CCFG(L2MODE)" + prop Enum :: "4-way cache (0k),4-way cache (32k),4-way cache (64k),4-way cache (128k),4-way cache (256k)" + prop JSName :: "C641XCCFGL2MODE" + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "641x" + prop Set :: ($i = self.C641XL2MODEOPTS, self.C641XL2MODEOPTS = $1, $e = self.L2CacheSizeCheck(), if ($e != "ok") {self.C641XL2MODEOPTS = $i} , $e) + } + global L2MODE :: = (if GBL.DSPSUBTYPE == 6400 {self.setC641XL2MODE()} else {self.setL2MODE()}) { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "L2 Mode - CCFG(L2MODE) Values" + prop Enum :: "0,1,2,3,7" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global L2PRIORITY :: 0 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "L2 Requestor Priority - CCFG(P)" + prop Enum :: "0,1" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global L2MARMASK :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "L2 MAR0-15 - bitmask used to initialize MARs" + prop JSName :: "C621XMAR" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6712 || GBL.DSPSUBTYPE == 6713) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "621x/671x" + } + global SUPPORTCSL :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 0 + } + global ENABLEALLTRC :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable All TRC Trace Event Classes" + prop JSName :: "ENABLEALLTRC" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (if ($1) {self.TRCMASKVALUE = 0xDBEF} else {self.TRCMASKVALUE = 0x4000}, self.ENABLEALLTRC = $1, "ok") + } + global TRCMASKVALUE :: 56303 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 0 + } + global CALLCSLCFGINIT :: = self.DISPCALLCSLCFGINIT { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 0 + } + global CDBPATH :: "" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "CDB search path in COFF file" + prop JSName :: "CDBRELATIVEPATH" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global LINKWITHROM :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Link with ROM" + prop JSName :: "LINKWITHROM" + prop Visible :: 0 + prop Writable :: if (self.DSPSUBTYPE == 6799 && self.ENABLEINST) {1} else {0} + prop NoGen :: 1 + prop Set :: ($e = "ok", if ($1) {$e = self.error("This BIOS version does not support linking with ROM.")} , $e) + } + global C641XL2PRIORITY :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2MARMASK1 :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAR96-111 - bitmask controls EMIFB CE space" + prop JSName :: "C641XMAREMIFB" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2MARMASK2 :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAR128-143 - bitmask controls EMIFA CE0 space" + prop JSName :: "C641XMARCE0" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2MARMASK3 :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAR144-159 - bitmask controls EMIFA CE1 space" + prop JSName :: "C641XMARCE1" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2MARMASK4 :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAR160-175 - bitmask controls EMIFA CE2 space" + prop JSName :: "C641XMARCE2" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2MARMASK5 :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAR176-191 - bitmask controls EMIFA CE3 space" + prop JSName :: "C641XMARCE3" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2REQPRIORITY :: "urgent" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "641x L2 Requestor Priority Queue - CCFG(P)" + prop JSName :: "C641XCCFGP" + prop Enum :: "urgent,high,medium,low" + prop Visible :: 1 + prop Writable :: if ((GBL.DSPSUBTYPE == 6400) && GBL.L2CONFIGURE == 1) {1} else {0} + prop NoGen :: 1 + prop Set :: (self.L2REQPRIORITY = $1, if (self.L2REQPRIORITY == "urgent") {self.C641XL2PRIORITY = 0} else {if (self.L2REQPRIORITY == "high") {self.C641XL2PRIORITY = 1} else {if (self.L2REQPRIORITY == "medium") {self.C641XL2PRIORITY = 2} else {self.C641XL2PRIORITY = 3}}}, "ok") + prop TabName :: "641x" + } + global L2CONFIGALLOC :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Configure Priority Queues" + prop JSName :: "C641XSETL2ALLOC" + prop Visible :: 1 + prop Writable :: (GBL.DSPSUBTYPE == 6400 && GBL.L2CONFIGURE == 1) + prop NoGen :: 0 + prop TabName :: "641x" + } + global L2ALLOC0 :: 6 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Max L2 Transfer Requests on URGENT Queue (L2ALLOC0)" + prop JSName :: "C641XL2ALLOC0" + prop Enum :: "0,1,2,3,4,5,6,7" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6400 && GBL.L2CONFIGURE == 1 && GBL.L2CONFIGALLOC == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "641x" + } + global L2ALLOC1 :: 2 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Max L2 Transfer Requests on HIGH Queue (L2ALLOC1)" + prop JSName :: "C641XL2ALLOC1" + prop Enum :: "0,1,2,3,4,5,6,7" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6400 && GBL.L2CONFIGURE == 1 && GBL.L2CONFIGALLOC == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "641x" + } + global L2ALLOC2 :: 2 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Max L2 Transfer Requests on MEDIUM Queue (L2ALLOC2)" + prop JSName :: "C641XL2ALLOC2" + prop Enum :: "0,1,2,3,4,5,6,7" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6400 && GBL.L2CONFIGURE == 1 && GBL.L2CONFIGALLOC == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "641x" + } + global L2ALLOC3 :: 2 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Max L2 Transfer Requests on LOW Queue (L2ALLOC3)" + prop JSName :: "C641XL2ALLOC3" + prop Enum :: "0,1,2,3,4,5,6,7" + prop Visible :: 1 + prop Writable :: if (GBL.DSPSUBTYPE == 6400 && GBL.L2CONFIGURE == 1 && GBL.L2CONFIGALLOC == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "641x" + } + global L2ALLOC :: = ((self.L2ALLOC0) | (self.L2ALLOC1 << 4) | (self.L2ALLOC2 << 8) | (self.L2ALLOC3 << 12)) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop NoGen :: 0 + } +} + +type MEM { + isa ObjectMgr + prop Label :: "MEM - Memory Section Manager" + prop name :: "MEM" + prop DependsOn :: "SEM" + prop IsContainedIn :: SYSTEM + prop GlobalIcon :: 115 + prop InstanceIcon :: 116 + prop GlobalHelpTopic :: (108) + prop InstanceHelpTopic :: (208) + prop InstancePropertyPage :: ("{3D658E70-05E7-11d0-BD44-0020AFEE33C8}") + prop GlobalPropertyPage :: ("{3D658E71-05E7-11d0-BD44-0020AFEE33C8}") + prop heapLabelStr :: (self.iHeapId) + prop GenLinkPrologue :: (if (GBL.DSPTYPE == 55) {"-stack 0x%1x\n-sysstack 0x%2x\n\nMEMORY {%4t\0, _cmd55stksz, _cmd55systksz"} else {"-stack 0x%1x\nMEMORY {%4t\0, _stackSize"}) + prop _stackSize :: MEM.STACKSIZE + prop AllocType :: (if (self.REUSE == 0 && self.USERCMD == 0) {"19\0, _argsString, _argsSeg, _midPlace, _sysdataString, _sysdataSeg, _thirdPlace, _trcinitString, _trcinitSeg, _midPlace, _gblinitString, _gblinitSeg, _midPlace, _memObjString, _memObjSeg, _midPlace, _sysinitString, _initSeg, _sysinitPlace, _sysregsString, _regsSeg, _midPlace, _bssString, _bssSeg, _firstPlace, _farString, _farSeg, _secondPlace, _cinitString, _cinitSeg, _midPlace, _pinitString, _pinitSeg, _midPlace, _dataString, _dataSeg, _midPlace, _constString, _constSeg, _midPlace, _switchString, _switchSeg, _midPlace, _cioString, _cioSeg, _midPlace, _textString, _textSeg, _midPlace, _frtString, _frtSeg, _midPlace, _biosString, _biosSeg, _midPlace, _stackString, _stackSeg, _midPlace"} else {if (self.REUSE == 0 && self.USERCMD == 1) {"9\0, _argsString, _argsSeg, _midPlace, _sysdataString, _sysdataSeg, _thirdPlace, _trcinitString, _trcinitSeg, _midPlace, _gblinitString, _gblinitSeg, _midPlace, _memObjString, _memObjSeg, _midPlace, _sysinitString, _initSeg, _sysinitPlace, _sysregsString, _regsSeg, _midPlace, _biosString, _biosSeg, _midPlace, _stackString, _stackSeg, _midPlace"} else {if (self.REUSE == 1 && self.USERCMD == 0) {"18\0, _argsString, _argsSeg, _midPlace, _sysdataString, _sysdataSeg, _thirdPlace, _trcinitString, _trcinitSeg, _midPlace, _gblinitString, _gblinitSeg, _midPlace, _memObjString, _memObjSeg, _midPlace, _sysregsString, _regsSeg, _midPlace, _bssString, _bssSeg, _firstPlace, _farString, _farSeg, _secondPlace, _cinitString, _cinitSeg, _midPlace, _pinitString, _pinitSeg, _midPlace, _dataString, _dataSeg, _midPlace, _constString, _constSeg, _midPlace, _switchString, _switchSeg, _midPlace, _cioString, _cioSeg, _midPlace, _textString, _textSeg, _midPlace, _frtString, _frtSeg, _midPlace, _biosString, _biosSeg, _midPlace, _stackString, _stackSeg, _midPlace"} else {"8\0, _argsString, _argsSeg, _midPlace, _sysdataString, _sysdataSeg, _thirdPlace, _trcinitString, _trcinitSeg, _midPlace, _gblinitString, _gblinitSeg, _midPlace, _memObjString, _memObjSeg, _midPlace, _sysregsString, _regsSeg, _midPlace, _biosString, _biosSeg, _midPlace, _stackString, _stackSeg, _midPlace"}}}) + prop _firstPlace :: 0 + prop _secondPlace :: 0 + 1 + prop _thirdPlace :: 0 + 2 + prop _midPlace :: (0x7fffffff / 2) + prop _sysinitPlace :: (0x7fffffff / 2) + prop _argsString :: ("%8t .args: align=4 fill=0 {%12t\n *(.args)\n . += 0x%1x;%8t\n }\0, _argsSize") + prop _bssString :: ("%8t .bss: {}") + prop _farString :: ("%8t .far: {}") + prop _cinitString :: (if (self.ENABLELOADSEG == 1) {if (MEM.CINITSEG == MEM.LOADCINITSEG) {"%8t .cinit: {}"} else {"%8t .cinit: {} load > %1s, run\0, _loadcinitSeg"}} else {"%8t .cinit: {}"}) + prop _pinitString :: (if (self.ENABLELOADSEG == 1) {if (MEM.PINITSEG == MEM.LOADPINITSEG) {"%8t .pinit: {}"} else {"%8t .pinit: {} load > %1s, run\0, _loadpinitSeg"}} else {"%8t .pinit: {}"}) + prop _trcinitString :: (if (self.ENABLELOADSEG == 1) {if (MEM.TRCINITSEG == MEM.LOADTRCINITSEG) {"%8t .trcdata: {}"} else {"%8t .trcdata: {} load > %1s, run\0, _loadtrcinitSeg"}} else {"%8t .trcdata: {}"}) + prop _gblinitString :: (if (self.ENABLELOADSEG == 1) {if (MEM.BIOSINITSEG == MEM.LOADBIOSINITSEG) {"%8t .gblinit: {}"} else {"%8t .gblinit: {} load > %1s, run\0, _loadgblinitSeg"}} else {"%8t .gblinit: {}"}) + prop _dataString :: ("%8t .data: {}") + prop _constString :: (if (self.ENABLELOADSEG == 1) {if (MEM.CONSTSEG == MEM.LOADCONSTSEG) {"%8t GROUP {\n %8t .const: align = 0x8 {} \n %8t .printf (COPY): {} \n%8t }"} else {"%8t .const: align = 0x8 {} load > %1s run\0, _loadconstSeg"}} else {"%8t GROUP {\n %8t .const: align = 0x8 {} \n %8t .printf (COPY): {} \n%8t }"}) + prop _switchString :: (if (self.ENABLELOADSEG == 1) {if (MEM.SWITCHSEG == MEM.LOADSWITCHSEG) {"%8t .switch: {}"} else {"%8t .switch: {} load > %1s, run\0, _loadswitchSeg"}} else {"%8t .switch: {}"}) + prop _sysmemString :: ("%8t .sysmem: {}") + prop _cioString :: ("%8t .cio: {}") + prop _memObjString :: ("%8t .mem: {}") + prop _sysdataString :: (if ((GBL.ROM == 0) && (GBL.DSPTYPE == 54)) {"%8t .sysdata: align = 128 {%12t\n GBL_A_SYSPAGE = .;\n GBL_A_SYSDP = GBL_A_SYSPAGE >> 7;\n %8t }"} else {"%8t .sysdata: {}"}) + prop _sysinitString :: (if (self.ENABLELOADSEG == 1) {if (MEM.INITSEG == MEM.LOADINITSEG) {"%8t .sysinit: {}"} else {"%8t .sysinit: {} load > %1s, run\0, _loadinitSeg"}} else {"%8t .sysinit: {}"}) + prop _sysregsString :: ("%8t .sysregs: {}") + prop _textString :: (if (self.ENABLELOADSEG == 1) {if (MEM.TEXTSEG == MEM.LOADTEXTSEG) {"%8t .text: {}"} else {"%8t .text: {} load > %1s, run\0, _loadtextSeg"}} else {"%8t .text: {}"}) + prop _frtString :: ("%8t frt: {}") + prop _biosString :: (if (self.ENABLELOADSEG == 1) {if (MEM.BIOSSEG == MEM.LOADBIOSSEG) {"%8t .bios: {}"} else {"%8t .bios: {} load > %1s, run\0, _loadbiosSeg"}} else {"%8t .bios: {}"}) + prop _stackString :: (if (GBL.DSPTYPE == 62) {"%8t .stack: {%12t\n GBL_stackbeg = .;\n *(.stack)\n GBL_stackend = GBL_stackbeg + 0x%1x - 1;%12t\n _HWI_STKBOTTOM = GBL_stackbeg + 0x%1x - 4 & ~7;%12t\n _HWI_STKTOP = GBL_stackbeg;%8t\n }\0, _stackSize, _stackSize"} else {if (GBL.DSPTYPE == 54) {"%8t .stack: {%12t\n GBL_stackbeg = .;\n *(.stack)\n GBL_stackend = ((GBL_stackbeg + 0x%1x - 1) & 0xfffe) ;%8t\n _HWI_STKBOTTOM = GBL_stackend;%12t\n _HWI_STKTOP = GBL_stackbeg;%8t\n }\0, _stackSize"} else {if (GBL.DSPTYPE == 55) {"%8t GROUP { \n%16t .sysstack : align = 0x4 {%12t\n %16t GBL_sysstackbeg = .;\n %16t *(.sysstack)\n %16t GBL_sysstackend = GBL_sysstackbeg + 0x%2x -1 ;%12t\n %16t _HWI_SYSSTKTOP = GBL_sysstackbeg; %12t\n %16t_HWI_SYSSTKBOTTOM = (GBL_sysstackend+1);\n%16t} \n%16t .stack: align = 0x4 {%12t\n %16t GBL_stackbeg = .;\n %16t *(.stack)\n GBL_stackend = (GBL_stackbeg + 0x%1x - 1) ;%12t\n %16t _HWI_STKBOTTOM = (GBL_stackend+1);%12t\n %16t _HWI_STKTOP = (GBL_stackbeg);%16t\n }%8t\n } BLOCK(0x20000), run \0, _cmd55stksz, _cmd55systksz"} else {"%8t .stack: {%12t\n GBL_stackbeg = .;\n *(.stack)\n GBL_stackend = GBL_stackbeg + 0x%1x - 1;%8t\n _HWI_STKBOTTOM = GBL_stackbeg;%12t\n _HWI_STKTOP = (GBL_stackend + 1);%8t\n }\0, _stackSize"}}}) + prop _memHdrSize :: 8 + prop GenLinkEpilogue :: ("%0t}") + prop _stackSeg :: MEM.STACKSEG + prop _textSeg :: MEM.TEXTSEG + prop _frtSeg :: MEM.TEXTSEG + prop _biosSeg :: MEM.BIOSSEG + prop _dataSeg :: MEM.DATASEG + prop _cioSeg :: MEM.CIOSEG + prop _sysmemSeg :: MEM.SYSMEMSEG + prop _constSeg :: MEM.CONSTSEG + prop _initSeg :: MEM.INITSEG + prop _pinitSeg :: MEM.PINITSEG + prop _trcinitSeg :: MEM.TRCINITSEG + prop _gblinitSeg :: MEM.BIOSINITSEG + prop _regsSeg :: MEM.SYSDATASEG + prop _sysdataSeg :: MEM.SYSDATASEG + prop _argsSeg :: MEM.ARGSSEG + prop _argsSize :: MEM.ARGSSIZE + prop _bssSeg :: MEM.BSSSEG + prop _farSeg :: MEM.FARSEG + prop _cinitSeg :: MEM.CINITSEG + prop _memObjSeg :: MEM.CFGOBJSEG + prop _switchSeg :: MEM.SWITCHSEG + prop _loadtextSeg :: MEM.LOADTEXTSEG + prop _loadbiosSeg :: MEM.LOADBIOSSEG + prop _loadconstSeg :: MEM.LOADCONSTSEG + prop _loadinitSeg :: MEM.LOADINITSEG + prop _loadpinitSeg :: MEM.LOADPINITSEG + prop _loadtrcinitSeg :: MEM.LOADTRCINITSEG + prop _loadgblinitSeg :: MEM.LOADBIOSINITSEG + prop _loadcinitSeg :: MEM.LOADCINITSEG + prop _loadswitchSeg :: MEM.LOADSWITCHSEG + prop AllocInst :: (if (self.iAllocHeap == 1) {"1\0, _instAllocDesc, _objMemSeg, _placement"} ) + prop _instAllocDesc :: (if self.INITSEG.iAllocHeap && self.REUSE && self.INITSEG == self {"%8t GROUP {%12t\n .sysinitgap {. += 0x%2x;}\n .sysinit:\n .%0r$heap: {%16t\n _%0r_base = %0r$B;\n _%0r_length = %0r$L;\n . += 0x%1x;%12t\n }%8t\n } START(%0r$B), SIZE(%0r$L)\0, _heapsize, _sysinitgap, _heaplen"} else {"%8t .%0r$heap: {%12t\n %0r$B = .;\n _%0r_base = .;\n %0r$L = 0x%2x;\n _%0r_length = 0x%2x;\n . += 0x%1x;%8t\n }\0, _heapsize, _heaplen"}) + prop _objMemSeg :: self + prop _placement :: 0x7fffffff - 1 + prop _heapsize :: (self.iHeapSize) + prop _heaplen :: (self.iHeapSize) + prop _sysinitgap :: 2 * 4 + prop GenInstLink :: (if GBL.DSPTYPE == 62 {"%0r %16t: origin = 0x%1x, %40tlen = 0x%2x%4t\0, _origin, _len"} else {if GBL.DSPTYPE == 55 {"PAGE %3d: %16t%0r: %26torigin = 0x%1x, %40tlen = 0x%2x%4t\0, _cmd55origin, _cmd55len, _page"} else {"PAGE %3d: %14t%0r: %26torigin = 0x%1x, %50tlen = 0x%2x%4t\0, _origin, _len, _page"}}) + prop localInit :: ($d = "ok", scan ($i; MEM) {if ($i.space == "code" && $i.iAllocHeap == 1) {$d = self.error("Code memory cannot have a heap")} }, if (self.SEGZERO.iAllocHeap == 1) {self.SEGZERO.iReqHeapCount++} else {$d = self.error("Segment for DSP/BIOS objects must be a memory segment with a heap")}, if (self.MALLOCSEG.iAllocHeap == 1) {self.MALLOCSEG.iReqHeapCount++} else {$d = self.error("Segment for malloc()/free() must be a memory segment with a heap")}, $d) + prop _page :: (self.page) + prop _origin :: (self.base) + prop _len :: (self.len) + prop maxObjs :: (32767) + prop codeMember :: (if $1.dynamicLoading == 1 {0} else {if GBL.DSPTYPE == 62 {(($1.space == "code") || ($1.space == "code/data"))} else {if GBL.DSPTYPE == 54 {($1.space == "code")} else {if GBL.DSPTYPE == 28 {($1.space == "code")} else {if GBL.DSPTYPE == 55 {(($1.space == "code") || ($1.space == "code/data"))} else {($1.space == "code/data")}}}}}) + prop dataMember :: (if $1.dynamicLoading == 1 {0} else {if GBL.DSPTYPE == 62 {($1.space == "data" || $1.space == "code/data") && $1 != MEM_NULL} else {if GBL.DSPTYPE == 54 {(($1.space != "code") && ($1 != MEM_NULL)) && $1.space != "io"} else {if GBL.DSPTYPE == 28 {(($1.space != "code") && ($1 != MEM_NULL)) && $1.space != "io"} else {if GBL.DSPTYPE == 55 {($1.space == "data" || $1.space == "code/data") && $1 != MEM_NULL} else {(($1.space == "code/data") && ($1 != MEM_NULL))}}}}}) + prop dataNullMember :: (if $1.dynamicLoading == 1 {0} else {if GBL.DSPTYPE == 62 {$1.space == "data" || $1.space == "code/data"} else {if GBL.DSPTYPE == 54 {$1.space != "code" && $1.space != "io"} else {if GBL.DSPTYPE == 28 {$1.space != "code" && $1.space != "io"} else {if GBL.DSPTYPE == 55 {$1.space == "data" || $1.space == "code/data"} else {$1.space == "code/data"}}}}}) + prop dataCodeMember :: (if $1.dynamicLoading == 1 {0} else {if GBL.DSPTYPE == 62 {($1.space == "data" || $1.space == "code/data") && $1 != MEM_NULL} else {if GBL.DSPTYPE == 54 {$1.space == "code" && $1 != MEM_NULL} else {if GBL.DSPTYPE == 28 {$1.space == "code" && $1 != MEM_NULL} else {if GBL.DSPTYPE == 55 {($1.space == "data" || $1.space == "code/data") && $1 != MEM_NULL} else {$1.space == "code/data" && $1 != MEM_NULL}}}}}) + prop memWritable :: (self.iIsModifiable && self.iDelUser != "MEM") + prop validate :: ($e = self.checkMemOverlap($1), if ($e == "ok") {$e = self.checkHeapSize($1)} , if ($e == "ok") {$e = self.checkHeapSeg($1)} , $e) + prop checkHeapSeg :: ($e = "ok", if ($1 == MEM_NULL && MEM.NOHEAPS == 0) {if (MEM.MALLOCSEG == MEM_NULL) {$e = ("Heaps are enabled, but the segment for malloc (MEM.MALLOCSEG) is not set correctly. Please create a heap in one of your data segments and set MEM.MALLOCSEG to it.")} , if (MEM.SEGZERO == MEM_NULL) {$e = ("Heaps are enabled, but the segment for DSP/BIOS Objects (MEM.BIOSOBJSEG) is not set correctly. Please create a heap in one of your data segments and set MEM.BIOSOBJSEG to it.")} } , $e) + prop checkHeapSize :: ($e = "ok", if (MEM.NOHEAPS == 0) {if ($1.iAllocHeap && $1 != MEM_NULL) {if ($1.iHeapSize > $1.len) {$e = ("MEM segment %s: heap cannot be larger than the length of segment that contains it.")} } } , $e) + prop checkMemOverlap :: ($e = "ok", if ($1 != MEM_NULL && $1.iIsUsed == 1) {if ($1.len == 0) {$a = $1.base} else {$a = ($1.base + $1.len - 1)}, scan ($j; MEM) {if ($1 != $j && $j != MEM_NULL && $j.iIsUsed == 1 && (GBL.DSPTYPE == 62 || $1.space == $j.space)) {if (!($j == CACHE_L2 && GBL.L2CONFIGURE == 0)) {$b = $j.base, if ($j.len == 0) {$c = $j.base} else {$c = ($j.base + $j.len - 1)}, if ($a >= $b && $1.base <= $c) {$e = ("MEM segment %s: overlaps with another segment or cache configuration."), break} } } }} , $e) + prop _spaceEnum :: (self.ENUMSPACE) + prop checkHeapId :: ($e = "ok", scan ($i; MEM) {if ($i.iAllocHeap == 1 && $i.iUserHeapId == 1 && $i.iHeapId == $1 && $i.iHeapId != @segment_name) {$e = self.error("This identifier label is already in use"), break} }, $e) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 2 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumHeap :: = ($a = 0, scan ($i; MEM) {if ($i != MEM_NULL) {$a += $i.iAllocHeap} }, $a) { + prop NoGen :: 0 + } + global REUSE :: = (if self.INITSEG.space != "code" && self.INITSEG.iAllocHeap == 1 {self.SAVEREUSE} else {0}) { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Reuse Startup Code Space" + prop JSName :: "REUSECODESPACE" + prop Visible :: 1 + prop Writable :: self.INITSEG.space != "code" && self.INITSEG.iAllocHeap == 1 + prop NoGen :: 1 + prop Set :: (self.SAVEREUSE = $1, "ok") + } + global SAVEREUSE :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + global doCheckOverlap :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global MAPSELECT :: "Map 1" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Map Mode" + prop JSName :: "MAPMODE" + prop Enum :: "Map 0,Map 1" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global ARGSSIZE :: 4 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "0x%04x" + prop Style :: 0x01 | 0x02 + prop Label :: "Argument Buffer Size" + prop JSName :: "ARGSSIZE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (if ($1 < 4) {self.error("The 'arguments' section must have at least 4 words.")} else {self.ARGSSIZE = $1, "ok"}) + } + global ARGSSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataMember($1) + prop Label :: "Argument Buffer Section (.args)" + prop JSName :: "ARGSSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + } + global BIOSSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.codeMember($1) + prop Label :: "BIOS Code Section (.bios)" + prop JSName :: "BIOSSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Code" + } + global STACKSIZE :: 1024 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "0x%04x" + prop Style :: if GBL.DSPTYPE == 54 {0x01 | 0x02} else {0x02} + prop Label :: "Stack Size (MAUs)" + prop JSName :: "STACKSIZE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (if ((GBL.DSPTYPE == 55) && (GBL.DSPSUBTYPE != 5599)) {self.STACKSIZE = ($1 & -2)} else {if ((GBL.DSPTYPE == 55) && (GBL.DSPSUBTYPE == 5599)) {self.STACKSIZE = ($1 & -4)} else {self.STACKSIZE = $1}}, "ok") + prop PropSetOkUserMsg :: if (MEM.STACKSIZE < GlobalStatus.MinStackSize) {"Warning: You are setting the stack size to a value that is less than the Estimated Minimum Stack Size!"} else {"ok"} + } + global USERCMD :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "User .cmd File For Compiler Sections" + prop JSName :: "USERCOMMANDFILE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global STACKSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataMember($1) + prop Label :: "Stack Section (.stack)" + prop JSName :: "STACKSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + prop Set :: (if (GBL.DSPTYPE == 55) {(MEM.STACKSEG = $1), (MEM.SYSSTACKSEG = $1)} else {(MEM.STACKSEG = $1)}, "ok") + } + global ENABLELOADSEG :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Specify Separate Load Addresses" + prop JSName :: "ENABLELOADADDR" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global LOADBIOSSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.codeMember($1) + prop Label :: "Load Address - BIOS Code Section (.bios)" + prop JSName :: "LOADBIOSSEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global INITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.codeMember($1) + prop Label :: "Startup Code Section (.sysinit)" + prop JSName :: "SYSINITSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Code" + } + global LOADINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.codeMember($1) + prop Label :: "Load Address - Startup Code Section (.sysinit)" + prop JSName :: "LOADSYSINITSEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global BIOSINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataCodeMember($1) + prop Label :: "DSP/BIOS Init Tables (.gblinit)" + prop JSName :: "GBLINITSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + } + global TRCINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataCodeMember($1) + prop Label :: "TRC Initial Value (.trcdata)" + prop JSName :: "TRCDATASEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + } + global LOADBIOSINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataCodeMember($1) + prop Label :: "Load Address - DSP/BIOS Init Tables (.gblinit)" + prop JSName :: "LOADGBLINITSEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global LOADTRCINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataCodeMember($1) + prop Label :: "Load Address - TRC Initial Value (.trcdata)" + prop JSName :: "LOADTRCDATASEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global SYSDATASEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataMember($1) + prop Label :: "DSP/BIOS Kernel State (.sysdata)" + prop JSName :: "SYSDATASEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + } + global CFGOBJSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: self.dataMember($1) + prop Label :: "DSP/BIOS Conf Sections (.*obj)" + prop JSName :: "OBJSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Data" + } + global NOHEAPS :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "No Dynamic Memory Heaps" + prop JSName :: "NOMEMORYHEAPS" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (if ($1) {self.SEGZERO.iReqHeapCount--, self.SEGZERO = MEM_NULL, self.MALLOCSEG.iReqHeapCount--, self.MALLOCSEG = MEM_NULL, TSK.STACKSEG.iReqHeapCount--, TSK.STACKSEG = MEM_NULL, scan ($i; MEM) {if ($i.iAllocHeap && $i != MEM_NULL) {$i.iAllocHeap = 0, $i.iHeapSize = 0} }} , self.NOHEAPS = $1, "ok") + prop PropSetOkUserMsg :: if (MEM.NOHEAPS == 1) {"Currently specified heaps no longer valid"} else {"Please reconfigure heaps under individual mem segments"} + } + global SEGZERO :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataNullMember($1) && $1.iAllocHeap) + prop Label :: "Segment For DSP/BIOS Objects" + prop JSName :: "BIOSOBJSEG" + prop Visible :: 1 + prop Writable :: MEM.NOHEAPS == 0 + prop NoGen :: 0 + prop Set :: (if (self.SEGZERO.iReqHeapCount > 0) {self.SEGZERO.iReqHeapCount--} , self.SEGZERO = $1, self.SEGZERO.iReqHeapCount++, "ok") + } + global MALLOCSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataNullMember($1) && $1.iAllocHeap) + prop Label :: "Segment For malloc() / free()" + prop JSName :: "MALLOCSEG" + prop Visible :: 1 + prop Writable :: (MEM.NOHEAPS == 0) + prop NoGen :: 0 + prop Set :: (if (self.MALLOCSEG.iReqHeapCount > 0) {self.MALLOCSEG.iReqHeapCount--} , self.MALLOCSEG = $1, self.MALLOCSEG.iReqHeapCount++, "ok") + } + global USEMPC :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Memory Protection Controller module" + prop JSName :: "USEMPC" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global LNKCMDFILE :: "" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Specify User Linker cmd File" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global TEXTSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.codeMember($1)) + prop Label :: "Text Section (.text)" + prop JSName :: "TEXTSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global LOADTEXTSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.codeMember($1)) + prop Label :: "Load Address - Text Section (.text)" + prop JSName :: "LOADTEXTSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0 && self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global SWITCHSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "Switch Jump Tables (.switch)" + prop JSName :: "SWITCHSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global LOADSWITCHSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "Load Address - Switch Jump Tables (.switch)" + prop JSName :: "LOADSWITCHSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0 && self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global BSSSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "C Variables Section (.bss)" + prop JSName :: "BSSSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global FARSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "C Variables Section (.far)" + prop JSName :: "FARSEG" + prop Visible :: if GBL.DSPTYPE == 62 {1} else {0} + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global CINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "Data Initialization Section (.cinit)" + prop JSName :: "CINITSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global LOADCINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "Load Address - Data Initialization Section (.cinit)" + prop JSName :: "LOADCINITSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0 && self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global PINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "C Function Initialization Table (.pinit)" + prop JSName :: "PINITSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global LOADPINITSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataCodeMember($1)) + prop Label :: "Load Address - C Function Initialization Table (.pinit)" + prop JSName :: "LOADPINITSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0 && self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global CONSTSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "Constant Sections (.const, .printf)" + prop JSName :: "CONSTSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global LOADCONSTSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "Load Address - Constant Sections (.const, .printf)" + prop JSName :: "LOADCONSTSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0 && self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global DATASEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "Data Section (.data)" + prop JSName :: "DATASEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global CIOSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "Data Section (.cio)" + prop JSName :: "CIOSEG" + prop Visible :: 1 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + prop Set :: (self.CIOSEG = $1, self.SYSMEMSEG = $1, "ok") + } + global SYSMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: (self.dataMember($1)) + prop Label :: "Data Section (.sysmem)" + prop JSName :: "SYSMEMSEG" + prop Visible :: 0 + prop Writable :: (self.USERCMD == 0) + prop NoGen :: 1 + prop TabName :: "Compiler Sections" + } + global STUBMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Function Stub Memory (.hwi)" + prop JSName :: "HWISEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Code" + prop Set :: (self.STUBMEMSEG = $1, HWI.STUBMEMSEG = $1, "ok") + } + global LOADSTUBMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Load Address - Function Stub Memory (.hwi)" + prop JSName :: "LOADHWISEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global VECMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Interrupt Service Table Memory (.hwi_vec)" + prop JSName :: "HWIVECSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Code" + prop Set :: (self.VECMEMSEG = $1, HWI.VECMEMSEG = $1, GlobalStatus.gDirty = 1, if ($1.base == 0) {HWI.GENERATE_RESET_VEC = 0} , "ok") + } + global LOADVECMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Load Address -Interrupt Service Table Memory (.hwi_vec)" + prop JSName :: "LOADHWIVECSEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global RTDXTEXTMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "RTDX Text Segment (.rtdx_text)" + prop JSName :: "RTDXTEXTSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop TabName :: "BIOS Code" + prop Set :: (self.RTDXTEXTMEMSEG = $1, RTDX.TEXTMEMSEG = $1, "ok") + } + global LOADRTDXTEXTMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Load Address - RTDX Text Segment (.rtdx_text)" + prop JSName :: "LOADRTDXTEXTSEG" + prop Visible :: 1 + prop Writable :: (self.ENABLELOADSEG == 1) + prop NoGen :: 1 + prop TabName :: "Load Address" + } + global ENUMSPACE :: = if GBL.DSPTYPE == 62 {"code,data,code/data,reserved"} else {if GBL.DSPTYPE == 54 {"code,data,io,other,reserved"} else {if GBL.DSPTYPE == 28 {"code,data,io,other,reserved"} else {if GBL.DSPTYPE == 55 {"code/data,code,data,io,reserved"} else {"code/data,io,reserved"}}}} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "ENUMSPACE" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst base :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: if GBL.DSPTYPE == 62 {"0x%08x"} else {"0x%06x"} + prop Style :: 0x02 + prop Label :: "base" + prop JSName :: "base" + prop Visible :: 1 + prop Writable :: (self.iIsModifiable) + prop NoGen :: 1 + prop Set :: ($e = "ok", $a = self.base, self.base = $1, if (MEM.CALLBACKOBJ != nil) {$e = MEM.CALLBACKOBJ.call(self), if ($e != "ok") {self.base = $a} } , $e) + } + inst len :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: if GBL.DSPTYPE == 62 {"0x%08x"} else {"0x%04x"} + prop Style :: 0x08 + prop Label :: "len" + prop JSName :: "len" + prop Visible :: 1 + prop Writable :: (self.memWritable) + prop NoGen :: 0 + prop Set :: ($e = "ok", $a = self.len, self.len = $1, if (MEM.CALLBACKOBJ != nil) {$e = MEM.CALLBACKOBJ.call(self), if ($e != "ok") {self.len = $a} } , "ok") + } + inst page :: = (if GBL.DSPTYPE == 62 {-1} else {if GBL.DSPTYPE == 55 {(if self.space == "code" {0} else {if self.space == "data" {1} else {if self.space == "io" {2} else {0}}})} else {if self.space == "code" {0} else {if self.space == "data" {1} else {if self.space == "io" {2} else {3}}}}}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iAllocHeap :: if MEM.NOHEAPS == 1 {0} else {1} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "create a heap in this memory" + prop JSName :: "createHeap" + prop Visible :: 1 + prop Writable :: (self.space == "data" || self.space == "code/data") && (MEM.NOHEAPS == 0) && self.memWritable + prop NoGen :: 0 + prop Set :: ($a = "ok", if ($1 == 0 && self.iReqHeapCount > 0) {self.error("This heap is used by one or more of: segment for DSP/BIOS objects, segment for malloc()/free(), TSK default stack segment")} else {if ($1 == 0) {self.iUserHeapId = 0, self.iHeapId = @segment_name} , self.iAllocHeap = $1, MEM.gDirty = 1, $a}) + } + inst iHeapSize :: 0x8000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: if GBL.DSPTYPE == 62 {"0x%08x"} else {"0x%04x"} + prop Style :: 0x02 + prop Label :: "heap size" + prop JSName :: "heapSize" + prop Visible :: 1 + prop Writable :: (self.iAllocHeap) && (self.iIsModifiable) && (MEM.NOHEAPS == 0) + prop Set :: (self.iHeapSize = $1, "ok") + prop NoGen :: 1 + } + inst iSegZero :: = MEM.SEGZERO + inst iUserHeapId :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "enter a user defined heap identifier label" + prop JSName :: "enableHeapLabel" + prop Set :: (if ($1 == 0) {self.iHeapId = @segment_name} , self.iUserHeapId = $1, "ok") + prop Visible :: 1 + prop Writable :: (self.iAllocHeap) && (self.iIsModifiable) && (self.NOHEAPS == 0) + prop NoGen :: 1 + } + inst iHeapId :: @segment_name { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "heap identifier label" + prop JSName :: "heapLabel" + prop Set :: ($e = self.checkHeapId($1), if ($e == "ok") {self.iHeapId = $1} , $e) + prop Writable :: (self.iAllocHeap) && (self.iIsModifiable) && (self.NOHEAPS == 0) && (self.iUserHeapId) + prop Visible :: 1 + prop NoGen :: 0 + } + inst iReqHeapCount :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst space :: (if GBL.DSPTYPE == 55 {"code/data"} else {"data"}) { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: MEM._spaceEnum() + prop JSName :: "space" + prop Visible :: 1 + prop Writable :: (self.memWritable) + prop NoGen :: 1 + prop Set :: ($e = "ok", if ($1 != "data" && $1 != "code/data" && self.iAllocHeap == 1) {$e = self.error("Cannot select this space if a heap will be created")} else {$a = self.space, self.space = $1, if (MEM.CALLBACKOBJ != nil) {$e = MEM.CALLBACKOBJ.call(self), if ($e != "ok") {self.space = $a} } }, $e) + } + inst dynamicLoading :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Reserved for dynamic loading" + prop JSName :: "dynamicLoading" + prop Visible :: GBL.ENABLEDLL + prop Writable :: GBL.ENABLEDLL + prop NoGen :: 1 + } + inst iIsModifiable :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +object MEM_NULL :: MEM { + param iComment :: "Place holder segment which allows user to disable heaps" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param base :: 0 + param len :: 0 + param iAllocHeap :: 1 + param iHeapSize :: 32768 + param iUserHeapId :: 0 + param iHeapId :: @segment_name + param iReqHeapCount :: 0 + param space :: "data" + param dynamicLoading :: 0 + param iIsModifiable :: 1 +} + +type OBJ { + isa ObjectMgr + prop name :: "OBJ" + prop Visible :: 0 + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _objMemDesc, _memSeg, _placement"} ) + prop _objMemDesc :: ("%8t .obj: {}") + prop _memSeg :: MEM.CFGOBJSEG + prop _placement :: (0x7fffffff / 2) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type BUF { + isa ObjectMgr + prop name :: "BUF" + prop Label :: "BUF - Buffer Manager" + prop IsContainedIn :: SYSTEM + prop GlobalIcon :: 199 + prop InstanceIcon :: 200 + prop InstanceHelpTopic :: (421) + prop GlobalHelpTopic :: (321) + prop InstancePropertyPage :: ("{B7240DE8-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DE9-AA51-11cf-9BFE-0000C0AC14C7}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t.buf:{}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop AllocInst :: ("1\0, _instAllocDesc, _instMemSeg, _placement") + prop _instAllocDesc :: ("%8t .%0s$data: align = 0x%1x {%12t\n %0s$databeg = .;\n .+= %2d; %8t\n }\0, _objAlign, _buflength") + prop _objAlign :: self.align + prop _instMemSeg :: self.bufseg + prop _buflength :: (self.postalignsize * self.bufcount) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"buf.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far BUF_Obj %0r;\n\0"} else {"extern BUF_Obj %0r;\n\0"}) + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = ((7 + 3) * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = ((7 + 4) * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = ((7 + 3) * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (12 + 6)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (12 + 6)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (7 + 4)} , if (GBL.DSPTYPE == 28) {$a = (12 + 6)} , $a) + prop dataSize :: ($d = 0, scan ($i; BUF) {if ($i.IsConfObj()) {$d += $i.len} , $d += BUF.objectSize}, $d) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global ENABLED :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Compile in logging" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst bufseg :: self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Memory segment for buffer pool" + prop JSName :: "bufSeg" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst bufcount :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Buffer count" + prop JSName :: "bufCount" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (self.bufcount = $1, self.postalignsize = (self.size + (self.align - 1)) & ~(self.align - 1), self.len = $1 * self.postalignsize, "ok") + } + inst size :: 8 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Buffer size (MADUs)" + prop JSName :: "size" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 < 8) {self.error("Size should be atleast 8 bytes")} else {self.size = $1, self.postalignsize = ($1 + (self.align - 1)) & ~(self.align - 1), self.len = self.postalignsize * self.bufcount, "ok"}) + } + inst align :: 4 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Buffer alignment(Power of 2)" + prop JSName :: "align" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 < 4) {self.error("Alignment should be atleast 4 ")} else {self.align = $1, self.postalignsize = (self.size + ($1 - 1)) & ~($1 - 1), self.len = self.postalignsize * self.bufcount, "ok"}) + } + inst len :: self.size { + prop Label :: "Buffer pool length (MADUs)" + prop JSName :: "len" + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + } + inst postalignsize :: self.size { + prop Label :: "Buffer size after alignment (MADUs)" + prop JSName :: "postalignsize" + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 0 + } +} + +type POOL { + isa Module + prop Visible :: 1 + prop name :: "POOL" + prop Label :: "POOL - Allocator Manager" + prop IsConfMod :: self.USEPOOL + prop IsContainedIn :: SYSTEM + prop GlobalIcon :: 199 + prop InstanceIcon :: 200 + prop GlobalHelpTopic :: (324) + prop InstanceHelpTopic :: (424) + prop InstancePropertyPage :: ("{473C4A62-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{473C4A63-B1A8-11d0-9885-0020AFEE33C6}") + prop DependsOn :: "MEM,BUF" + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global USEPOOL :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Allocator Manager" + prop JSName :: "ENABLEPOOL" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } +} + +type CLK { + isa ObjectMgr + prop name :: "CLK" + prop Label :: "CLK - Clock Manager" + prop IsContainedIn :: SCH + prop IsConfMod :: 1 + prop GlobalIcon :: 103 + prop InstanceIcon :: 104 + prop InstanceHelpTopic :: (202) + prop GlobalHelpTopic :: (102) + prop InstancePropertyPage :: ("{EEB2AB41-51E3-11d0-A61D-0000C070F3E9}") + prop GlobalPropertyPage :: ("{EEB2AB40-51E3-11d0-A61D-0000C070F3E9}") + prop objectSize :: (if (GBL.DSPTYPE == 55 || GBL.DSPTYPE == 28) {$a = (2 * 4)} else {$a = (1 * 4)}, $a) + prop GenLinkPrologue :: ("SECTIONS {%4t\n.%1L: {\n%8t \n CLK_F_gethtime = %5s;\n %1U_A_TABBEG = .;\n %4S\n %1U_A_TABEND = .;\n %1U_A_TABLEN = (. - %1U_A_TABBEG) / %2d;\n%4t} > %3s \0, name, _objSize, _memSeg, _linkString, clkFxn, _clkStartFxn") + prop _clkStartFxn :: if (GBL.SUPPORTCSL && self.USETIMER) {@_CLK_start6x} else {@FXN_F_nop} + prop GenLinkEpilogue :: ("%0t}\n_CLK_PRD = CLK_PRD;\n_CLK_COUNTSPMS = CLK_COUNTSPMS;\n_CLK_REGS = CLK_REGS;\n_CLK_USETIMER = CLK_USETIMER;\n_CLK_TIMERNUM = CLK_TIMERNUM;\n_CLK_TDDR = CLK_TDDR;\n\0") + prop _linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no CLK objs */"} + prop _memSeg :: CLK.OBJMEMSEG + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop clkFxn :: if (self.USETIMER == 1) {self.CLKFXN} else {@FXN_F_zero} + prop maxObjs :: (32767) + prop SortByField :: "iPri" + prop SortGroups :: 1 + prop localInit :: (if (GBL.CALLBACKOBJ != CLK) {CLK.gGBLChain = GBL.CALLBACKOBJ, GBL.CALLBACKOBJ = CLK} ) + prop dataSize :: (self.objectSize() * (CLK.gNumOf + 1)) + prop localCanCreate :: (if self.USETIMER {"ok"} else {self.error("The CLK Manager must be enabled before inserting a CLK")}) + prop localCreate :: (CLK.HOOKFXN = @HWI_F_dispatch, self.seizeHwi(self.WHICHHWI), "ok") + prop localDelete :: (if (self.gNumOf == 1) {if (GBL.CALLMODEL == "far") {CLK.HOOKFXN = @CLK_F_frete, self.seizeHwi(self.WHICHHWI)} else {CLK.HOOKFXN = @CLK_F_rete, self.seizeHwi(self.WHICHHWI)}} , "ok") + prop adjustPrd :: (if GBL.DSPTYPE == 62 {0} else {if GBL.DSPSUBTYPE == 5599 {0} else {1}}) + prop seizeHwi :: (if ($1.client == "USER" && $1 == HWI_UNUSED) {self.error("Interrupt not mapped for selected timer.")} else {if ($1.client == "USER" && $1.function != @HWI_unused) {self.error("Interrupt mapped to selected timer is already in use.")} else {if ($1.client == "CSL") {self.error("Interrupt mapped to selected timer is already in use by CSL.")} else {$1.function = @CLK_F_isr, $1.client = "CLK", $1.iEventId = $1.iSource.iIntrSelectNum, $1.iUseDispatcher = (if CLK.HOOKFXN == @HWI_F_dispatch {1} else {0}), $1.iArg = (if $1.iUseDispatcher == 1 {@CLK_A_TABBEG} else {0}), HWI.gDirty = 1, "ok"}}}) + prop releaseHwi :: ($1.function = @HWI_unused, $1.client = "USER", $1.iUseDispatcher = 0, $1.iArg = 0, HWI.gDirty = 1, "ok") + prop seizeTimer :: (if ($1 == "Timer 0") {self.WHICHTIMER = "Timer 0", self.WHICHHWI = Timer_0.iHwi, self.REGS = if (GBL.DSPSUBTYPE == 5599) {0x620} else {0x01000}, self.TIMERNUM = 0, self.TIMERIMR = 0x0, self.TIMERIFR = 0x1, self.INTBIT = 4, self.TIMERIMRMASK = self.WHICHHWI.Ier0Mask, self.IMR0TINTMASK = self.WHICHHWI.Ier0Mask, self.IMR1TINTMASK = 0x0, self.setMicroseconds(self.MICROSECONDS)} else {if ($1 == "Timer 1") {self.WHICHTIMER = "Timer 1", self.WHICHHWI = Timer_1.iHwi, self.REGS = if (GBL.DSPSUBTYPE == 5599) {0x640} else {0x2400}, self.TIMERNUM = 1, self.TIMERIMR = 0x45, self.TIMERIFR = 0x46, self.INTBIT = 6, self.TIMERIMRMASK = self.WHICHHWI.Ier1Mask, self.IMR0TINTMASK = 0x0, self.IMR1TINTMASK = self.WHICHHWI.Ier1Mask, self.setMicroseconds(self.MICROSECONDS)} else {if ($1 == "Timer 2") {self.WHICHTIMER = "Timer 2", self.WHICHHWI = Timer_2.iHwi, self.REGS = 0x4000, self.TIMERNUM = 2, self.TIMERIMR = 0x0, self.TIMERIFR = 0x1, self.INTBIT = 11, self.TIMERIMRMASK = self.WHICHHWI.Ier0Mask, self.IMR0TINTMASK = self.WHICHHWI.Ier0Mask, self.IMR1TINTMASK = 0x0, self.setMicroseconds(self.MICROSECONDS)} }}, "ok") + prop setMicroseconds :: ($a = if FIXTDDR == 1 {self.TDDR} else {0xffffffff}, $b = 0xffffffff, $c = (float($a) + 1.0) * ((float($b) + self.adjustPrd) / (GBL.MIPS / 8)), if ($1 < $c && $1 > 0.1) {if (self.FIXTDDR == 0) {self.TDDR = int((1.0 * $1 * GBL.MIPS / 8) / (float($b) + self.adjustPrd))} , self.PRD = int((1.0 * $1 * GBL.MIPS) / (8 * (self.TDDR + 1.0))) - self.adjustPrd, self.MICROSECONDS = ((float((self.PRD)) + CLK.adjustPrd) * ((self.TDDR) + 1.0) * 8 / GBL.MIPS), if (self.CALLBACKOBJ != nil) {self.CALLBACKOBJ.call()} , "ok"} else {self.error("The on-chip timer does not have enough range to support this combination of DSP MIPS and Microseconds/Int")}) + prop call :: ($a = ((float((CLK.PRD)) + CLK.adjustPrd) * ((CLK.TDDR) + 1.0) * 8 / GBL.MIPS), $b = CLK.MICROSECONDS, $e = "ok", if (($e = self.setMicroseconds(CLK.MICROSECONDS)) == "ok") {if (CLK.gGBLChain != nil) {$e = CLK.gGBLChain.call()} , if ($e != "ok") {self.setMicroseconds($b), self.error($e)} else {"ok"}} else {$e}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gGBLChain :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: self.USETIMER + prop NoGen :: 1 + } + global WHICHHWI :: HWI_INT14 { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: HWI + prop Label :: "CPU Interrupt" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + } + global INTBIT :: = self.WHICHHWI.iIntrEnableMask + global WHICHTIMER :: "Timer 0" { + prop Label :: "Timer Selection" + prop JSName :: "TIMERSELECT" + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Timer 0,Timer 1,Timer 2" + prop Visible :: 1 + prop Writable :: self.USETIMER + prop NoGen :: 1 + prop Set :: (if (self.WHICHTIMER != $1) {if (self.USETIMER == 0) {$e = "ok"} else {if (self.WHICHHIRESTIMER == $1) {$e = self.error("Must choose a timer different from the high resolution timer")} else {if ($1 == "Timer 0") {$a = Timer_0.iHwi} else {if ($1 == "Timer 1") {$a = Timer_1.iHwi} else {$a = Timer_2.iHwi}}, $e = self.seizeHwi($a)}}, if ($e == "ok") {self.releaseHwi(self.WHICHHWI), if ($1 == "Timer 0") {self.TIMERNUM = 0, self.WHICHHWI = Timer_0.iHwi} else {if ($1 == "Timer 1") {self.TIMERNUM = 1, self.WHICHHWI = Timer_1.iHwi} else {self.TIMERNUM = 2, self.WHICHHWI = Timer_2.iHwi}}, self.WHICHTIMER = $1, self.HOOKFXN = if self.gNumOf > 0 {@HWI_F_dispatch} else {(if GBL.CALLMODEL == "far" {@CLK_F_frete} else {@CLK_F_rete})}, self.seizeHwi(self.WHICHHWI)} , $e} ) + } + global REGS :: = if self.WHICHTIMER == "Timer 0" {self.TIMER0BASE} else {if self.WHICHTIMER == "Timer 1" {self.TIMER1BASE} else {self.TIMER2BASE}} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Visible :: 0 + prop Writable :: 1 + } + global TIMER0BASE :: 26476544 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Writable :: 1 + prop Visbile :: 0 + prop JSName :: "TIMER0BASE" + prop NoGen :: 1 + } + global TIMER1BASE :: 26738688 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Writable :: 1 + prop Visbile :: 0 + prop JSName :: "TIMER1BASE" + prop NoGen :: 1 + } + global TIMER2BASE :: 28049408 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Writable :: 1 + prop Visbile :: 0 + prop JSName :: "TIMER2BASE" + prop NoGen :: 1 + } + global TIMERNUM :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop NoGen :: 0 + } + global USETIMER :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable CLK Manager" + prop JSName :: "ENABLECLK" + prop Visible :: 1 + prop Writable :: if self.gNumOf > 0 {0} else {1} + prop NoGen :: 0 + prop Set :: (if ($1 == 1 && self.USETIMER == 0) {if (($e = self.seizeHwi(self.WHICHHWI)) == "ok") {self.USETIMER = 1, self.TIMEFXN = if CLK.HIRES {CLK.clkFxn()} else {@CLK_F_getltime}, self.HOOKFXN = if GBL.CALLMODEL == "far" {@CLK_F_frete} else {@CLK_F_rete}, self.seizeHwi(self.WHICHHWI), GlobalStatus.gDirty = 1, if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {self.releaseHwi(self.WHICHHWI), self.TIMEFXN = @FXN_F_zero, self.HOOKFXN = @FXN_F_nop, self.USETIMER = 0, GlobalStatus.gDirty = 1, self.error("Current stack size inadequate to enable CLK")} else {if (GBL.ENABLEINST == 1) {IDL_busyObj.Create("IDL"), IDL.USEIDLBUSYOBJ = 1, IDL_cpuLoad.Create("IDL"), IDL.AUTOCALCULATE = GBL.OLDAUTOCALCULATE} , $e}} else {$e}} else {if ($1 == 0 && self.USETIMER == 1) {self.releaseHwi(self.WHICHHWI), self.TIMEFXN = @FXN_F_zero, self.HOOKFXN = @FXN_F_nop, self.USETIMER = 0, if (GBL.ENABLEINST == 1) {IDL_busyObj.Delete("IDL"), IDL.USEIDLBUSYOBJ = 0, IDL_cpuLoad.Delete("IDL"), GBL.OLDAUTOCALCULATE = IDL.AUTOCALCULATE, IDL.AUTOCALCULATE = 0} , "ok"} else {"ok"}}) + } + global HIRES :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use high resolution time for internal timings" + prop JSName :: "HIRESTIME" + prop Visible :: 1 + prop Writable :: self.USETIMER + prop NoGen :: 1 + prop Set :: (if (CLK.USETIMER) {CLK.HIRES = $1, if (CLK.USETIMER) {CLK.TIMEFXN = if CLK.HIRES {CLK.clkFxn()} else {@CLK_F_getltime}} , "ok"} else {self.error("CLK Manager must be enabled in order to get high resolution timings.")}) + } + global INSTRPERCLK :: 8 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global MICROSECONDS :: 10.000000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: 0x04 + prop Format :: "%.4f" + prop Label :: "Microseconds/Int" + prop JSName :: "MICROSECONDS" + prop Set :: (self.setMicroseconds($1)) + prop Visible :: 1 + prop Writable :: if ((CLK.PROGTIMREGS != 0) | (self.USETIMER == 0)) {0} else {1} + prop NoGen :: 1 + } + global MICROSECS :: = int(round(self.MICROSECONDS)) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global PROGTIMREGS :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Directly configure on-chip timer registers" + prop JSName :: "CONFIGURETIMER" + prop Visible :: 1 + prop Writable :: self.USETIMER + prop NoGen :: 1 + } + global TCR :: = 0x20 | CLK.TDDR { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 | 0x02 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global FIXTDDR :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Fix TDDR" + prop JSName :: "FIXTDDR" + prop Visible :: (GBL.DSPTYPE != 62) && (GBL.DSPSUBTYPE != 2420) && (GBL.DSPSUBTYPE != 5599) + prop Writable :: CLK.PROGTIMREGS && (GBL.DSPTYPE != 62) && (GBL.DSPSUBTYPE != 2420) && (GBL.DSPSUBTYPE != 5599) + prop NoGen :: 1 + } + global TDDR :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Label :: if GBL.DSPSUBTYPE == 5561 {"TDDR Register (PREMD=0)"} else {"TDDR Register"} + prop JSName :: "TCRTDDR" + prop Set :: (if ((GBL.DSPSUBTYPE != 5502) && (GBL.DSPSUBTYPE != 5802) && (GBL.DSPTYPE != 62) && (GBL.DSPSUBTYPE != 5599) && ($1 > 0xffffffff)) {self.error("The on-chip timer does not have enough range to support this value, maximum is 15.")} else {CLK.TDDR = $1, CLK.MICROSECONDS = ((float((CLK.PRD)) + CLK.adjustPrd) * ((CLK.TDDR) + 1.0) * 8 / GBL.MIPS), if (CLK.CALLBACKOBJ != nil) {CLK.CALLBACKOBJ.call()} , "ok"}) + prop Visible :: GBL.DSPTYPE != 62 + prop Writable :: CLK.PROGTIMREGS && GBL.DSPTYPE != 62 + prop NoGen :: 0 + } + global TDDRHIGH :: = ((self.TDDR & 0xffff0000) >> 16) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + } + global PRD :: 900 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Label :: if (GBL.CLKTYPE == 700) {"Compare0 Register"} else {"PRD Register"} + prop JSName :: "PRD" + prop Set :: (CLK.PRD = $1, CLK.MICROSECONDS = ((float((CLK.PRD)) + CLK.adjustPrd) * ((CLK.TDDR) + 1.0) * 8 / GBL.MIPS), if (CLK.CALLBACKOBJ != nil) {CLK.CALLBACKOBJ.call()} , "ok") + prop Visible :: 1 + prop Writable :: if ((self.PROGTIMREGS) && (self.USETIMER)) {1} else {0} + prop NoGen :: 0 + } + global PRDHIGH :: = ((self.PRD & 0xffff0000) >> 16) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + } + global COUNTSPMS :: = int(round(GBL.MIPS * 1000.0 / (CLK.TDDR + 1) / 8)) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + } + global COUNTSPMSHIGH :: = ((self.COUNTSPMS & 0xffff0000) >> 16) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + } + global INSTRUCTIONS :: = (1.0 * (float(CLK.PRD) + CLK.adjustPrd) * (CLK.TDDR + 1.0) * 8) { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: 0x04 + prop Format :: "%.0f" + prop Label :: "Instructions/Int" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + } + global TIMEFXN :: @CLK_F_getshtime { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global HOOKFXN :: @HWI_F_dispatch { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global CLKFXN :: = if (CLK.PRD == 0xffffffff) || (CLK.WHICHHIRESTIMER != "None") {@CLK_F_getfhtime} else {@CLK_F_getshtime} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: PRD { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALDIV :: = if GBL.DSPSUBTYPE == 2420 {self.HTIMEDIV} else {1} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global CALMULT :: = if GBL.DSPSUBTYPE == 2420 {self.HTIMEMULT} else {if GBL.DSPSUBTYPE == 1510 {self.PRDMULTFACTOR * 8} else {8}} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global HTIMEDIV :: = if GBL.DSPSUBTYPE == 2420 {self.setHtimeParams()} else {1} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global HTIMEMULT :: = if GBL.DSPSUBTYPE == 1510 {self.PRDMULTFACTOR * 8} else {if GBL.DSPSUBTYPE == 2420 {self.setHtimeParams()} else {if GBL.DSPSUBTYPE == 5502 {8} else {if GBL.DSPSUBTYPE == 6499 {1} else {((self.TDDR + 1) * 8)}}}} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global LTIMEDIV :: = if GBL.DSPSUBTYPE == 2420 {if self.INPUTCLK == 0.032 {self.setLtimeParams()} else {self.HTIMEDIV}} else {1} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global LTIMEMULT :: = if GBL.DSPSUBTYPE == 1510 {(self.PRDMULTFACTOR * self.PRD * 8)} else {if GBL.DSPSUBTYPE == 2420 {if self.INPUTCLK == 0.032 {self.setLtimeParams()} else {(self.HTIMEMULT * self.PRD)}} else {((self.TDDR + 1) * (self.PRD + self.adjustPrd) * (8))}} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global HTIMEPERLTIME :: = if GBL.DSPSUBTYPE == 5502 {int(round(GBL.MIPS * self.MICROSECONDS / 8))} else {if GBL.DSPSUBTYPE == 2420 {int(round(self.HTIMECLK * self.MICROSECONDS / 8))} else {if GBL.DSPSUBTYPE == 6499 {int(round(GBL.MIPS * self.MICROSECONDS))} else {(self.PRD + CLK.adjustPrd)}}} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x20 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global WHICHHIRESTIMER :: "None" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "None,Timer 0,Timer 1,Timer 2" + prop Label :: "Timer to use for high resolution timings" + prop JSName :: "WHICHHIRESTIMER" + prop Visible :: 1 + prop Writable :: self.USETIMER + prop NoGen :: 1 + prop Set :: (if ($1 == self.WHICHTIMER) {$e = self.error("Must choose a timer different from the system tick timer")} else {self.WHICHHIRESTIMER = $1, $e = "ok"}, $e) + } + global HIRESREGS :: = if self.WHICHHIRESTIMER != "None" {(if self.WHICHHIRESTIMER == "Timer 0" {self.TIMER0BASE} else {if self.WHICHHIRESTIMER == "Timer 1" {self.TIMER1BASE} else {self.TIMER2BASE}})} else {(self.REGS)} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst function :: @FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "function" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst Order :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 1 + prop Writable :: 1 + } + inst iPri :: 0 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop NoGen :: 1 + } +} + +type PRD { + isa ObjectMgr + prop name :: "PRD" + prop Label :: "PRD - Periodic Function Manager" + prop IsContainedIn :: SCH + prop IsConfMod :: 1 + prop GlobalIcon :: 119 + prop InstanceIcon :: 120 + prop InstanceHelpTopic :: (210) + prop GlobalHelpTopic :: (110) + prop InstancePropertyPage :: ("{B7240DE0-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DE1-AA51-11cf-9BFE-0000C0AC14C7}") + prop STSGetMaxFmt :: ("%g ticks") + prop STSGetSumFmt :: (PRD.STSGetMaxFmt()) + prop STSGetAvgFmt :: ("%.2f ticks") + prop GetPeriod :: self.period + prop IsOneShot :: if self.mode == "one-shot" {1} else {0} + prop objectSize :: (if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (10 * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (9 * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (12 * 4)} , if (GBL.DSPTYPE == 28 || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE")) {$a = (12 * 4)} , if (GBL.DSPTYPE == 62) {$a = (8 * 4)} , $a) + prop GenLinkPrologue :: ("SECTIONS {%4t\n.%1L: {\n%8t %1U_A_TABBEG = .;\n %4S\n %1U_A_TABEND = .;\n %1U_A_TABLEN = (. - %1U_A_TABBEG) / %2d;\n%4t} > %3s%5s\0, name, objSize, memSeg, linkString, pageString") + prop GenLinkEpilogue :: ("%0t}\n\0") + prop linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop pageString :: if GBL.DSPTYPE == 62 {""} else {if GBL.DSPTYPE == 55 {(if PRD.OBJMEMSEG.space() == "code" {" PAGE 0"} else {if PRD.OBJMEMSEG.space() == "data" {" PAGE 1"} else {if PRD.OBJMEMSEG.space() == "io" {" PAGE 2"} else {" PAGE 0"}}})} else {if GBL.DSPTYPE == 28 {" PAGE 1"} else {" PAGE 1"}}} + prop memSeg :: PRD.OBJMEMSEG + prop objSize :: if GBL.DSPTYPE == 55 {self.objectSize() * 2} else {self.objectSize()} + prop dataSize :: (self.objectSize() * PRD.gNumOf) + prop localInit :: (if (CLK.CALLBACKOBJ != nil) {self.error("PRD initialization failure")} , CLK.CALLBACKOBJ = PRD, if (PRD.USECLK && PRD_clock.iIsUsed == 0) {PRD_clock.Create("PRD")} , if (PRD_clock.iIsUsed == 1) {if (self.gNumOf == 0) {if (TSK.USETSK == 1 && TSK.TSKTICK == "PRD") {PRD_clock.function = @PRD_F_tick} else {PRD_clock.function = @FXN_F_nop}} else {PRD_clock.function = @PRD_F_tick}} ) + prop localCanCreate :: (if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {self.error(" System Stack Size too small")} else {self.myCreate("can")}) + prop localCreate :: (STS.gNumEmbed += 1, if (($a = self.myCreate("do")) == "ok") {if (PRD_clock.iIsUsed == 1) {if (self.gNumOf == 0) {PRD_clock.function = @PRD_F_tick} } } , $a) + prop localCanDelete :: (self.myDelete("can")) + prop localDelete :: (STS.gNumEmbed -= 1, if (($a = self.myDelete("do")) == "ok") {if (self.gNumOf == 1) {if (PRD_clock.iIsUsed == 1) {if (TSK.USETSK == 1 && TSK.TSKTICK == "PRD") {PRD_clock.function = @PRD_F_tick} else {PRD_clock.function = @FXN_F_nop}} } } , $a) + prop maxObjs :: (32767) + prop myCreate :: (if (PRD_swi.function != @PRD_F_swi) {PRD_swi.function = @PRD_F_swi} , if (PRD_swi.iIsUsed) {"ok"} else {if (SWI.CanCreate() == "ok") {if ($1 == "do") {if (KNL_swi.iIsUsed == 1 && PRD_swi.pri == 0) {PRD_swi.pri = 1} , PRD_swi.Create("PRD")} else {"ok"}} else {self.error("Can't create an SWI for PRD (try deleting a SWI)")}}) + prop myDelete :: (if (PRD_swi.function != @PRD_F_swi) {PRD_swi.function = @PRD_F_swi} , if (self.gNumOf == 1) {if ($1 == "do") {PRD_swi.Delete("PRD")} else {"ok"}} else {"ok"}) + prop call :: (if (CLK.USETIMER != 0) {PRD.MICROSECONDS = CLK.MICROSECONDS} , PRD.CALLBACKOBJ.call()) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"prd.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far PRD_Obj %0r;\n\0"} else {"extern PRD_Obj %0r;\n\0"}) + prop SortByField :: "iPri" + prop SortGroups :: 1 + prop DEFAULT_THOOKFXN :: @_KNL_tick + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global USECLK :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use CLK Manager to drive PRD" + prop JSName :: "USECLK" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: (if ($1 == 1 && self.USECLK == 0) {if (CLK.USETIMER == 0) {self.error("In order to drive periodic functions, the CLK Manager must be enabled")} else {self.USECLK = 1, self.MICROSECONDS = CLK.MICROSECONDS, CLK.CALLBACKOBJ = PRD, PRD_clock.Create("PRD"), GlobalStatus.gDirty = 1, if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {self.USECLK = 0, self.MICROSECONDS = 0.0, CLK.CALLBACKOBJ = nil, PRD_clock.Delete("PRD"), self.error("Current Stack size inadequate to enable this option")} else {"ok"}}} else {if ($1 == 0 && self.USECLK == 1) {self.USECLK = 0, self.MICROSECONDS = 0.0, CLK.CALLBACKOBJ = nil, PRD_clock.Delete("PRD")} , "ok"}) + prop NoGen :: 1 + } + global MICROSECONDS :: 10.000000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: 0x04 + prop Format :: "%.1f" + prop Label :: "Microseconds/Tick" + prop JSName :: "MICROSECONDS" + prop Visible :: 1 + prop Writable :: self.USECLK == 0 + prop NoGen :: 1 + } + global SCALAR :: = ($d = 2, $f = 0, while ($d <= 0x4000 && $f == 0) {scan ($i; PRD) {if ((($i.period / $d) * $d != $i.period)) || ($i.mode == "one-shot") {$f = 1} }, if ($f == 0) {$d = 2 * $d} }, $d / 2) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global THOOKFXN :: @_KNL_tick { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "System Tick Hook Function" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global CALLBACKOBJ :: STS { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst period :: 0x7fff { + prop Label :: "period (ticks)" + prop JSName :: "period" + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if (($1 > 0) && ($1 < 0x8000)) {self.period = $1, self.gDirty = 1, "ok"} else {self.error("Periodic function periods must be greater than 0 and less than 0x8000")}) + } + inst mode :: "continuous" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "continuous,one-shot" + prop JSName :: "mode" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst function :: @FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst arg0 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg0" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst arg1 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg1" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst milliseconds :: = ((self.period * PRD.MICROSECONDS) / 1000.0) { + prop Label :: "period (ms)" + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: 0x04 + prop Format :: "%.1f" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + } + inst Order :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 0 + prop Writable :: 1 + } + inst iPri :: 0 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop NoGen :: 1 + } + inst filter :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filter" + prop NoGen :: 0 + } + inst maxformat :: "%g ticks" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "maxformat" + prop NoGen :: 0 + } + inst sumformat :: "%g ticks" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "sumformat" + prop NoGen :: 0 + } + inst avgformat :: "%.2f ticks" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "avgformat" + prop NoGen :: 0 + } + inst unittype :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "unittype" + prop NoGen :: 0 + } +} + +object PRD_swi :: SWI { + param iComment :: "This Software ISR executes all configured PRD functions" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "PRD" + param iDelMsg :: "This object is automatically deleted when all PRD objects are deleted" + param function :: @PRD_F_swi + param pri :: 1 + param mailbox :: 0 + param arg0 :: 0 + param arg1 :: 0 + param dorta :: 1 + param Order :: 0 + param filter :: 2 + param maxformat :: "%g inst" + param sumformat :: "%g inst" + param avgformat :: "%.2f inst" + param filtmaxmult :: 1 + param filtsummult :: 1 + param unittype :: 0 +} + +object PRD_clock :: CLK { + param iComment :: "This clock function calls PRD_tick from within the on-chip timer ISR" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "PRD" + param iDelMsg :: "This object is automatically deleted by disabling the 'Use CLK Manager to drive PRD' option of PRD" + param function :: @PRD_F_tick + param Order :: 0 + param iPri :: 0 +} + +type RTDX { + isa ObjectMgr + prop Label :: "RTDX - Real-Time Data Exchange Settings" + prop name :: "RTDX" + prop IsConfMod :: self.USERTDX + prop IsContainedIn :: IOF + prop GlobalIcon :: 145 + prop InstanceIcon :: 146 + prop GlobalHelpTopic :: (113) + prop InstanceHelpTopic :: (213) + prop InstancePropertyPage :: ("{f80273c0-3838-11d2-a32c-006097656921}") + prop GlobalPropertyPage :: ("{050a0600-3839-11d2-a32c-006097656921}") + prop AllocType :: (if self.USERTDX {"2\0, _rtdxDataAllocDesc, _rtdxDataSeg, _placement, + _rtdxTextAllocDesc, _rtdxTextSeg, _placement"} else {""}) + prop _rtdxDataAllocDesc :: (" .%1L_data: {} \0, name") + prop _rtdxTextAllocDesc :: (if (MEM.ENABLELOADSEG == 1) {if (MEM.RTDXTEXTMEMSEG == MEM.LOADRTDXTEXTMEMSEG) {" .%1L_text: {} \0, name"} else {" .%1L_text: {} load > %2s, run \0, name, _loadRtdxTextMemSeg"}} else {" .%1L_text: {} \0, name"}) + prop _rtdxDataSeg :: RTDX.DATAMEMSEG + prop _rtdxTextSeg :: MEM.RTDXTEXTMEMSEG + prop _loadRtdxTextMemSeg :: MEM.LOADRTDXTEXTMEMSEG + prop _placement :: (0x7fffffff / 2) + prop _objSize :: RTDX.BUFMEMSIZE + prop GenLinkPrologue :: (if self.USERTDX {"_RTDX_interrupt_mask = 0x%1x;\n\0, _interruptMask"} else {""}) + prop _interruptMask :: RTDX.MASK + prop cGen :: 1 + prop noObjectAlias :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"rtdx.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {if (self.iChannelMode == "output") {"extern far RTDX_outputChannel %0r;\n\0"} else {"extern far RTDX_inputChannel %0r;\n\0"}} else {if (self.iChannelMode == "output") {"extern RTDX_outputChannel %0r;\n\0"} else {"extern RTDX_inputChannel %0r;\n\0"}}) + prop cGenCInst :: (if (self.iChannelMode == "output") {"RTDX_CreateOutputChannel(%0r);\n\0"} else {"RTDX_CreateInputChannel(%0r);\n\0"}) + prop dataSize :: ($d = 0, if (self.USERTDX) {$d = RTDX.BUFMEMSIZE} else {$d = 0}, scan ($a; RTDX) {if ($a.iChannelMode == "output") {$d += 1} else {$d += 3}}, $d) + prop localCanCreate :: ($e = "ok", if (RTDX.USERTDX != 1) {$e = self.error("RTDX manager not enabled")} , $e) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global USERTDX :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Real-Time Data Exchange (RTDX)" + prop JSName :: "ENABLERTDX" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 == 0) {if (HST.LNKTYPE == "RTDX") {self.error("RTDX is being used by HST; select a different host link type before attempting to disable RTDX")} else {if (self.gNumOf > 0) {self.error("Cannot disable RTDX until all RTDX objects are deleted.")} else {GlobalStatus.gDirty = 1, self.USERTDX = $1, if (RTDX.CALLBACKOBJ != nil) {RTDX.CALLBACKOBJ.call()} , "ok"}}} else {if ((GBL.DSPTYPE == 55) && (GBL.MEMORYMODEL == "HUGE")) {self.error("RTDX NOT enabled. Not supported for huge model")} else {GlobalStatus.gDirty = 1, self.USERTDX = $1, if (RTDX.CALLBACKOBJ != nil) {RTDX.CALLBACKOBJ.call()} , "ok"}}) + } + global USERTEXECUTION :: = 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable Real-Time Execution Control" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global RTDXTYPE :: "Simulator" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "JTAG,HSRTDX,Simulator" + prop Label :: "RTDX Mode" + prop JSName :: "MODE" + prop Visible :: 1 + prop Writable :: self.USERTDX + prop NoGen :: 0 + prop Set :: (self.RTDXTYPE = $1, if (RTDX.CALLBACKOBJ != nil) {RTDX.CALLBACKOBJ.call()} , "ok") + } + global DATAMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "RTDX Data Segment (.rtdx_data)" + prop JSName :: "RTDXDATASEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global BUFMEMSIZE :: = (256 + 2) * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Label :: "RTDX Buffer Size (MAUs)" + prop JSName :: "BUFSIZE" + prop Visible :: 1 + prop Writable :: self.USERTDX + prop NoGen :: 0 + prop Set :: (if (HST.RTDX == 0) {self.BUFMEMSIZE = $1, GlobalStatus.gDirty = 1, "ok"} else {if ($1 < (HST.MAXFRAMESET + 3) * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) {self.error("size (in MAUs) must be at least: (largest configured HST channel framesize in words + 3) * (MAUs per word)")} else {self.BUFMEMSIZE = $1, GlobalStatus.gDirty = 1, if (HST.LNKTYPE == "RTDX") {HST.MAXFRAMEALLOWED = (self.BUFMEMSIZE / (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) - 3, "ok"} else {"ok"}}}) + } + global TEXTMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "RTDX Text Segment (.rtdx_text)" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global MASK :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "0x%08x" + prop Style :: 0x02 + prop Label :: "RTDX Interrupt Mask" + prop JSName :: "INTERRUPTMASK" + prop Visible :: 1 + prop Writable :: self.USERTDX + prop NoGen :: 1 + prop Set :: (self.MASK = $1, "ok") + } + global CALLBACKOBJ :: HWI { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iChannelMode :: "output" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Channel Mode" + prop JSName :: "channelMode" + prop Enum :: "input,output" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (GlobalStatus.gDirty = 1, self.iChannelMode = $1, "ok") + } +} + +type HST { + isa ObjectMgr + prop name :: "HST" + prop Label :: "HST - Host Channel Manager" + prop IsContainedIn :: IOF + prop DependsOn :: "HWI" + prop FileStream :: 1 + prop GlobalIcon :: 107 + prop InstanceIcon :: 108 + prop GlobalHelpTopic :: (104) + prop InstanceHelpTopic :: (204) + prop maxObjs :: (GBL.DSPWORDSIZE) + prop dataSize :: ($b = 0, scan ($i; HST) {if ($i.IsConfObj()) {$b += (12 + $i.framesize) * $i.numframes + PIP.OBJSIZE + self.objectSize()} }, $b) + prop InstancePropertyPage :: ("{B7240DEA-AA51-11cf-9BFE-0000C0AC14C8}") + prop GlobalPropertyPage :: ("{B7240DEB-AA51-11cf-9BFE-0000C0AC14C8}") + prop localCreate :: (PIP.gNumEmbed += 1, if (self.gNumOf == 0) {(LNK_dataPump.Create("HST"))} , "ok") + prop localDelete :: (PIP.gNumEmbed -= 1, $b = 0, scan ($i; HST) {if ($i != self) {if ($i.IsConfObj()) {if ($i.framesize > $b) {$b = $i.framesize} } } }, self.MAXFRAMESET = $b, if (self.gNumOf == 1) {(LNK_dataPump.Delete("HST"))} , "ok") + prop GenLinkPrologue :: (if (self.LNKTYPE == "RTDX") {"_LNK_dspFrameReadyMask = LNK_dspFrameReadyMask; \n_LNK_dspFrameRequestMask = LNK_dspFrameRequestMask; \n_LNK_readDone = LNK_readDone; \n_LNK_readFail = LNK_readFail; \n_LNK_readPend = LNK_readPend; \n_LNK_writeFail = LNK_writeFail;"} ) + prop AllocType :: ("2\0, _globalAllocDesc, _memSeg, _placement, _dsmAllocDesc, _dsmMemSeg, _placement") + prop _globalAllocDesc :: ("%8t .%1L: {%12t\n %1U_A_TABBEG = .;\n _%1U_A_TABBEG = .;\n %2S\n %1U_A_TABEND = .;\n _%1U_A_TABEND = .;\n %1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;\n _%1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;%8t\n }\0, name, _linkString, _objSize") + prop objectSize :: (if (GBL.DSPTYPE == 28) {$a = (10 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (8 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (8 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (6 * 4)} , if (GBL.DSPTYPE == 54 || GBL.DSPTYPE == 62) {$a = (5 * 4)} , $a) + prop _dsmAllocDesc :: ("%8t .dsm: {}") + prop _placement :: (0x7fffffff / 2) + prop AllocInst :: ("1\0, _instAllocDesc, _objMemSeg, _placement") + prop _instAllocDesc :: ("/* %0s buffer */\n.hst%2d: %3S\0, name, _objId, _alignString, _objAlign") + prop _alignString :: if self.bufalign > 1 {"align = 0x%4x {}"} else {""} + prop _objId :: self.iId + prop _objAlign :: self.bufalign + prop _objMemSeg :: self.bufseg + prop _linkString :: if (self.gNumOf + self.gNumEmbed) > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop _memSeg :: HST.OBJMEMSEG + prop _dsmMemSeg :: HST.DSMBUFSEG + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"hst.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far HST_Obj %0r;\n\0"} else {"extern HST_Obj %0r;\n\0"}) + prop modifiable :: ((if self.iDelUser == "USER" {1} else {0})) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 3 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 2 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumEmbed :: 0 { + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global LNKTYPE :: "RTDX" { + prop Label :: "Host Link Type" + prop JSName :: "HOSTLINKTYPE" + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "RTDX,NONE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (if ($1 == "RTDX") {if (RTDX.USERTDX == 0) {if ((GBL.DSPTYPE == 55) && (GBL.MEMORYMODEL == "HUGE")) {self.error(" HOSTLINKTYPE cannot be RTDX for huge model")} else {self.error("RTDX module must be enabled before it can be used by HST")}} else {if ((RTDX.BUFMEMSIZE / (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) - 2 < self.MAXFRAMESET) {self.error("RTDX buffer size too small for largest configured HST channel")} else {if (self.LNKTYPE == "NONE") {GlobalStatus.gDirty = 1, self.LNKTYPE = $1, $b = 0, scan ($i; HST) {if ($i.IsConfObj()) {if ($i.framesize > $b) {$b = $i.framesize} } }, self.MAXFRAMESET = $b, self.MAXFRAMEALLOWED = (RTDX.BUFMEMSIZE / (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) - 3, "ok"} else {self.LNKTYPE = $1, self.MAXFRAMEALLOWED = (RTDX.BUFMEMSIZE / (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) - 3, "ok"}}}} else {if ($1 == "Shared Memory") {if ((self.DSMMEMSIZE / 4) < self.MAXFRAMESET) {self.error("Shared memory buffer too small for largest configured HST channel")} else {if (self.LNKTYPE == "NONE") {GlobalStatus.gDirty = 1, self.LNKTYPE = $1, $b = 0, scan ($i; HST) {if ($i.IsConfObj()) {if ($i.framesize > $b) {$b = $i.framesize} } }, self.MAXFRAMESET = $b, self.MAXFRAMEALLOWED = self.DSMMEMSIZE / 4, "ok"} else {self.LNKTYPE = $1, self.MAXFRAMEALLOWED = self.DSMMEMSIZE / 4, "ok"}}} else {GlobalStatus.gDirty = 1, self.LNKTYPE = $1, "ok"}}) + } + global RTDX :: = if self.LNKTYPE == "RTDX" {1} else {0} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use RTDX for host link" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global DSM :: = if self.LNKTYPE == "Shared Memory" {1} else {0} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use Shared Memory for host link" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global EVM54 :: = if self.LNKTYPE == "EVM54" {1} else {0} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use EVM54's I/O ports for host link" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global NONE :: = if self.LNKTYPE == "NONE" {1} else {0} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "No host link" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global MAXFRAMESET :: 64 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAXFRAMESET" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global MAXFRAMEALLOWED :: 255 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "MAXFRAMEALLOWED" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global DSMBUFSEG :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Shared Memory Segment" + prop Visible :: 0 + prop Writable :: self.DSM + prop NoGen :: 0 + } + global DSMMEMSIZE :: = 1024 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 | 0x02 + prop Label :: "Shared Memory Frame Size (MAUs)" + prop Visible :: 0 + prop Writable :: self.DSM + prop NoGen :: 0 + prop Set :: (if ($1 < HST.MAXFRAMESET * 4) {self.error("size (in MAUs) must be at least: 4 * largest configured HST channel framesize (in words)")} else {self.DSMMEMSIZE = $1, GlobalStatus.gDirty = 1, if (self.LNKTYPE == "Shared Memory") {self.MAXFRAMEALLOWED = self.DSMMEMSIZE / 4, "ok"} else {"ok"}}) + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst mode :: "output" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "mode" + prop Enum :: "input,output" + prop Visible :: 1 + prop Writable :: self.modifiable() + prop NoGen :: 0 + } + inst bufseg :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop Label :: "bufseg" + prop JSName :: "bufSeg" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst bufalign :: 4 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 | 0x02 + prop JSName :: "bufAlign" + prop Visible :: 1 + prop Writable :: self.modifiable() + prop NoGen :: 1 + prop Set :: (if ($1 < 4) {self.error("Alignment must be greater than or equal to 4")} else {if (($1 % 2) != 0) {self.error("Alignment must be a power of 2")} else {$i = $1, while ((($i % 2) == 0) && ($i != 2)) {$i = $i / 2}, if (($i % 2) != 0) {self.error("Alignment must be a power of 2")} else {self.bufalign = $1, "ok"}}}) + } + inst buf :: "" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst framesize :: 0x80 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "framesize (words)" + prop JSName :: "frameSize" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 < 1) {self.error("framesize must be >= 1.")} else {if (($1 > self.MAXFRAMEALLOWED) && ((self.RTDX == 1) || (self.DSM == 1))) {if (self.RTDX == 1) {self.error("size (in words) is limited to: (RTDX buffer size in MAUs) / (MAUs per word) - 3")} else {self.error("size (in words) is limited to: shared memory frame size (in MAUs)/4")}} else {self.framesize = $1, $b = 0, scan ($i; HST) {if ($i.IsConfObj()) {if ($i.framesize > $b) {$b = $i.framesize} } }, self.MAXFRAMESET = $b, GlobalStatus.gDirty = 1, "ok"}}) + } + inst numframes :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop JSName :: "numFrames" + prop Visible :: 1 + prop Writable :: self.modifiable() + prop NoGen :: 0 + prop Set :: (if ($1 < 1) {self.error("Channels must contain at least 1 frame.")} else {GlobalStatus.gDirty = 1, self.numframes = $1, "ok"}) + } + inst stsflg :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "statistics" + prop JSName :: "statistics" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst notify :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyFxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "DHL" || self.iDelUser != "USER" {0} else {1}) + prop NoGen :: 0 + prop TabName :: "Notify Function" + } + inst arg0 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg0" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "DHL" || self.iDelUser != "USER" {0} else {1}) + prop NoGen :: 0 + prop TabName :: "Notify Function" + } + inst arg1 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg1" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "DHL" || self.iDelUser != "USER" {0} else {1}) + prop NoGen :: 0 + prop TabName :: "Notify Function" + } + inst lnk :: = if self.RTDX {"RTDX"} else {"NOTRTDX"} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "link type" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iDHLAvailable :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Make this channel available for a new DHL device" + prop JSName :: "availableForDHL" + prop Set :: (if (($1 == 0) && (self.iDHLAvailable == 1)) {DHL.gChannelsAvailable--} else {if (($1 == 1) && (self.iDHLAvailable == 0)) {DHL.gChannelsAvailable++} }, self.iDHLAvailable = $1, "ok") + prop Writable :: self.modifiable() + prop Visible :: 1 + prop NoGen :: 1 + } + inst bufFrameAlign :: = self.bufalign { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } +} + +object LNK_dataPump :: IDL { + param iComment :: "This object cannot be deleted" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "HST" + param iDelMsg :: "This object cannot be deleted" + param function :: @LNK_F_dataPump + param cycles :: 0 + param calibration :: 1 + param Order :: 0 + param iPri :: 0 +} + +object RTA_dispatcher :: IDL { + param iComment :: "This object cannot be deleted" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "HST" + param iDelMsg :: "This object cannot be deleted" + param function :: @RTA_F_dispatch + param cycles :: 0 + param calibration :: 1 + param Order :: 0 + param iPri :: 0 +} + +object RTA_fromHost :: HST { + param iComment :: "Used to access LOG and STS data" + param iIsUsed :: 1 + param iId :: 1 + param iDelUser :: "HST" + param iDelMsg :: "This object cannot be deleted" + param mode :: "input" + param bufseg :: IRAM + param bufalign :: 4 + param buf :: "" + param framesize :: 4 + param numframes :: 1 + param stsflg :: 0 + param notify :: @_FXN_F_nop + param arg0 :: 0 + param arg1 :: 0 + param iDHLAvailable :: 0 +} + +object RTA_toHost :: HST { + param iComment :: "Used to access LOG and STS data" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "HST" + param iDelMsg :: "This object cannot be deleted" + param mode :: "output" + param bufseg :: IRAM + param bufalign :: 4 + param buf :: "" + param framesize :: 64 + param numframes :: 1 + param stsflg :: 0 + param notify :: @_FXN_F_nop + param arg0 :: 0 + param arg1 :: 0 + param iDHLAvailable :: 0 +} + +type HWI { + isa ObjectMgr + prop name :: "HWI" + prop Label :: "HWI - Hardware Interrupt Service Routine Manager" + prop IsContainedIn :: SCH + prop SortChildHierView :: 0 + prop GlobalIcon :: 109 + prop InstanceIcon :: 110 + prop InstanceHelpTopic :: (205) + prop GlobalHelpTopic :: (105) + prop dataSize :: (0 * HWI.gNumOf) + prop localCanCreate :: (self.error("New hardware interrupt objects cannot be created")) + prop InstancePropertyPage :: ("{B7240DE6-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DE7-AA51-11cf-9BFE-0000C0AC14C7}") + prop DependsOn :: "GBL,OBJ,BUF,CLK,IDL,LCK,LOG,MBX,MEM,PIP,POOL,PRD,QUE,RTDX,SEM,STS,SYS" + prop AllocType :: (if self.ZEROTAB {"1\0, _stubsAllocDesc, _memSeg, _placement"} else {if ((MEM.ENABLELOADSEG) && (MEM.VECMEMSEG != MEM.LOADVECMEMSEG)) {"2\0, _stubsAllocDesc, _memSeg, _placement, + _vectAllocDesc, _loadvecSeg, _minplace"} else {"2\0, _stubsAllocDesc, _memSeg, _placement, + _vectAllocDesc, _vecSeg, _minplace"}}) + prop _stubsAllocDesc :: (if ((MEM.ENABLELOADSEG) && (MEM.STUBMEMSEG != MEM.LOADSTUBMEMSEG)) {"%8t .%1L: {} load > %2s, run\0, name, _loadstubSeg"} else {"%8t .%1L: {} \0, name"}) + prop _vectAllocDesc :: (if ((MEM.ENABLELOADSEG) && (MEM.VECMEMSEG != MEM.LOADVECMEMSEG)) {"%8t .%1L_vec: {%12t\n %1U_A_VECS = .;\n *(.hwi_vec)%8t\n } run > %2s align = 0x400, load \0, name, _vecSeg"} else {"%8t .%1L_vec: {%12t\n %1U_A_VECS = .;\n *(.hwi_vec)%8t\n } align = 0x400\0, name"}) + prop _placement :: (0x7fffffff / 2) + prop _minplace :: 0 + prop GenLinkPrologue :: (if self.ZEROTAB {if ((MEM.ENABLELOADSEG) && (MEM.VECMEMSEG != MEM.LOADVECMEMSEG)) {"SECTIONS {%4t\n .%1L_vec: {%8t\n %1U_A_VECS = .;\n *(.hwi_vec)%4t\n } load > %2s, run = 0x0 %0t\n}\n\0 , name, _loadvecSeg"} else {"SECTIONS {%4t\n .%1L_vec: 0x0 {%8t\n %1U_A_VECS = .;\n *(.hwi_vec)%4t\n }%0t\n}\n\0, name"}} else {if self.GENERATE_RESET_VEC {"SECTIONS {%4t\n .%1L_reset: %2x {}%0t\n}\n\0, name, .RESETVECTORADDR"} else {""}}) + prop GenLinkEpilogue :: ("%0t_HWI_CFGDISPATCHED = HWI_CFGDISPATCHED;\n\0") + prop localInit :: (if (RTDX.CALLBACKOBJ != nil) {self.error("HWI initialization failure.")} , RTDX.CALLBACKOBJ = HWI) + prop call :: (if (RTDX.USERTDX == 0) {HWI_RESERVED1.function = @HWI_unused, HWI_RESERVED1.iUseDispatcher = 0, if (HWI_INT9.iSource == JTAGRTDX9 && HWI_INT9.function == @_RTDX_Poll) {HWI_INT9.iSource = MCSP_0_Transmit, HWI_INT9.iReMappable = 1, HWI_INT9.function = @HWI_unused, HWI_INT9.iUseDispatcher = 0, HWI_INT9.iIntrMask = "self", HWI_INT9.IntrMask = 0x200, HWI_INT9.client = "USER"} , if (HWI_INT11.iSource == HSRTDX11 && HWI_INT11.function == @_HSRTDX_xmt) {HWI_INT11.iSource = MCSP_0_Receive, HWI_INT11.iReMappable = 1, HWI_INT11.function = @HWI_unused, HWI_INT11.iUseDispatcher = 0, HWI_INT11.iIntrMask = "self", HWI_INT11.IntrMask = 0x800, HWI_INT11.client = "USER"} , if (HWI_INT12.iSource == HSRTDX12 && HWI_INT12.function == @_HSRTDX_rec) {HWI_INT12.iSource = MCSP_1_Transmit, HWI_INT12.iReMappable = 1, HWI_INT12.function = @HWI_unused, HWI_INT12.iUseDispatcher = 0, HWI_INT12.iIntrMask = "self", HWI_INT12.IntrMask = 0x1000, HWI_INT12.client = "USER"} } else {HWI_RESERVED1.function = @_RTDX_Poll, HWI_RESERVED1.iUseDispatcher = 1, if (RTDX.RTDXTYPE == "HSRTDX") {if (HWI_INT9.iSource == JTAGRTDX9 && HWI_INT9.function == @_RTDX_Poll) {HWI_INT9.iSource = MCSP_0_Transmit, HWI_INT9.iReMappable = 1, HWI_INT9.function = @HWI_unused, HWI_INT9.iUseDispatcher = 0, HWI_INT9.iIntrMask = "self", HWI_INT9.IntrMask = 0x200, HWI_INT9.client = "USER"} , HWI_INT11.iSource = HSRTDX11, HWI_INT11.iReMappable = 0, HWI_INT11.function = @_HSRTDX_xmt, HWI_INT11.iUseDispatcher = 1, HWI_INT11.iIntrMask = "bitmask", HWI_INT11.IntrMask = 0x1808, HWI_INT11.client = "RTDX", HWI_INT12.iSource = HSRTDX12, HWI_INT12.iReMappable = 0, HWI_INT12.function = @_HSRTDX_rec, HWI_INT12.iUseDispatcher = 1, HWI_INT12.iIntrMask = "bitmask", HWI_INT12.IntrMask = 0x1808, HWI_INT12.client = "RTDX"} else {HWI_INT9.iSource = JTAGRTDX9, HWI_INT9.iReMappable = 0, HWI_INT9.function = @_RTDX_Poll, HWI_INT9.iUseDispatcher = 1, HWI_INT9.iIntrMask = "bitmask", HWI_INT9.IntrMask = 0x208, HWI_INT9.client = "RTDX", if (HWI_INT11.iSource == HSRTDX11 && HWI_INT11.function == @_HSRTDX_xmt) {HWI_INT11.iSource = MCSP_0_Receive, HWI_INT11.iReMappable = 1, HWI_INT11.function = @HWI_unused, HWI_INT11.iUseDispatcher = 0, HWI_INT11.iIntrMask = "self", HWI_INT11.IntrMask = 0x800, HWI_INT11.client = "USER"} , if (HWI_INT12.iSource == HSRTDX12 && HWI_INT12.function == @_HSRTDX_rec) {HWI_INT12.iSource = MCSP_1_Transmit, HWI_INT12.iReMappable = 1, HWI_INT12.function = @HWI_unused, HWI_INT12.iUseDispatcher = 0, HWI_INT12.iIntrMask = "self", HWI_INT12.IntrMask = 0x1000, HWI_INT12.client = "USER"} }}) + prop _memSeg :: MEM.STUBMEMSEG + prop _loadstubSeg :: MEM.LOADSTUBMEMSEG + prop _linkString :: ($b = 0, scan ($a; HWI) {if ($a.monitor != "Nothing") {$b = 1} }, if ($b == 1) {"*(.hwi)"} else {"/* no HWI stubs are necessary */"}) + prop name2addr :: ($i = 0, $b = nil, scan ($a; {"Nothing", "Data Value", "Stack Pointer", "Top of SW Stack", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15"}) {if ($b == nil) {if ($a == $1) {$b = {0, 0, 0, @GBL_stackbeg, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}[$i]} , $i++} }, if ($b == nil) {$b = 0} , $b) + prop name2type :: ($i = 0, $b = nil, scan ($a; {"Nothing", "Data Value", "Stack Pointer", "Top of SW Stack", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15"}) {if ($b == nil) {if ($a == $1) {if ($i < 5) {$b = {"unsigned", "signed", "unsigned", "unsigned", "unsigned"}[$i]} } , $i++} }, if ($b == nil) {$b = "unsigned"} , $b) + prop _vecSeg :: MEM.VECMEMSEG + prop _loadvecSeg :: MEM.LOADVECMEMSEG + prop HWIR0_DISP :: (if (HWI_RESERVED0.iUseDispatcher == 1) {0x4} else {0}) + prop HWIR1_DISP :: (if (HWI_RESERVED1.iUseDispatcher == 1) {0x8} else {0}) + prop HWI4_DISP :: (if (HWI_INT4.iUseDispatcher == 1) {0x10} else {0}) + prop HWI5_DISP :: (if (HWI_INT5.iUseDispatcher == 1) {0x20} else {0}) + prop HWI6_DISP :: (if (HWI_INT6.iUseDispatcher == 1) {0x40} else {0}) + prop HWI7_DISP :: (if (HWI_INT7.iUseDispatcher == 1) {0x80} else {0}) + prop HWI8_DISP :: (if (HWI_INT8.iUseDispatcher == 1) {0x100} else {0}) + prop HWI9_DISP :: (if (HWI_INT9.iUseDispatcher == 1) {0x200} else {0}) + prop HWI10_DISP :: (if (HWI_INT10.iUseDispatcher == 1) {0x400} else {0}) + prop HWI11_DISP :: (if (HWI_INT11.iUseDispatcher == 1) {0x800} else {0}) + prop HWI12_DISP :: (if (HWI_INT12.iUseDispatcher == 1) {0x1000} else {0}) + prop HWI13_DISP :: (if (HWI_INT13.iUseDispatcher == 1) {0x2000} else {0}) + prop HWI14_DISP :: (if (HWI_INT14.iUseDispatcher == 1) {0x4000} else {0}) + prop HWI15_DISP :: (if (HWI_INT15.iUseDispatcher == 1) {0x8000} else {0}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 65535 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 16 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global STUBMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.codeMember($1) + prop Label :: "Function Stub Memory" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + global ZEROTAB :: = if 6400 == 6499 {0} else {self.VECMEMSEG.base == self.RESETVECTORADDR} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Writable :: 0 + prop Visible :: 0 + } + global VECMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop Label :: "Interrupt Service Table Memory" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + prop MemberTest :: MEM.codeMember($1) + prop Set :: (self.VECMEMSEG = $1, if ($1.base == 0) {self.GENERATE_RESET_VEC = 0} , "ok") + } + global GENERATE_RESET_VEC :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Generate RESET vector" + prop JSName :: "RESETVECTOR" + prop Writable :: self.ZEROTAB == 0 + prop Visible :: 1 + prop NoGen :: 0 + } + global RESETVECTORADDR :: 0 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Label :: "RESET vector address" + prop JSName :: "RESETVECTORADDR" + prop Format :: "0x%08x" + prop Style :: 0x02 + prop Writable :: self.GENERATE_RESET_VEC + prop Visible :: 1 + prop NoGen :: 1 + } + global EXT4_POLARITY :: "low-to-high" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "low-to-high,high-to-low" + prop Label :: "External Interrupt Pin 4 Polarity" + prop JSName :: "EXTPIN4POLARITY" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXT5_POLARITY :: "low-to-high" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "low-to-high,high-to-low" + prop Label :: "External Interrupt Pin 5 Polarity" + prop JSName :: "EXTPIN5POLARITY" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXT6_POLARITY :: "low-to-high" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "low-to-high,high-to-low" + prop Label :: "External Interrupt Pin 6 Polarity" + prop JSName :: "EXTPIN6POLARITY" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global EXT7_POLARITY :: "low-to-high" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "low-to-high,high-to-low" + prop Label :: "External Interrupt Pin 7 Polarity" + prop JSName :: "EXTPIN7POLARITY" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global POLARITYMASK :: = (if self.EXT4_POLARITY == "high-to-low" {1} else {0}) | (if self.EXT5_POLARITY == "high-to-low" {1} else {0}) << 1 | (if self.EXT6_POLARITY == "high-to-low" {1} else {0}) << 2 | (if self.EXT7_POLARITY == "high-to-low" {1} else {0}) << 3 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global INTRMULTLOW :: = (HWI_INT4.iEventId) | (HWI_INT5.iEventId << 5) | (HWI_INT6.iEventId << 10) | (HWI_INT7.iEventId << 16) | (HWI_INT8.iEventId << 21) | (HWI_INT9.iEventId << 26) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Writable :: 0 + prop Visible :: 0 + prop NoGen :: 0 + } + global INTRMULTHIGH :: = (HWI_INT10.iEventId) | (HWI_INT11.iEventId << 5) | (HWI_INT12.iEventId << 10) | (HWI_INT13.iEventId << 16) | (HWI_INT14.iEventId << 21) | (HWI_INT15.iEventId << 26) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Writable :: 0 + prop Visible :: 0 + prop NoGen :: 0 + } + global CFGDISPATCHED :: = (self.HWIR0_DISP | self.HWIR1_DISP | self.HWI4_DISP | self.HWI5_DISP | self.HWI6_DISP | self.HWI7_DISP | self.HWI8_DISP | self.HWI9_DISP | self.HWI10_DISP | self.HWI11_DISP | self.HWI12_DISP | self.HWI13_DISP | self.HWI14_DISP | self.HWI15_DISP) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "dispatched mask" + prop Style :: 0x02 + prop Writable :: 1 + prop Visible :: 0 + prop NoGen :: 0 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iSource :: Reset { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: ISRC + prop MemberTest :: 1 + prop Label :: "interrupt source" + prop JSName :: "interruptSource" + prop Visible :: if (GBL.CLKTYPE == 700) {0} else {if (GBL.DSPSUBTYPE == 6499) {0} else {1}} + prop Writable :: if (GBL.CLKTYPE == 700) {0} else {self.iReMappable} + prop NoGen :: 1 + prop Set :: ($a = $1, if ($a == Reset) {self.error("The Reset interrupt source cannot be remapped")} else {if ($a == Non_Maskable) {self.error("The Non-Maskable interrupt source cannot be remapped")} else {if ($a == Reserved) {self.error("The Reserved interrupt source cannot be remapped")} else {if (CLK.WHICHHWI == self && $a != self.iSource && CLK.USETIMER) {self.error("This interrupt is in use by CLK, settings may be changed in the CLK Manager")} else {if ($a == CLK.WHICHHWI.iSource && CLK.USETIMER == 1) {self.error("Interrupt source is in use by CLK, settings may be changed in the CLK Manager.")} else {$a.iHwi = self, self.iSource.iHwi = HWI_UNUSED, self.iSource = $1, self.iEventId = self.iSource.iIntrSelectNum, "ok"}}}}}) + } + inst iEventId :: = self.iSource.iIntrSelectNum { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "interrupt selection number" + prop JSName :: "interruptSelectNumber" + prop Style :: 0x02 + prop Visible :: if (GBL.CLKTYPE == 700) {0} else {1} + prop Writable :: if (GBL.CLKTYPE == 700) {0} else {self.iReMappable} + prop NoGen :: 1 + } + inst iReMappable :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iIntrEnableMask :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst function :: @HWI_unused { + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: if ((self.function == @RESERVED) || (self.client != "USER")) {0} else {1} + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop NoGen :: 0 + prop Set :: (self.function = $1, GlobalStatus.gDirty = 1, "ok") + } + inst iSTSObj :: HWI_RESETSTS { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst monitor :: "Nothing" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Nothing,Data Value,Stack Pointer,Top of SW Stack,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15" + prop JSName :: "monitor" + prop Visible :: 1 + prop Writable :: ((self.function != @HWI_unused && self.function != @RESERVED) && (self.iId != 0)) + prop NoGen :: 0 + prop Set :: (if ($1 != self.monitor) {$e = "ok", if ($1 == "Nothing") {if (($e = self.iSTSObj.Delete("HWI")) == "ok") {self.monitor = "Nothing", self.addr = self.name2addr(self.monitor), self.dataType = self.name2type(self.monitor)} } else {if (self.iSTSObj.iIsUsed || ($e = self.iSTSObj.Create("HWI")) == "ok") {self.monitor = $1, if (self.monitor == "Data Value") {self.addr = self.saveAddr, self.dataType = self.saveType} else {self.addr = self.name2addr(self.monitor), self.dataType = self.name2type(self.monitor)}} else {self.monitor = "Nothing"}}, $e} else {"ok"}) + } + inst saveAddr :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst saveType :: "signed" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst addr :: 0 { + prop JSName :: "addr" + prop Visible :: 1 + prop Writable :: (if self.monitor == "Data Value" {1} else {0}) + prop NoGen :: 0 + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Format :: if GBL.DSPTYPE == 62 {"0x%08x"} else {"0x%04x"} + prop Set :: (self.addr = $1, self.saveAddr = $1, "ok") + } + inst dataType :: "signed" { + prop Visible :: 1 + prop Writable :: (if self.monitor == "Nothing" {0} else {1}) + prop NoGen :: 0 + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "signed,unsigned" + prop Label :: "type" + prop JSName :: "dataType" + prop Set :: (if (self.monitor != "Nothing") {self.dataType = $1, self.saveType = $1, "ok"} else {self.error("The monitor field must set to modify this field")}) + } + inst operation :: "STS_add(*addr)" { + prop Visible :: 1 + prop Writable :: (if self.monitor == "Nothing" {0} else {1}) + prop NoGen :: 0 + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "operation" + prop Enum :: "STS_add(*addr),STS_delta(*addr),STS_add(-*addr),STS_delta(-*addr),STS_add(|*addr|),STS_delta(|*addr|)" + prop Set :: (if (self.monitor != "Nothing") {self.operation = $1, "ok"} else {self.error("The monitor field must set to modify this field")}) + } + inst client :: "USER" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iUseDispatcher :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use Dispatcher" + prop JSName :: "useDispatcher" + prop Visible :: 1 + prop Writable :: if (self.client == "USER") {1} else {0} + prop NoGen :: 0 + prop TabName :: "Dispatcher" + prop Set :: (if (($1 == 1) && (self == HWI_NMI)) {self.error("HWI dispatcher can't be used for NMI")} else {self.iUseDispatcher = $1, "ok"}) + } + inst iArg :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Arg" + prop JSName :: "arg" + prop Visible :: 1 + prop Writable :: if ((self.iUseDispatcher == 1) && (self.client == "USER")) {1} else {0} + prop NoGen :: 0 + prop TabName :: "Dispatcher" + prop Set :: (self.iArg = $1, "ok") + } + inst iIntrMask :: "self" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Interrupt Mask" + prop JSName :: "interruptMask" + prop Enum :: "all,none,self,bitmask" + prop Visible :: 1 + prop Writable :: if (self.iUseDispatcher == 1) {1} else {0} + prop NoGen :: 1 + prop TabName :: "Dispatcher" + prop Set :: (if ($1 == "all") {self.IntrMask = 0xffff} else {if ($1 == "self") {self.IntrMask = 1 << self.iId} else {if ($1 == "none") {self.IntrMask = 0} }}, self.iIntrMask = $1, "ok") + } + inst IntrMask :: (1 << self.iId) { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "0x%04x" + prop Style :: 0x02 + prop Label :: "Interrupt Bit Mask" + prop JSName :: "interruptBitMask" + prop Visible :: 1 + prop Writable :: if ((self.iUseDispatcher == 1) && (self.iIntrMask == "bitmask")) {1} else {0} + prop NoGen :: 0 + prop TabName :: "Dispatcher" + prop Set :: (if ($1 > 0xffff) {self.error("Invalid Number")} else {self.IntrMask = $1, "ok"}) + } + inst iCacheControl :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Don't modify cache control" + prop JSName :: "cacheControl" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 1 + prop TabName :: "Dispatcher" + prop Set :: (if ($1 == 1) {self.iCCBitMask = 0x1} else {self.iCCBitMask = (self.iPCCBitMask | self.iDCCBitMask)}, self.iCacheControl = $1, "ok") + } + inst iPCCMask :: (if (GBL.DSPSUBTYPE == 6200 || GBL.DSPSUBTYPE == 6700) {"mapped"} else {"cache enable"}) { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "mapped,cache enable,cache freeze,cache bypass" + prop Label :: "Program Cache Control Mask" + prop JSName :: "progCacheMask" + prop Visible :: 1 + prop Writable :: if ((self.iUseDispatcher == 1) && (self.iCacheControl == 0)) {1} else {0} + prop NoGen :: 1 + prop TabName :: "Dispatcher" + prop Set :: (if ((GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6400) && $1 != "cache enable") {self.error("unsupported cache mode for 6x1x/64x device (cache enable must be selected)")} else {if ($1 == "mapped") {self.iPCCBitMask = 0x0000} else {if ($1 == "cache enable") {self.iPCCBitMask = 0x0040} else {if ($1 == "cache freeze") {self.iPCCBitMask = 0x0060} else {self.iPCCBitMask = 0x0080}}}, self.iPCCMask = $1, self.iCCBitMask = self.iPCCBitMask | self.iDCCBitMask, "ok"}) + } + inst iPCCBitMask :: 0x0000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDCCMask :: (if (GBL.DSPSUBTYPE == 6200 || GBL.DSPSUBTYPE == 6700) {"mapped"} else {"cache enable"}) { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "mapped,cache enable,cache freeze,cache bypass" + prop Label :: "Data Cache Control Mask" + prop JSName :: "dataCacheMask" + prop Visible :: 1 + prop Writable :: if ((self.iUseDispatcher == 1) && (self.iCacheControl == 0)) {1} else {0} + prop NoGen :: 1 + prop TabName :: "Dispatcher" + prop Set :: (if ((GBL.DSPSUBTYPE == 6211 || GBL.DSPSUBTYPE == 6711 || GBL.DSPSUBTYPE == 6400) && $1 != "cache enable") {self.error("unsupported cache mode for 6x1x/64x device (cache enable must be selected)")} else {if ($1 == "mapped") {self.iDCCBitMask = 0x0000} else {if ($1 == "cache enable") {self.iDCCBitMask = 0x0008} else {if ($1 == "cache freeze") {self.iDCCBitMask = 0x000C} else {self.iDCCBitMask = 0x0010}}}, self.iDCCMask = $1, self.iCCBitMask = self.iPCCBitMask | self.iDCCBitMask, "ok"}) + } + inst iDCCBitMask :: 0x0000 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iCCBitMask :: 1 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iLoadTrack :: 0 { + prop Label :: "Support CPU load tracking" + prop JSName :: "loadTrack" + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } +} + +object HWI_RESET_STS :: STS { + param iComment :: "provides statistics for the RESET ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_RESET :: HWI { + param iComment :: "defines function for the RESET ISR" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Reset + param iReMappable :: 0 + param iIntrEnableMask :: 1 + param function :: @_c_int00 + param iSTSObj :: HWI_RESET_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 1 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_NMI_STS :: STS { + param iComment :: "provides statistics for the NMI ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_NMI :: HWI { + param iComment :: "defines function for the NMI ISR" + param iIsUsed :: 1 + param iId :: 1 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Non_Maskable + param iReMappable :: 0 + param iIntrEnableMask :: 2 + param function :: @HWI_unused + param iSTSObj :: HWI_NMI_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 2 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_RESERVED0_STS :: STS { + param iComment :: "This STS object is being used by a HWI object and cannot be deleted" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_RESERVED0 :: HWI { + param iComment :: "RESERVED for RTDX" + param iIsUsed :: 1 + param iId :: 2 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Reserved + param iReMappable :: 0 + param iIntrEnableMask :: 4 + param function :: @RESERVED + param iSTSObj :: HWI_RESERVED0_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "RTDX" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 4 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_RESERVED1_STS :: STS { + param iComment :: "This STS object is being used by a HWI object and cannot be deleted" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_RESERVED1 :: HWI { + param iComment :: "RESERVED for RTDX" + param iIsUsed :: 1 + param iId :: 3 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Reserved + param iReMappable :: 0 + param iIntrEnableMask :: 8 + param function :: @_RTDX_Poll + param iSTSObj :: HWI_RESERVED1_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "RTDX" + param iUseDispatcher :: 1 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 8 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT4_STS :: STS { + param iComment :: "provides statistics for the INT4 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT4 :: HWI { + param iComment :: "defines the INT4 Interrupt" + param iIsUsed :: 1 + param iId :: 4 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: External_Pin_4 + param iReMappable :: 1 + param iIntrEnableMask :: 16 + param function :: @HWI_unused + param iSTSObj :: HWI_INT4_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 16 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT5_STS :: STS { + param iComment :: "provides statistics for the INT5 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT5 :: HWI { + param iComment :: "defines the INT5 Interrupt" + param iIsUsed :: 1 + param iId :: 5 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: External_Pin_5 + param iReMappable :: 1 + param iIntrEnableMask :: 32 + param function :: @HWI_unused + param iSTSObj :: HWI_INT5_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 32 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT6_STS :: STS { + param iComment :: "provides statistics for the INT6 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT6 :: HWI { + param iComment :: "defines the INT6 Interrupt" + param iIsUsed :: 1 + param iId :: 6 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: External_Pin_6 + param iReMappable :: 1 + param iIntrEnableMask :: 64 + param function :: @HWI_unused + param iSTSObj :: HWI_INT6_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 64 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT7_STS :: STS { + param iComment :: "provides statistics for the INT7 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT7 :: HWI { + param iComment :: "defines the INT7 Interrupt" + param iIsUsed :: 1 + param iId :: 7 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: External_Pin_7 + param iReMappable :: 1 + param iIntrEnableMask :: 128 + param function :: @HWI_unused + param iSTSObj :: HWI_INT7_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 128 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT8_STS :: STS { + param iComment :: "provides statistics for the INT8 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT8 :: HWI { + param iComment :: "defines the INT8 Interrupt" + param iIsUsed :: 1 + param iId :: 8 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: EDMA_Controller + param iReMappable :: 1 + param iIntrEnableMask :: 256 + param function :: @HWI_unused + param iSTSObj :: HWI_INT8_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 256 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT9_STS :: STS { + param iComment :: "provides statistics for the INT9 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT9 :: HWI { + param iComment :: "defines the INT9 Interrupt" + param iIsUsed :: 1 + param iId :: 9 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: JTAGRTDX9 + param iReMappable :: 0 + param iIntrEnableMask :: 520 + param function :: @_RTDX_Poll + param iSTSObj :: HWI_INT9_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "RTDX" + param iUseDispatcher :: 1 + param iArg :: 0 + param iIntrMask :: "bitmask" + param IntrMask :: 520 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT10_STS :: STS { + param iComment :: "provides statistics for the INT10 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT10 :: HWI { + param iComment :: "defines the INT10 Interrupt" + param iIsUsed :: 1 + param iId :: 10 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Timer_2 + param iReMappable :: 1 + param iIntrEnableMask :: 1024 + param function :: @HWI_unused + param iSTSObj :: HWI_INT10_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 1024 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT11_STS :: STS { + param iComment :: "provides statistics for the INT11 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT11 :: HWI { + param iComment :: "defines the INT11 Interrupt" + param iIsUsed :: 1 + param iId :: 11 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: MCSP_0_Receive + param iReMappable :: 1 + param iIntrEnableMask :: 2048 + param function :: @HWI_unused + param iSTSObj :: HWI_INT11_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 2048 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT12_STS :: STS { + param iComment :: "provides statistics for the INT12 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT12 :: HWI { + param iComment :: "defines the INT12 Interrupt" + param iIsUsed :: 1 + param iId :: 12 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: MCSP_1_Transmit + param iReMappable :: 1 + param iIntrEnableMask :: 4096 + param function :: @HWI_unused + param iSTSObj :: HWI_INT12_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 4096 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT13_STS :: STS { + param iComment :: "provides statistics for the INT13 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT13 :: HWI { + param iComment :: "defines the INT13 Interrupt" + param iIsUsed :: 1 + param iId :: 13 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Host_Port_Host_to_DSP + param iReMappable :: 1 + param iIntrEnableMask :: 8192 + param function :: @HWI_unused + param iSTSObj :: HWI_INT13_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 8192 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT14_STS :: STS { + param iComment :: "provides statistics for the INT14 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT14 :: HWI { + param iComment :: "defines the INT14 Interrupt" + param iIsUsed :: 1 + param iId :: 14 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Timer_0 + param iEventId :: 1 + param iReMappable :: 1 + param iIntrEnableMask :: 16384 + param function :: @CLK_F_isr + param iSTSObj :: HWI_INT14_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "CLK" + param iUseDispatcher :: 1 + param iArg :: @CLK_A_TABBEG + param iIntrMask :: "self" + param IntrMask :: 16384 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_INT15_STS :: STS { + param iComment :: "provides statistics for the INT15 ISR" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HWI" + param iDelMsg :: "This STS object is being used by a HWI object and cannot be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +object HWI_INT15 :: HWI { + param iComment :: "defines the INT15 Interrupt" + param iIsUsed :: 1 + param iId :: 15 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Timer_1 + param iEventId :: 2 + param iReMappable :: 1 + param iIntrEnableMask :: 32768 + param function :: @HWI_unused + param iSTSObj :: HWI_INT15_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 32768 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +object HWI_UNUSED :: HWI { + param iComment :: "a dummy DSP interrupt for unused sources" + param iIsUsed :: 0 + param iId :: 16 + param iDelUser :: "HWI" + param iDelMsg :: "Hardware interrupt objects cannot be deleted" + param iSource :: Reset + param iReMappable :: 1 + param iIntrEnableMask :: 0 + param function :: @HWI_unused + param iSTSObj :: HWI_INT15_STS + param monitor :: "Nothing" + param saveAddr :: 0 + param saveType :: "signed" + param addr :: 0 + param dataType :: "signed" + param operation :: "STS_add(*addr)" + param client :: "USER" + param iUseDispatcher :: 0 + param iArg :: 0 + param iIntrMask :: "self" + param IntrMask :: 65536 + param iCacheControl :: 1 + param iPCCMask :: "cache enable" + param iPCCBitMask :: 0 + param iDCCMask :: "cache enable" + param iDCCBitMask :: 0 + param iCCBitMask :: 1 + param iLoadTrack :: 0 +} + +type SWI { + isa ObjectMgr + prop name :: "SWI" + prop Label :: "SWI - Software Interrupt Manager" + prop IsContainedIn :: SCH + prop DependsOn :: "HWI,SIO,HST,MSGQ" + prop GlobalIcon :: 123 + prop InstanceIcon :: 124 + prop InstanceHelpTopic :: (211) + prop GlobalHelpTopic :: (111) + prop HighTimeBased :: (if CLK.HIRES == 1 {1} else {0}) + prop LowTimeBased :: (if CLK.HIRES == 1 {0} else {1}) + prop uType :: (if (self.HighTimeBased()) {$a = 0} else {if (self.LowTimeBased()) {$a = 1} else {$a = 2}}, $a) + prop STSGetMaxFmt :: (if (SWI.STSUNITS == "raw") {if CLK.HIRES {"%g inst"} else {"%g ints"}} else {if SWI.STSUNITS == "microseconds" {"%.1f us"} else {"%.2f ms"}}) + prop STSGetSumFmt :: (SWI.STSGetMaxFmt()) + prop STSGetAvgFmt :: (if (SWI.STSUNITS == "raw") {if CLK.HIRES {"%.2f inst"} else {"%.2f ints"}} else {if SWI.STSUNITS == "microseconds" {"%.1f us"} else {"%.2f ms"}}) + prop STSFilterMaxMult :: ($a = 1) + prop STSFilterSumMult :: (SWI.STSFilterMaxMult($1)) + prop GetPriority :: (self.pri) + prop objectSize :: (if ((GBL.DSPTYPE == 54 && GBL.FARMODE == 0) || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL")) {$a = (12 * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (14 * 4)} , if (GBL.DSPTYPE == 28 || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE")) {$a = (20 * 4)} , if (GBL.DSPTYPE == 62) {$a = (11 * 4)} , $a) + prop GenLinkPrologue :: ("SECTIONS {%4t\n.%1L: {%8t\n %1U_A_TABBEG = .;\n %4S\n %1U_A_TABEND = .;\n %1U_A_TABLEN = (. - %1U_A_TABBEG) / %2d;%4t\n} > %3s%5s\0, name, objSize, memSeg, linkString, pageString") + prop GenLinkEpilogue :: ("%0t}\n\0") + prop linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop pageString :: if GBL.DSPTYPE == 62 {""} else {if GBL.DSPTYPE == 55 {(if SWI.OBJMEMSEG.space() == "code" {" PAGE 0"} else {if SWI.OBJMEMSEG.space() == "data" {" PAGE 1"} else {if SWI.OBJMEMSEG.space() == "io" {" PAGE 2"} else {" PAGE 0"}}})} else {" PAGE 1"}} + prop memSeg :: SWI.OBJMEMSEG + prop objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop maxObjs :: (32767) + prop dataSize :: (self.objectSize() * SWI.gNumOf) + prop localCanCreate :: (if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {self.error("System stack size (see MEM) is too small to support a new SWI priority level.")} else {"ok"}) + prop localCreate :: (STS.gNumEmbed += 1, SWI.EXECFXN = @SWI_F_exec, SWI.RUNFXN = @SWI_F_run, "ok") + prop localDelete :: (STS.gNumEmbed -= 1, if (self.gNumOf == 1) {SWI.EXECFXN = @FXN_F_nop, SWI.RUNFXN = @FXN_F_nop} , "ok") + prop SortByField :: "pri" + prop SortGroups :: 15 + prop InstancePropertyPage :: ("{B7240DEC-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DED-AA51-11cf-9BFE-0000C0AC14C7}") + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"swi.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far SWI_Obj %0r;\n\0"} else {"extern SWI_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global EHOOKFXN :: @GBL_NULL { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Enable Scheduler and Return to Idle Function" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global IHOOKFXN :: @GBL_NULL { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Exit Scheduler and Return to Idle Function" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global EXECFXN :: @SWI_F_exec { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Configured SWI executive" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global RUNFXN :: @SWI_F_run { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Configured SWI executive body" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global STSUNITS :: "raw" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "raw,milliseconds,microseconds" + prop Label :: "Statistics Units" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst priority :: = (self.pri + 1) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "priority" + prop JSName :: "" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst function :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst pri :: 1 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14" + prop Label :: "priority" + prop JSName :: "priority" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: ($a = self.pri, self.pri = $1, if (self == KNL_swi) {if ($1 != 0) {self.pri = $a, self.error("KNL_swi must remain at Priority 0.")} else {"ok"}} else {if ($1 == 0 && KNL_swi.iIsUsed == 1) {self.pri = $a, self.error("Priority 0 reserved for KNL_swi only.")} else {GlobalStatus.gDirty = 1, if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {self.pri = $a, self.error("System stack size (see MEM) is too small to support a new SWI priority level.")} else {if ($1 > 14) {self.pri = $a, self.error("SWI can only support 15 priority levels.")} else {"ok"}}}}) + } + inst mailbox :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 | 0x02 + prop JSName :: "mailbox" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst arg0 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg0" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst arg1 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "arg1" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst dorta :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst Order :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 0 + prop Writable :: 1 + } + inst filter :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filter" + prop NoGen :: 0 + } + inst maxformat :: self.STSGetMaxFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "maxformat" + prop NoGen :: 0 + } + inst sumformat :: self.STSGetSumFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "sumformat" + prop NoGen :: 0 + } + inst avgformat :: self.STSGetAvgFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "avgformat" + prop NoGen :: 0 + } + inst filtmaxmult :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filtmaxmult" + prop NoGen :: 0 + } + inst filtsummult :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filtsummult" + prop NoGen :: 0 + } + inst unittype :: self.uType() { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "unittype" + prop NoGen :: 0 + } +} + +type TSK { + isa ObjectMgr + prop name :: "TSK" + prop Label :: "TSK - Task Manager" + prop IsConfMod :: self.USETSK + prop IsContainedIn :: SCH + prop DependsOn :: "SWI,HOOK" + prop GlobalIcon :: 143 + prop InstanceIcon :: 144 + prop GlobalHelpTopic :: (314) + prop InstanceHelpTopic :: (414) + prop InstancePropertyPage :: ("{473C4A64-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{473C4A65-B1A8-11d0-9885-0020AFEE33C6}") + prop SortByField :: "iPRI" + prop SortGroups :: 17 + prop objectSize :: (if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (27 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (44 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (44 * 4)} , if (GBL.DSPTYPE == 28) {$a = (40 * 4)} , if (GBL.DSPTYPE == 62 || (GBL.DSPTYPE == 54 && GBL.FARMODE == 0)) {$a = (24 * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (25 * 4)} , $a) + prop GenLinkPrologue :: (if (self.USETSK != 0) {"SECTIONS {%4t\n.%1L: {%8t\n %1U_A_TABBEG = .;\n %4S\n %1U_A_TABEND = .;\n %1U_A_TABLEN = (. - %1U_A_TABBEG) / %2d;%4t\n} > %3s%5s\0, name, objSize, _bssmemSeg, linkString, pageString"} else {"_KNL_swi = 0;"}) + prop linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop pageString :: if GBL.DSPTYPE == 62 {""} else {if GBL.DSPTYPE == 55 {(if TSK.OBJMEMSEG.space() == "code" {" PAGE 0"} else {if TSK.OBJMEMSEG.space() == "data" {" PAGE 1"} else {if TSK.OBJMEMSEG.space() == "io" {" PAGE 2"} else {" PAGE 0"}}})} else {" PAGE 1"}} + prop GenLinkEpilogue :: (if (self.USETSK != 0) {"%0t}\n\0"} else {""}) + prop _objAllocDesc :: ("%8t .TSK$obj: {}") + prop _bssmemSeg :: self.OBJMEMSEG + prop _objmemSeg :: MEM.CFGOBJSEG + prop AllocInst :: (if self.iAUTOSTK {"1\0, _instStackDesc, _instStackSeg, _placement"} else {"0\0"}) + prop _instStackDesc :: (if (GBL.DSPTYPE == 40) {"%8t .%0s$stk: {%12t\n %0s$stack = .;\n . += %1d;%8t\n }\0, _instStackSize"} else {"%8t .%0s$stk: {%12t\n *(.%0s$stk)%8t\n }\0"}) + prop _self :: self + prop _instStackSize :: self.iSTKSZ * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE) + prop _instStackSeg :: self.iSTKSEG + prop _placement :: (0x7fffffff / 2) + prop localInit :: (KNL_swi.Create("SWI"), if (self.STACKSEG.iAllocHeap == 1) {self.STACKSEG.iReqHeapCount++, "ok"} else {self.error("TSK default stack segment must be a memory segment with a heap")}) + prop HighTimeBased :: (if CLK.HIRES == 1 {1} else {0}) + prop LowTimeBased :: (if CLK.HIRES == 1 {0} else {1}) + prop uType :: (if (self.HighTimeBased()) {$a = 0} else {if (self.LowTimeBased()) {$a = 1} else {$a = 2}}, $a) + prop STSGetMaxFmt :: (if (TSK.STSUNITS == "raw") {if CLK.HIRES {"%g inst"} else {"%g ints"}} else {if TSK.STSUNITS == "microseconds" {"%.1f us"} else {"%.2f ms"}}) + prop STSGetSumFmt :: (TSK.STSGetMaxFmt()) + prop STSGetAvgFmt :: (if (TSK.STSUNITS == "raw") {if CLK.HIRES {"%.2f inst"} else {"%.2f ints"}} else {if TSK.STSUNITS == "microseconds" {"%.1f us"} else {"%.2f ms"}}) + prop STSFilterMaxMult :: ($a = 1) + prop STSFilterSumMult :: (TSK.STSFilterMaxMult($1)) + prop localCreate :: (STS.gNumEmbed += 1, "ok") + prop localCanCreate :: ($e = "ok", if (TSK.USETSK != 1) {$e = self.error("TSK manager not enabled")} , $e) + prop localDelete :: (STS.gNumEmbed -= 1, "ok") + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"tsk.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far TSK_Obj %0r;\n\0"} else {"extern TSK_Obj %0r;\n\0"}) + prop NOPFXN :: @FXN_F_nop + prop _objId :: self.iId + prop objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop dataSize :: ($d = 0, scan ($i; TSK) {$d += ($i.iSTKSZ + self.objectSize() * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE))}, $d) + prop minStackSize :: ($a = self.STACKSIZE, scan ($i; TSK) {if ($i.STACKSIZE < $a) {$a = $i.STACKSIZE} }, $a) + prop maxObjs :: (32767) + prop GetPriority :: (self.iPRI) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global USETSK :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable TSK Manager" + prop JSName :: "ENABLETSK" + prop Visible :: 1 + prop Writable :: if GBL.DSPSUBTYPE == 0x55DA200 {0} else {1} + prop NoGen :: 1 + prop Set :: (if ($1 == 0) {if (self.gNumOf > 1) {self.error("Cannot disable TSK until all TSK objects are deleted.")} else {self.STACKSEG.iReqHeapCount--, TSK.STACKSEG = MEM_NULL, TSK.OBJMEMSEG = MEM_NULL, TSK_idle.iSTKSEG = MEM_NULL, TSK_idle.Delete("TSK"), KNL_swi.Delete("TSK"), PRD.THOOKFXN = self.NOPFXN, if (PRD.gNumOf == 0) {if (PRD_clock.iIsUsed == 1) {PRD_clock.function = @FXN_F_nop} } , self.USETSK = $1, "ok"}} else {$e = "ok", GlobalStatus.gDirty = 1, if (GlobalStatus.MinStackSize >= MEM.STACKSIZE) {$e = self.error("Current stack size inadequate to enable TSK"), break} , scan ($a; SWI) {if ($a != KNL_swi && $a.pri == 0 && $a.iIsUsed == 1) {$e = self.error("Cannot enable TSK when there are SWI objects at Priority 0."), break} }, if ($e == "ok") {TSK.STACKSEG = MEM_NULL, scan ($b; MEM) {if ($b.iAllocHeap && $b != MEM_NULL) {TSK.STACKSEG = $b, break} }, self.STACKSEG.iReqHeapCount++, self.USETSK = $1, TSK.OBJMEMSEG = SWI.OBJMEMSEG, TSK_idle.iSTKSEG = self.OBJMEMSEG, TSK_idle.Create("TSK"), KNL_swi.Create("TSK"), PRD.THOOKFXN = PRD.DEFAULT_THOOKFXN, if (TSK.TSKTICK == "PRD") {if (PRD_clock.iIsUsed == 1) {PRD_clock.function = @PRD_F_tick} } , if (MEM.NOHEAPS) {self.STACKSEG.iReqHeapCount++} , $e} else {$e}}) + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "OBJMEMSEG" + prop MemberType :: MEM + prop MemberTest :: MEM.dataNullMember($1) + prop Label :: "Object Memory" + prop Visible :: 1 + prop Writable :: self.USETSK + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global STACKSIZE :: 1024 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: if GBL.DSPTYPE == 54 {0x01} else {0x02} + prop Label :: "Default stack size (MAUs)" + prop JSName :: "STACKSIZE" + prop Visible :: 1 + prop Writable :: self.USETSK + } + global STACKSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataNullMember($1) && $1.iAllocHeap + prop Label :: "Stack segment for dynamic tasks" + prop JSName :: "STACKSEG" + prop Visible :: 1 + prop Writable :: self.USETSK && (MEM.NOHEAPS == 0) + prop Set :: (if (self.STACKSEG.iReqHeapCount > 0) {self.STACKSEG.iReqHeapCount--} , self.STACKSEG = $1, self.STACKSEG.iReqHeapCount++, "ok") + } + global PRIORITY :: 1 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "PRIORITY" + prop Enum :: "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15" + prop Label :: "Default task priority" + prop Visible :: 1 + prop Writable :: self.USETSK + } + global CREATEFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Create function" + prop JSName :: "CREATEFXN" + prop Visible :: 1 + prop Writable :: self.USETSK + prop TabName :: "Function Hooks" + prop Set :: (self.CREATEFXN = $1, HOOK_KNL.createFxn = self.CREATEFXN, "ok") + prop NoGen :: 1 + } + global VCREATEFXN :: = if HOOK_KNL.iIsUsed == 1 {@__HOOK_doCreate} else {self.CREATEFXN} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + } + global DELETEFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Delete function" + prop JSName :: "DELETEFXN" + prop Visible :: 1 + prop Writable :: self.USETSK + prop TabName :: "Function Hooks" + prop Set :: (self.DELETEFXN = $1, HOOK_KNL.deleteFxn = self.DELETEFXN, "ok") + prop NoGen :: 1 + } + global VDELETEFXN :: = if HOOK_KNL.iIsUsed == 1 {@__HOOK_doDelete} else {self.DELETEFXN} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + } + global EXITFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Exit function" + prop JSName :: "EXITFXN" + prop Visible :: 1 + prop Writable :: self.USETSK + prop TabName :: "Function Hooks" + prop Set :: (self.EXITFXN = $1, HOOK_KNL.exitFxn = self.EXITFXN, "ok") + prop NoGen :: 1 + } + global VEXITFXN :: = if HOOK_KNL.iIsUsed == 1 {@__HOOK_doExit} else {self.EXITFXN} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + } + global DOSWITCH :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call switch function" + prop JSName :: "CALLSWITCHFXN" + prop Writable :: self.USETSK + prop Visible :: 1 + prop NoGen :: 1 + prop Set :: (self.DOSWITCH = $1, HOOK_KNL.callSwitchFxn = self.DOSWITCH, "ok") + prop TabName :: "Function Hooks" + } + global VSWFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Switch function" + prop JSName :: "SWITCHFXN" + prop Visible :: 1 + prop NoGen :: 1 + prop Writable :: self.DOSWITCH && self.USETSK + prop Set :: (self.VSWFXN = $1, HOOK_KNL.switchFxn = self.VSWFXN, "ok") + prop TabName :: "Function Hooks" + } + global SWITCHFXN :: = (if (HOOK_KNL.iIsUsed) {$i = 0, scan ($a; HOOK) {if ($a.callSwitchFxn) {$i = 1} }, if ($i) {@__HOOK_doSwitch} else {0}} else {if (self.DOSWITCH) {self.VSWFXN} else {0}}) { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "" + prop TabName :: "Function Hooks" + } + global DOREADY :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call ready function" + prop JSName :: "CALLREADYFXN" + prop Writable :: self.USETSK + prop Visible :: 1 + prop NoGen :: 1 + prop Set :: (self.DOREADY = $1, HOOK_KNL.callReadyFxn = self.DOREADY, "ok") + prop TabName :: "Function Hooks" + } + global VRDYFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Ready function" + prop JSName :: "READYFXN" + prop Visible :: 1 + prop Writable :: self.DOREADY && self.USETSK + prop NoGen :: 1 + prop Set :: (self.VRDYFXN = $1, HOOK_KNL.readyFxn = self.VRDYFXN, "ok") + prop TabName :: "Function Hooks" + } + global READYFXN :: = (if (HOOK_KNL.iIsUsed) {$i = 0, scan ($a; HOOK) {if ($a.callReadyFxn) {$i = 1} }, if ($i) {@__HOOK_doReady} else {0}} else {if (self.DOREADY) {self.VRDYFXN} else {0}}) { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "" + prop TabName :: "Function Hooks" + } + global NUM_HOOKS :: = HOOK.gNumOf { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + } + global STSUNITS :: "raw" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "raw,milliseconds,microseconds" + prop Label :: "Statistics Units" + prop Visible :: 0 + prop Writable :: self.USETSK + prop NoGen :: 1 + } + global TSKTICK :: "PRD" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "PRD,User" + prop Label :: "TSK tick driven by" + prop JSName :: "DRIVETSKTICK" + prop Visible :: 1 + prop Writable :: self.USETSK + prop NoGen :: 1 + prop Set :: (if ($1 != self.TSKTICK) {if ($1 == "PRD") {PRD.THOOKFXN = PRD.DEFAULT_THOOKFXN, if (TSK.USETSK == 1) {if (PRD_clock.iIsUsed == 1) {PRD_clock.function = @PRD_F_tick} } } , if ($1 == "User") {PRD.THOOKFXN = self.NOPFXN, if (PRD.gNumOf == 0) {if (PRD_clock.iIsUsed == 1) {PRD_clock.function = @FXN_F_nop} } } , if ($1 != "PRD" && $1 != "User") {self.error("Invalid TSK tick driver selection")} } , self.TSKTICK = $1, "ok") + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iFXN :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Task function" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG0 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 0" + prop JSName :: "arg0" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG1 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 1" + prop JSName :: "arg1" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG2 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 2" + prop JSName :: "arg2" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG3 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 3" + prop JSName :: "arg3" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG4 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 4" + prop JSName :: "arg4" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG5 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 5" + prop JSName :: "arg5" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG6 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 6" + prop JSName :: "arg6" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iARG7 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "Task function argument 7" + prop JSName :: "arg7" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + prop TabName :: "Function" + } + inst iAUTOSTK :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Automatically allocate stack" + prop JSName :: "autoAllocateStack" + prop Set :: (if (($1 == 1) && (self.iAUTOSTK == 0)) {self.iSTKSZ = TSK.STACKSIZE} , self.iAUTOSTK = $1, "ok") + prop Visible :: 1 + prop Writable :: if self.iDelUser == "TSK" {0} else {1} + } + inst iMANSTK :: @null { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Manually allocated stack" + prop JSName :: "manualStack" + prop Visible :: 1 + prop Writable :: self.iAUTOSTK == 0 + } + inst iSTKSZ :: TSK.STACKSIZE { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: if GBL.DSPTYPE == 54 {0x01} else {0x02} + prop Label :: "Stack size (MAUs)" + prop JSName :: "stackSize" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: ($a = $1, if ($a < 32) {if (GBL.DSPSUBTYPE == 62) {self.error("Task stack size is too small.")} else {if ($a < 32) {self.error("Task stack size is too small.")} else {self.iSTKSZ = ($1 - ($1 - 1) % 8 + 7), GlobalStatus.gDirty = 1, "ok"}}} else {self.iSTKSZ = ($1 - ($1 - 1) % 8 + 7), GlobalStatus.gDirty = 1, "ok"}) + } + inst iSTKSEG :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: $1 == MEM_NULL || MEM.dataMember($1) + prop Label :: "Stack Memory Segment" + prop JSName :: "stackMemSeg" + prop Visible :: 1 + prop Writable :: 1 + } + inst iPRI :: TSK.PRIORITY { + prop Label :: "Priority" + prop JSName :: "priority" + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: (if (self == TSK_idle) {if ($1 == 0) {"ok"} else {self.error("Cannot change the priority of the idle task.")}} else {if ($1 == 0) {self.error("Priority 0 is reserved for the system idle task")} else {self.iPRI = $1, "ok"}}) + } + inst iENV :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Environment pointer" + prop JSName :: "envPointer" + prop Visible :: 1 + prop Writable :: self.iDelUser != "TSK" + prop TabName :: "Advanced" + } + inst iEXITFLAG :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Don't shut down system while this task is still running" + prop JSName :: "exitFlag" + prop Visible :: 1 + prop Writable :: 1 + prop TabName :: "Advanced" + } + inst iUSETSKNAME :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Allocate Task Name on Target" + prop JSName :: "allocateTaskName" + prop Visible :: 1 + prop Writable :: 1 + prop TabName :: "Advanced" + } + inst iSTATREG :: = GBL.CACHE { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "0x%08x" + prop Label :: "Initial Status Register value" + prop Visible :: 0 + prop Writable :: 1 + } + inst Order :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 0 + prop Writable :: 1 + } + inst filter :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filter" + prop NoGen :: 0 + } + inst maxformat :: self.STSGetMaxFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "maxformat" + prop NoGen :: 0 + } + inst sumformat :: self.STSGetSumFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "sumformat" + prop NoGen :: 0 + } + inst avgformat :: self.STSGetAvgFmt() { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "avgformat" + prop NoGen :: 0 + } + inst filtmaxmult :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filtmaxmult" + prop NoGen :: 0 + } + inst filtsummult :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filtsummult" + prop NoGen :: 0 + } + inst unittype :: self.uType() { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "unittype" + prop NoGen :: 0 + } +} + +object TSK_idle :: TSK { + param iComment :: "This is the idle task; it only runs when no other task is ready" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "TSK" + param iDelMsg :: "This task executes all IDL functions and cannot be deleted" + param iFXN :: @IDL_F_loop + param iARG0 :: 0 + param iARG1 :: 0 + param iARG2 :: 0 + param iARG3 :: 0 + param iARG4 :: 0 + param iARG5 :: 0 + param iARG6 :: 0 + param iARG7 :: 0 + param iAUTOSTK :: 1 + param iMANSTK :: @null + param iSTKSZ :: 1024 + param iSTKSEG :: IRAM + param iPRI :: 0 + param iENV :: 0 + param iEXITFLAG :: 1 + param iUSETSKNAME :: 0 + param Order :: 0 + param filter :: 2 + param maxformat :: "%g inst" + param sumformat :: "%g inst" + param avgformat :: "%.2f inst" + param filtmaxmult :: 1 + param filtsummult :: 1 + param unittype :: 0 +} + +object KNL_swi :: SWI { + param iComment :: "This Software Interrupt calls the TSK scheduler" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "TSK" + param iDelMsg :: "This object cannot be deleted in DSP/BIOS." + param function :: @_KNL_run + param pri :: 0 + param mailbox :: 0 + param arg0 :: 0 + param arg1 :: 0 + param dorta :: 1 + param Order :: 0 + param filter :: 2 + param maxformat :: "%g inst" + param sumformat :: "%g inst" + param avgformat :: "%.2f inst" + param filtmaxmult :: 1 + param filtsummult :: 1 + param unittype :: 0 +} + +type IDL { + isa ObjectMgr + prop Label :: "IDL - Idle Function Manager" + prop name :: "IDL" + prop IsContainedIn :: SCH + prop GlobalIcon :: 111 + prop InstanceIcon :: 112 + prop GlobalHelpTopic :: (106) + prop InstanceHelpTopic :: (206) + prop InstancePropertyPage :: ("{586735F1-770B-11d0-A61F-0000C070F3E9}") + prop GlobalPropertyPage :: ("{586735F0-770B-11d0-A61F-0000C070F3E9}") + prop objectSize :: (if (GBL.DSPTYPE == 55 || GBL.DSPTYPE == 28) {$a = (2 * 4)} else {$a = (1 * 4)}, $a) + prop GenLinkPrologue :: ("SECTIONS {%4t\n.%1L: {%8t\n %1U_A_TABBEG = .;\n %3S\n %1U_A_TABEND = .;\n %1U_A_TABLEN = (. - %1U_A_TABBEG) / %2d;\0, name, _objSize, _linkString") + prop GenLinkEpilogue :: ("%8t %1U_A_CALBEG = .;\n %4S\n %1U_A_CALEND = .;\n %1U_A_CALLEN = (. - %1U_A_CALBEG) / %2d;%4t\n} > %3s%5s%0t\n}\n%6S\n\0, name, _objSize, _memSeg, _linkCalString, _pageString, _nilBusyObj") + prop _linkString :: "*(.%1L)" + prop _linkCalString :: "*(.%1Lcal)" + prop _pageString :: if GBL.DSPTYPE == 62 {""} else {if GBL.DSPTYPE == 55 {(if IDL.OBJMEMSEG.space() == "code" {" PAGE 0"} else {if IDL.OBJMEMSEG.space() == "data" {" PAGE 1"} else {if IDL.OBJMEMSEG.space() == "io" {" PAGE 2"} else {" PAGE 0"}}})} else {" PAGE 1"}} + prop _nilBusyObj :: (if ((IDL.USEIDLBUSYOBJ == 0) && (GBL.ROM == 1)) {"IDL_busyObj = 0;\n"} else {""}) + prop _memSeg :: IDL.OBJMEMSEG + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop dataSize :: (self.objectSize() * (IDL.gNumOf + 1)) + prop maxObjs :: (32767) + prop SortByField :: "iPri" + prop SortGroups :: 1 + prop idlFxnSum :: ($a = 0, scan ($i; IDL) {$a += $i.cycles}, $a) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 3 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global AUTOCALCULATE :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Auto calculate idle loop instruction count" + prop JSName :: "AUTOCALCULATE" + prop Visible :: 1 + prop Writable :: CLK.USETIMER + prop Set :: (if ($1 == 1 && CLK.USETIMER == 0) {self.error("CLK must be enabled to do idle loop intruction count")} else {if ($1 == 1 && GBL.ENABLEINST == 0) {self.error("Real Time Analysis must be enabled to do idle loop instruction count")} else {self.AUTOCALCULATE = $1, "ok"}}) + prop NoGen :: 1 + } + global USECLKIDLTIME :: = IDL.AUTOCALCULATE { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global USEIDLBUSYOBJ :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALIBRFXN :: = (if (IDL.AUTOCALCULATE == 1) {if TSK.USETSK {@IDL_F_stub} else {@IDL_F_calibrate}} else {@GBL_NULL}) { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Idle Loop Auto-Calibrate Function" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global CALIBRERROR :: = (if (GBL.DSPTYPE == 62 && IDL.CALIBRFXN == @IDL_F_stub) {6} else {0}) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Idle Loop Auto-Calibrate Error" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + global LOOPOVERHEAD :: 0 { + prop Label :: "Idle Loop Instruction Count" + prop JSName :: "LOOPINSTCOUNT" + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: self.AUTOCALCULATE == 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst function :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + } + inst cycles :: 0 { + prop Label :: "CPU cycles" + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: if (self.iDelUser == "USER") {1} else {0} + prop NoGen :: 1 + } + inst calibration :: 1 { + prop Label :: "Include in CPU load calibration" + prop JSName :: "calibration" + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: if (self.iDelUser == "USER") {1} else {0} + prop NoGen :: 0 + } + inst Order :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 1 + prop Writable :: 1 + } + inst iPri :: 0 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop NoGen :: 1 + } +} + +object IDL_cpuLoad :: IDL { + param iComment :: "This object is required by the system to acquire CPU load data" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "IDL" + param iDelMsg :: "This object is required to compute CPU load and can't be deleted" + param function :: @IDL_F_busy + param cycles :: 0 + param calibration :: 1 + param Order :: 0 + param iPri :: 0 +} + +object IDL_busyObj :: STS { + param iComment :: "This object is required by the system to accumulate CPU load statistics" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "IDL" + param iDelMsg :: "This object is required to accumulate CPU load data and can't be deleted" + param prev :: 0 + param format :: "%g" + param filter :: 1 + param maxformat :: "%g" + param sumformat :: "%g" + param avgformat :: "%.2f" + param unittype :: "Not time based" + param operation :: "Nothing" + param iA :: 1 + param iB :: 0 + param iC :: 1 + param prevhigh :: 0 + param prevlow :: 0 +} + +type ISRC { + isa ObjectMgr + prop name :: "ISRC" + prop Label :: "ISRC - Interrupt Sources" + prop IsConfMod :: 1 + prop Visible :: 0 + prop InstancePropertyPage :: ("{91BA37C0-98C3-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{91BA37C1-98C3-11d1-988B-0020AFEE33C6}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iHwi :: HWI_UNUSED { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: HWI + prop MemberTest :: 1 + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iIntrSelectNum :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } +} + +object Reset :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_RESET + param iIntrSelectNum :: -1 +} + +object Non_Maskable :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_NMI + param iIntrSelectNum :: -1 +} + +object Reserved :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_RESERVED0 + param iIntrSelectNum :: -1 +} + +object Host_Port_Host_to_DSP :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT13 + param iIntrSelectNum :: 0 +} + +object DSPINT :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 0 +} + +object Timer_0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT14 + param iIntrSelectNum :: 1 +} + +object Timer_1 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT15 + param iIntrSelectNum :: 2 +} + +object EMIF_SDRAM_Timer :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT10 + param iIntrSelectNum :: 3 +} + +object External_Pin_4 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT4 + param iIntrSelectNum :: 4 +} + +object External_Pin_5 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT5 + param iIntrSelectNum :: 5 +} + +object External_Pin_6 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT6 + param iIntrSelectNum :: 6 +} + +object External_Pin_7 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT7 + param iIntrSelectNum :: 7 +} + +object EDMA_Controller :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT8 + param iIntrSelectNum :: 8 +} + +object HSRTDX11 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT11 + param iIntrSelectNum :: 10 +} + +object HSRTDX12 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT12 + param iIntrSelectNum :: 11 +} + +object MCSP_0_Transmit :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 12 +} + +object MCSP_0_Receive :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 13 +} + +object MCSP_1_Transmit :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 14 +} + +object MCSP_1_Receive :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 15 +} + +object HPI_PCI_to_DSP :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 0 +} + +object EMIFA_SDRAM_Timer :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iIntrSelectNum :: 3 +} + +object GPIO_Interrupt_4 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT4 + param iIntrSelectNum :: 4 +} + +object GPIO_Interrupt_5 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT5 + param iIntrSelectNum :: 5 +} + +object GPIO_Interrupt_6 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT6 + param iIntrSelectNum :: 6 +} + +object GPIO_Interrupt_7 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT7 + param iIntrSelectNum :: 7 +} + +object EDMA_Interrupt :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT8 + param iIntrSelectNum :: 8 +} + +object JTAGRTDX9 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 9 +} + +object EMU_DTDMA :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT9 + param iIntrSelectNum :: 9 +} + +object EMU_RTDX_RX :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT10 + param iIntrSelectNum :: 10 +} + +object EMU_RTDX_TX :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT11 + param iIntrSelectNum :: 11 +} + +object GPIO_Interrupt_0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 16 +} + +object MCSP_2_Transmit :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 17 +} + +object MCSP_2_Receive :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 18 +} + +object Timer_2 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_INT10 + param iIntrSelectNum :: 19 +} + +object EMIFB_SDRAM_Timer :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 20 +} + +object PCI_WAKEUP :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 21 +} + +object ICINT0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 22 +} + +object ICINT1 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 23 +} + +object UTOPIA_Interrupt :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 23 +} + +object EMAC_MDIO_INT :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 24 +} + +object AXINT1 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 24 +} + +object ARINT1 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 25 +} + +object VPINT0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 25 +} + +object VPINT1 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 26 +} + +object VPINT2 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 27 +} + +object AXINT0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 28 +} + +object ARINT0 :: ISRC { + param iComment :: "" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param iHwi :: HWI_UNUSED + param iIntrSelectNum :: 29 +} + +type LOG { + isa ObjectMgr + prop name :: "LOG" + prop Label :: "LOG - Event Log Manager" + prop IsContainedIn :: INS + prop GlobalIcon :: 113 + prop InstanceIcon :: 114 + prop InstanceHelpTopic :: (207) + prop GlobalHelpTopic :: (107) + prop InstancePropertyPage :: ("{B7240DE8-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DE9-AA51-11cf-9BFE-0000C0AC14C7}") + prop maxObjs :: (32767) + prop AllocType :: ("1\0, _globalAllocDesc, _memSeg, _placement") + prop _globalAllocDesc :: ("%8t .%1L: {%12t\n %1U_A_TABBEG = .;\n _%1U_A_TABBEG = .;\n %2S\n %1U_A_TABEND = .;\n _%1U_A_TABEND = .;\n %1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;\n _%1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;%8t\n }\0, name, _linkString, _objSize") + prop objectSize :: (if (GBL.DSPTYPE == 28 || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE")) {$a = (10 * 4)} , if (GBL.DSPTYPE == 62 || GBL.DSPTYPE == 54 || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL")) {$a = (6 * 4)} , $a) + prop _placement :: (0x7fffffff / 2) + prop AllocInst :: ("1\0, _instAllocDesc, _objMemSeg, _placement") + prop _instAllocDesc :: ("%8t /* %0s buffer */\n .%0s$buf: align = 0x%1x {}\0, _objAlign") + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop _memSeg :: LOG.OBJMEMSEG + prop _linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop _objAlign :: if GBL.DSPTYPE == 55 {self.buflen * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE) * 2} else {self.buflen * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)} + prop _objMemSeg :: self.bufseg + prop LogType :: self.iType + prop LogFormat :: self.iFormat + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"log.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far LOG_Obj %0r;\n\0"} else {"extern LOG_Obj %0r;\n\0"}) + prop dataSize :: ($d = 0, scan ($i; LOG) {if ($i.IsConfObj()) {$d += $i.buflen} , $d += self.objectSize()}, $d) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global ENABLED :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Compile in logging" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global TS :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "timestamped LOGs" + prop JSName :: "TS" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst bufseg :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "bufseg" + prop JSName :: "bufSeg" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst buflen :: 64 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "0,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432" + prop Label :: "buflen (words)" + prop JSName :: "bufLen" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (GlobalStatus.gDirty = 1, self.buflen = $1, "ok") + } + inst logtype :: "circular" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "circular,fixed" + prop Label :: "logtype" + prop JSName :: "logType" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst iType :: "printf" { + prop Label :: "datatype" + prop JSName :: "dataType" + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "printf,raw data" + prop Visible :: 1 + prop Writable :: if self.iType == "system" {0} else {1} + prop NoGen :: 0 + } + inst iFormat :: "0x%x, 0x%x, 0x%x" { + prop Label :: "format" + prop JSName :: "format" + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: if self.iType == "raw data" {1} else {0} + prop NoGen :: 0 + } +} + +object LOG_system :: LOG { + param iComment :: "This object is required by the system to accumulate execution trace information" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "LOG" + param iDelMsg :: "LOG_system is a system log and cannot be deleted." + param bufseg :: IRAM + param buflen :: 64 + param logtype :: "circular" + param iType :: "system" + param iFormat :: "0x%x, 0x%x, 0x%x" +} + +type PIP { + isa ObjectMgr + prop Label :: "PIP - Buffered Pipe Manager" + prop IsContainedIn :: IOF + prop GlobalIcon :: 117 + prop InstanceIcon :: 118 + prop GlobalHelpTopic :: (109) + prop InstanceHelpTopic :: (209) + prop name :: "PIP" + prop maxObjs :: (32767) + prop objectSize :: (if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (27 * 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (34 * 4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (30 * 4)} , if (GBL.DSPTYPE == 28 || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") || (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE")) {$a = (50 * 4)} , if (GBL.DSPTYPE == 62) {$a = (25 * 4)} , $a) + prop dataSize :: ($b = 0, scan ($i; PIP) {if ($i.IsConfObj()) {$b += (12 + $i.framesize) * $i.numframes + self.objectSize()} }, $b) + prop InstancePropertyPage :: ("{B7240DF0-AA51-11cf-9BFE-0000C0AC14C8}") + prop GlobalPropertyPage :: ("{B7240DF1-AA51-11cf-9BFE-0000C0AC14C8}") + prop localCreate :: ("ok") + prop AllocType :: ("1\0, _globalAllocDesc, _memSeg, _placement") + prop _globalAllocDesc :: ("%8t .%1L: {%12t\n %1U_A_TABBEG = .;\n _%1U_A_TABBEG = .;\n %2S\n %1U_A_TABEND = .;\n _%1U_A_TABEND = .;\n %1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;\n _%1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;%8t\n }\0, name, _linkString, _objSize") + prop AllocInst :: ("1\0, _instAllocDesc, _objMemSeg, _placement") + prop _instAllocDesc :: (if self.bufalign > 0 {"%8t /* %0s buffer */\n .pip%1d: align = 0x%2x {}\0, _objId, _objAlign"} else {"%8t /* %0s buffer */\n .pip%1d: {}\0, _objId"}) + prop _placement :: (0x7fffffff / 2) + prop _objId :: self.iId + prop _objAlign :: self.bufalign * 4 + prop _objMemSeg :: self.bufseg + prop _linkString :: if (self.gNumOf + self.gNumEmbed) > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop _memSeg :: PIP.OBJMEMSEG + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop mkId :: (self.iId = self.gNextId++, self.gNumOf++, self.iId) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"pip.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far PIP_Obj %0r;\n\0"} else {"extern PIP_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global gNumEmbed :: 2 { + prop NoGen :: 0 + } + global gNextId :: 0 + global OBJSIZE :: = self._objSize + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst bufseg :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "bufSeg" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 1 + } + inst bufalign :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "bufAlign" + prop Style :: 0x01 | 0x02 + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 1 + prop Set :: ($e = "ok", if ($1 == 0) {$e = self.error("Cannot set align value to 0")} else {self.bufalign = $1}, $e) + } + inst buf :: "" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst framesize :: 8 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "framesize (words)" + prop JSName :: "frameSize" + prop Style :: if GBL.DSPTYPE == 62 {0x02} else {0x01 | 0x02} + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop Set :: (if ($1 < 1) {self.error("framesize must be >= 1.")} else {GlobalStatus.gDirty = 1, self.framesize = $1, "ok"}) + } + inst numframes :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop JSName :: "numFrames" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop Set :: (if ($1 < 1) {self.error("Pipes must contain at least 1 frame.")} else {GlobalStatus.gDirty = 1, self.numframes = $1, "ok"}) + } + inst monitor :: "reader" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "monitor" + prop Enum :: "reader,writer,none" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst notifyWriter :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyWriterFxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst nwarg0 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyWriterArg0" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst nwarg1 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyWriterArg1" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst notifyReader :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyReaderFxn" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst nrarg0 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyReaderArg0" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst nrarg1 :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "notifyReaderArg1" + prop Visible :: 1 + prop Writable :: (if self.iDelUser == "USER" {1} else {0}) + prop NoGen :: 0 + prop TabName :: "Notify Functions" + } + inst bufFrameAlign :: = self._objAlign { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } +} + +type SEM { + isa ObjectMgr + prop name :: "SEM" + prop Label :: "SEM - Semaphore Manager" + prop IsContainedIn :: SYN + prop GlobalIcon :: 137 + prop InstanceIcon :: 138 + prop GlobalHelpTopic :: (310) + prop InstanceHelpTopic :: (410) + prop InstancePropertyPage :: ("{D01ACC04-38DD-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{D01ACC05-38DD-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t .sem: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = (8 + 3)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (10 + 4)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (8 + 3)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (16 + 6)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (16 + 6)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (10 + 4)} , if (GBL.DSPTYPE == 28) {$a = (16 + 6)} , $a) + prop dataSize :: (SEM.objectSize * SEM.gNumOf * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"sem.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far SEM_Obj %0r;\n\0"} else {"extern SEM_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iCount :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Label :: "Initial semaphore count" + prop JSName :: "count" + prop Visible :: 1 + prop Writable :: 1 + } +} + +type MBX { + isa ObjectMgr + prop name :: "MBX" + prop Label :: "MBX - Mailbox Manager" + prop IsContainedIn :: SYN + prop GlobalIcon :: 131 + prop InstanceIcon :: 132 + prop GlobalHelpTopic :: (307) + prop InstanceHelpTopic :: (407) + prop InstancePropertyPage :: ("{0EB45D44-38C1-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{0EB45D45-38C1-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _bssAllocDesc, _memSeg, _placement"} ) + prop _bssAllocDesc :: ("%8t .mbx: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop AllocInst :: ("1\0 _instAllocDesc, _instMemSeg, _placement") + prop _instAllocDesc :: ("%8t .%0s$que: align = 0x4 {%12t\n %0s$queElems = .;\n . += %1d;%8t\n }\0, _qElemSize") + prop _instMemSeg :: self.iMbxSeg + prop _qElemSize :: (if ((GBL.DSPTYPE == 55) && (GBL.DSPSUBTYPE != 5599)) {$a = self.iMsgSize, if ($a & 0x1) {$a += 1} , (8 + $a) * self.iMbxLength * 2} else {if (GBL.DSPTYPE == 28) {$a = self.iMsgSize, if ($a & 0x1) {$a += 1} , (8 + $a) * self.iMbxLength} else {$a = self.iMsgSize, $b = GBL.DSPWORDSIZE / GBL.DSPCHARSIZE, $c = $a & ($b - 1), if ($c != 0) {$a = $a + ($b - $c)} , (8 + $a) * self.iMbxLength}}) + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = (29)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (28)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (24)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (46)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (46)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (28)} , if (GBL.DSPTYPE == 28) {$a = (46)} , $a) + prop dataSize :: ($d = 0, scan ($i; MBX) {$d += (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE) * (($i.iMsgSize + 2) * $i.iMbxLength + self.objectSize())}, $d) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"mbx.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far MBX_Obj %0r;\n\0"} else {"extern MBX_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iMsgSize :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Label :: "Message Size" + prop JSName :: "messageSize" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: (if ($1 == 0) {self.error("Message size cannot be zero")} else {GlobalStatus.gDirty = 1, self.iMsgSize = $1, "ok"}) + } + inst iMbxLength :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Label :: "Mailbox Length" + prop JSName :: "length" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: (if ($1 == 0) {self.error("Mailbox length cannot be zero")} else {GlobalStatus.gDirty = 1, self.iMbxLength = $1, "ok"}) + } + inst iMbxSeg :: MBX.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Element memory segment" + prop JSName :: "elementSeg" + prop Visible :: 1 + prop Writable :: 1 + } +} + +type QUE { + isa ObjectMgr + prop name :: "QUE" + prop Label :: "QUE - Atomic Queue Manager" + prop IsContainedIn :: SYN + prop GlobalIcon :: 133 + prop InstanceIcon :: 134 + prop IsConfMod :: 1 + prop GlobalHelpTopic :: (309) + prop InstanceHelpTopic :: (409) + prop InstancePropertyPage :: ("{D01ACC01-38DD-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{D01ACC02-38DD-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t .que: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = (2)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (2)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (2)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (4)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (2)} , if (GBL.DSPTYPE == 28) {$a = (4)} , $a) + prop dataSize :: (QUE.objectSize * QUE.gNumOf * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"que.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far QUE_Obj %0r;\n\0"} else {"extern QUE_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type LCK { + isa ObjectMgr + prop name :: "LCK" + prop Label :: "LCK - Resource Lock Manager" + prop IsContainedIn :: SYN + prop GlobalIcon :: 129 + prop InstanceIcon :: 130 + prop IsConfMod :: 1 + prop GlobalHelpTopic :: (306) + prop InstanceHelpTopic :: (406) + prop InstancePropertyPage :: ("{0EB45D40-38C1-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{0EB45D41-38C1-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _bssAllocDesc, _memSeg, _placement"} ) + prop _bssAllocDesc :: ("%8t .lck: {}") + prop _objAllocDesc :: ("%8t .LCK$obj: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = (10)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (12)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (10)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (20)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (20)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (12)} , if (GBL.DSPTYPE == 28) {$a = (20)} , $a) + prop dataSize :: (LCK.objectSize * LCK.gNumOf * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"lck.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far LCK_Obj %0r;\n\0"} else {"extern LCK_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type STS { + isa ObjectMgr + prop name :: "STS" + prop Label :: "STS - Statistics Object Manager" + prop IsContainedIn :: INS + prop GlobalIcon :: 125 + prop InstanceIcon :: 126 + prop InstanceHelpTopic :: (212) + prop GlobalHelpTopic :: (112) + prop AllocType :: ("1\0, _globalAllocDesc, _memSeg, _placement") + prop _globalAllocDesc :: ("%8t .%1L: {%12t\n %1U_A_TABBEG = .;\n _%1U_A_TABBEG = .;\n %2S\n %1U_A_TABEND = .;\n _%1U_A_TABEND = .;\n %1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;\n _%1U_A_TABLEN = (. - _%1U_A_TABBEG) / %3d;%8t\n }\0, name, _linkString, _objSize") + prop localInit :: (if (PRD.CALLBACKOBJ != nil) {self.error("STS initialization failure")} , PRD.CALLBACKOBJ = STS) + prop objectSize :: ((4 * 4)) + prop _placement :: (0x7fffffff / 2) + prop _linkString :: if self.gNumOf > 0 {"*(.%1L)"} else {"/* no %1U objects */"} + prop _memSeg :: STS.OBJMEMSEG + prop _objSize :: if GBL.DSPTYPE == 55 {(2 * self.objectSize())} else {self.objectSize()} + prop dataSize :: (self.objectSize() * (STS.gNumOf + STS.gNumEmbed)) + prop maxObjs :: (32767) + prop InstancePropertyPage :: ("{B7240DEE-AA51-11cf-9BFE-0000C0AC14C7}") + prop GlobalPropertyPage :: ("{B7240DEF-AA51-11cf-9BFE-0000C0AC14C7}") + prop STSGetMaxFmt :: (self.format) + prop STSGetSumFmt :: (self.format) + prop STSGetAvgFmt :: ("%.2f") + prop STSFilterSum :: ((self.iA * $1 + self.iB * $2) / (1.0 * self.iC)) + prop STSFilterMax :: ((self.iA * $1 + self.iB) / (1.0 * self.iC)) + prop HighTimeBased :: (if self.unittype == "High resolution time based" {1} else {0}) + prop LowTimeBased :: (if self.unittype == "Low resolution time based" {1} else {0}) + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"sts.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far STS_Obj %0r;\n\0"} else {"extern STS_Obj %0r;\n\0"}) + prop modifiable :: ((if (self.iDelUser == "USER" || self.iDelUser == "HWI") {1} else {0})) + prop untype :: (if (self.unittype == "Not time based") {$a = 2} , if (self.unittype == "High resolution time based") {$a = 0} , if (self.unittype == "Low resolution time based") {$a = 1} , $a) + prop optype :: (if (self.operation == "Nothing") {$a = 0} , if (self.operation == "A * x") {$a = 1} , if (self.operation == "A * x + B") {$a = 2} , if (self.operation == "(A * x + B) / C") {$a = 3} , $a) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global gNumEmbed :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst prev :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: self.modifiable() + prop JSName :: "previousVal" + prop NoGen :: GBL.DSPTYPE != 40 && GBL.DSPTYPE != 62 + prop Set :: (self.prev = $1, self.prevlow = $1 & 0xffff, self.prevhigh = ($1 >> 16) & 0xffff, "ok") + } + inst format :: "%g" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "format" + prop NoGen :: 1 + } + inst filter :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "filter" + prop NoGen :: 0 + } + inst maxformat :: "%g" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "maxformat" + prop NoGen :: 0 + } + inst sumformat :: "%g" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "sumformat" + prop NoGen :: 0 + } + inst avgformat :: "%.2f" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop Label :: "avgformat" + prop NoGen :: 0 + } + inst unittype :: "Not time based" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Not time based,High resolution time based,Low resolution time based" + prop Label :: "unit type" + prop JSName :: "unitType" + prop Visible :: 1 + prop Writable :: self.modifiable() + prop NoGen :: 1 + prop Set :: (self.unittype = $1, if ($1 == "High resolution time based") {self.iA = 1, self.iB = 0, self.iC = 1, self.operation = "A * x"} else {if ($1 == "Low resolution time based") {self.iA = 1, self.iB = 0, self.iC = 1, self.operation = "A * x"} else {self.iA = 1, self.iB = 0, self.iC = 1, self.operation = "Nothing"}}, "ok") + } + inst operation :: "Nothing" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Nothing,A * x,A * x + B,(A * x + B) / C" + prop Label :: "host operation" + prop JSName :: "operation" + prop Visible :: 1 + prop Writable :: ((self.unittype != "Low resolution time based") && self.modifiable()) + prop NoGen :: 1 + prop Set :: (self.operation = $1, if ($1 == "Nothing" && self.unittype != "High resolution time based") {self.iA = 1, self.iB = 0, self.iC = 1} else {if ($1 == "A * x") {self.iB = 0, self.iC = 1} else {if ($1 == "A * x + B") {self.iC = 1} }}, "ok") + } + inst op :: = self.optype() { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + inst uType :: = self.untype() { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 0 + } + inst iA :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: (self.modifiable() && !(self.unittype != "Not time based" || self.operation == "Nothing")) + prop Label :: "A" + prop JSName :: "numA" + prop NoGen :: 0 + } + inst iB :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: (self.modifiable() && !(self.unittype == "Low resolution time based" || self.operation == "Nothing" || self.operation == "A * x")) + prop Label :: "B" + prop JSName :: "numB" + prop NoGen :: 0 + } + inst iC :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: (self.modifiable() && (self.unittype == "Not time based" && self.operation == "(A * x + B) / C")) + prop Label :: "C" + prop JSName :: "numC" + prop NoGen :: 0 + } + inst prevhigh :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: GBL.DSPTYPE == 40 || GBL.DSPTYPE == 62 + } + inst prevlow :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } +} + +type SYS { + isa Module + prop name :: "SYS" + prop Label :: "SYS - System Settings" + prop IsContainedIn :: SYSTEM + prop GlobalIcon :: 141 + prop InstanceIcon :: 142 + prop IsConfMod :: 1 + prop GlobalHelpTopic :: (313) + prop InstanceHelpTopic :: (413) + prop InstancePropertyPage :: ("{473C4A62-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{473C4A63-B1A8-11d0-9885-0020AFEE33C6}") + prop AllocType :: (if self.PUTCFXN == @_UTL_doPutc {"2\0, _globalAllocDesc, _memSeg, _midPlace, _traceString, _traceSeg, _midPlace"} else {"1\0, _globalAllocDesc, _memSeg, _midPlace"}) + prop _globalAllocDesc :: ("%8t .sys: {}") + prop _traceString :: ("%8t .trace: fill = 0x0 align = 0x4 {%12t\n_SYS_PUTCBEG = .;\n. += 0x%1x;\n_SYS_PUTCEND = . - 1;%8t\n }\0, _traceSize") + prop _midPlace :: (0x7fffffff / 2) + prop _memSeg :: MEM.CFGOBJSEG + prop _traceSeg :: SYS.TRACESEG + prop _traceSize :: SYS.TRACESIZE + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global TRACESIZE :: 512 { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Format :: "%d" + prop Style :: 0x01 | 0x02 + prop Label :: "Trace Buffer Size" + prop JSName :: "TRACESIZE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global TRACESEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Trace Buffer Memory" + prop JSName :: "TRACESEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global ABORTFXN :: @_UTL_doAbort { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Abort Function" + prop JSName :: "ABORTFXN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global ERRORFXN :: @_UTL_doError { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Error Function" + prop JSName :: "ERRORFXN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global EXITFXN :: @_UTL_halt { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Exit Function" + prop JSName :: "EXITFXN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global PUTCFXN :: @_UTL_doPutc { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Putc Function" + prop JSName :: "PUTCFXN" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } +} + +type SIO { + isa ObjectMgr + prop name :: "SIO" + prop Label :: "SIO - Stream Input and Output Manager" + prop IsContainedIn :: IOF + prop DependsOn :: "DIO,DGN,DHL,DPI" + prop GlobalIcon :: 139 + prop InstanceIcon :: 140 + prop GlobalHelpTopic :: (311) + prop InstanceHelpTopic :: (411) + prop InstancePropertyPage :: ("{7C4C9A60-763E-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{7C4C9A61-763E-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"2\0, _bssAllocDesc, _memSeg, _placement, + _objAllocDesc, _memSeg, _placement"} ) + prop _bssAllocDesc :: ("%8t .SIO$bss: {%12t\n *(.SIO$bss)%8t\n }") + prop _objAllocDesc :: ("%8t .SIO$obj: {%12t\n *(.SIO$obj)%8t\n }") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop AllocInst :: ("1\0, _instBufDesc, _instBufSeg, _placement") + prop _instBufDesc :: (if self.iAlign > 1 {"%8t .%0s$bufs: align = 0x%1x {}\0, _objAlign"} else {"%8t .%0s$bufs: {}"}) + prop _objAlign :: self.iAlign + prop _instBufSeg :: self.iBufSegid + prop defDev :: ($h = nil, $i = nil, $j = nil, scan ($h; nil) {if ($h.isDriver == 1) {scan ($i; $h) {if ($j == nil && $i.iIsTerminal != 0 && $i.iIsVirtual == 0) {$j = $i, break} }} }, $j) + prop devList :: ($h = nil, $i = nil, $j = nil, scan ($h; nil) {if ($h.isDriver == 1) {scan ($i; $h) {if ($j == nil && $i.iIsTerminal != 0 && $i.iIsVirtual == 0) {$j = $i, scan ($a; DIO) {if ($a == $i) {$i.numTimeUse++} }, break} }} }, $j) + prop setDev :: ($h = nil, $i = nil, $j = nil, scan ($h; nil) {if ($h.isDriver == 1) {scan ($i; $h) {if ($i == $1) {$j = $i} }} }, $j) + prop localCanCreate :: (if (self.defDev == nil) {self.error("A driver device must be created before creating a stream.")} else {"ok"}) + prop localDelete :: (scan ($a; DIO) {if ($a == self.iDevice) {self.iDevice.numTimeUse--} }, "ok") + prop cGen :: 1 + prop cHeaderName :: if self.gNumOf > 0 {"sio.h"} else {""} + prop cGenHInst :: (if (GBL.DSPTYPE == 62) {"extern far SIO_Obj %0r;\n\0"} else {"extern SIO_Obj %0r;\n\0"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumEmbed :: 0 { + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global USEISSUERECLAIM :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use Only Issue/Reclaim Model" + prop JSName :: "USEISSUERECLAIM" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (self.USEISSUERECLAIM = $1, if ($1 == 1) {scan ($i; SIO) {$i.iModelName = "Issue/Reclaim"}} , "ok") + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDevice :: SIO.devList { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop TypeTest :: $1.isDriver == 1 + prop MemberTest :: $1.driverType != "DEV_IOMTYPE" + prop Label :: "Device" + prop JSName :: "deviceName" + prop Set :: (if (($1.iIsTerminal == 0) && (self.iDevCtrlParam == "")) {self.error("To select a stacking device, enter first a terminal device in Device Control String")} else {if ($1.iIsVirtual == 1) {self.error("The device you have selected is a virtual instance, you must select a non-virtual device")} else {scan ($a; DIO) {if ($a == self.iDevice) {self.iDevice.numTimeUse--} }, scan ($b; DIO) {if ($b == $1) {$1.numTimeUse++} }, self.iDevice = self.setDev($1), "ok"}}) + prop Visible :: 1 + prop Writable :: 1 + } + inst iDevCtrlParam :: "" { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Device Control String" + prop JSName :: "controlParameter" + prop Visible :: 1 + prop Writable :: 1 + } + inst iDevId :: = self.iDevice.iDevId + inst iFxns :: = self.iDevice.iFxns + inst iMode :: "input" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "input,output" + prop Label :: "Mode" + prop JSName :: "mode" + prop Visible :: 1 + prop Writable :: 1 + } + inst iBufsize :: 0x80 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x02 + prop Label :: "Buffer size" + prop JSName :: "bufSize" + prop Visible :: 1 + prop Writable :: 1 + } + inst iNbufs :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Label :: "Number of buffers" + prop JSName :: "numBufs" + prop Visible :: 1 + prop Writable :: 1 + } + inst iBufSegid :: = self.OBJMEMSEG { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Place buffers in memory segment" + prop JSName :: "bufSegId" + prop Visible :: 1 + prop Writable :: self.iAllocBuf == 1 + } + inst iAlign :: 1 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768" + prop Label :: "Buffer alignment" + prop JSName :: "bufAlign" + prop Visible :: 1 + prop Writable :: self.iAllocBuf == 1 + } + inst iFlush :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Flush" + prop JSName :: "flush" + prop Visible :: 1 + prop Writable :: 1 + } + inst iModelName :: "Standard" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "Standard,Issue/Reclaim" + prop Label :: "Model" + prop JSName :: "modelName" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: ($e = "ok", if (self.USEISSUERECLAIM == 1) {if ($1 == "Standard") {$e = self.error("SIO Issue/Reclaim model support selected")} else {self.iModel = if $1 == "Standard" {"SIO_STANDARD"} else {"SIO_ISSUERECLAIM"}, self.iModelName = $1}} else {self.iModel = if $1 == "Standard" {"SIO_STANDARD"} else {"SIO_ISSUERECLAIM"}, self.iModelName = $1}, $e) + } + inst iAllocBuf :: = self.iSaveAllocBuf { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Allocate Static Buffer(s)" + prop JSName :: "allocStaticBuf" + prop Visible :: 1 + prop Writable :: 1 + prop Set :: (self.iSaveAllocBuf = $1, "ok") + } + inst iSaveAllocBuf :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iModel :: "SIO_STANDARD" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "SIO_STANDARD,SIO_ISSUERECLAIM" + prop Visible :: 0 + prop Writable :: 0 + } + inst iTimeout :: = if self.iModel == "SIO_ISSUERECLAIM" {self.iSaveTimeout} else {-1} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Timeout for I/O operation" + prop JSName :: "timeout" + prop Visible :: 1 + prop Writable :: self.iModel == "SIO_ISSUERECLAIM" + prop Set :: (self.iSaveTimeout = $1, "ok") + } + inst iSaveTimeout :: -1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst useCallBackFxn :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "use callback function" + prop JSName :: "useCallBackFxn" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop TabName :: "Callback" + } + inst callBackFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "callback function" + prop JSName :: "callBackFxn" + prop Visible :: 1 + prop Writable :: self.useCallBackFxn + prop NoGen :: 0 + prop TabName :: "Callback" + } + inst arg0 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "argument 0" + prop JSName :: "arg0" + prop Visible :: 1 + prop Writable :: self.useCallBackFxn + prop NoGen :: 0 + prop TabName :: "Callback" + } + inst arg1 :: 0 { + prop Type :: "{E91790E0-0456-11d2-B8D0-006008BDB66F}" + prop Label :: "argument 1" + prop JSName :: "arg1" + prop Visible :: 1 + prop Writable :: self.useCallBackFxn + prop NoGen :: 0 + prop TabName :: "Callback" + } +} + +type GIO { + isa Module + prop Visible :: 1 + prop name :: "GIO" + prop Label :: "GIO - General Input/Output Manager" + prop IsConfMod :: self.USEGIO + prop IsContainedIn :: IOF + prop DependsOn :: "UDEV" + prop GlobalIcon :: 141 + prop InstanceIcon :: 142 + prop GlobalHelpTopic :: (320) + prop InstanceHelpTopic :: (420) + prop InstancePropertyPage :: ("{473C4A62-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{473C4A63-B1A8-11d0-9885-0020AFEE33C6}") + prop AllocType :: ("1\0, _globalAllocDesc, _memSeg, _midPlace") + prop _globalAllocDesc :: ("%8t .gio: {}") + prop _midPlace :: (0x7fffffff / 2) + prop _memSeg :: MEM.CFGOBJSEG + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global CALLBACKOBJ :: nil { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global USEGIO :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable General Input/Output Manager" + prop JSName :: "ENABLEGIO" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global CREATEFXN :: = if self.USEGIO == 1 {@_SEM_create} else {@_FXN_F_nop} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Create Function" + prop JSName :: "CREATEFXN" + prop Visible :: 1 + prop Writable :: self.USEGIO + prop NoGen :: 0 + } + global DELETEFXN :: = if self.USEGIO == 1 {@_SEM_delete} else {@_FXN_F_nop} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Delete Function" + prop JSName :: "DELETEFXN" + prop Visible :: 1 + prop Writable :: self.USEGIO + prop NoGen :: 0 + } + global PENDFXN :: = if self.USEGIO == 1 {@_SEM_pend} else {@_FXN_F_nop} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Pend Function" + prop JSName :: "PENDFXN" + prop Visible :: 1 + prop Writable :: self.USEGIO + prop NoGen :: 0 + } + global POSTFXN :: = if self.USEGIO == 1 {@_SEM_post} else {@_FXN_F_nop} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Post Function" + prop JSName :: "POSTFXN" + prop Visible :: 1 + prop Writable :: self.USEGIO + prop NoGen :: 0 + } +} + +type DEV { + isa ObjectMgr + prop name :: "DEV" + prop Visible :: 0 + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _bssAllocDesc, _memSeg, _placement"} , if (self.devCount() > 0) {"1\0, _devtableDesc, _memSeg, _placement"} ) + prop _bssAllocDesc :: ("%8t .dev: {}") + prop _devtableDesc :: ("%8t .devtable: {}") + prop _memSeg :: MEM.CFGOBJSEG + prop _placement :: (0x7fffffff / 2) + prop DependsOn :: "HWI" + prop devCount :: ($i = nil, $a = 0, scan ($i; nil) {if ($i.isDriver == 1) {$a = $a + $i.gNumOf} }, $a) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } +} + +type UDEV { + isa ObjectMgr + prop name :: "UDEV" + prop Label :: "User-Defined Devices" + prop IsContainedIn :: SIODRIVER + prop DependsOn :: "DEV" + prop GlobalIcon :: 127 + prop InstanceIcon :: 128 + prop GlobalHelpTopic :: (315) + prop InstanceHelpTopic :: (415) + prop InstancePropertyPage :: ("{7AE86AA0-35C0-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{7AE86AA1-35C0-11d1-988B-0020AFEE33C6}") + prop maxObjs :: (32767) + prop isDriver :: (1) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t .udev: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: MEM.CFGOBJSEG + prop _driverType :: (if self.fxnTableType == "DEV_Fxns" {"DEV_SIOTYPE"} else {"DEV_IOMTYPE"}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iInit :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "init function" + prop JSName :: "initFxn" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (self.iInit = $1, self.initFxn = self.iInit, "ok") + } + inst iFxns :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "function table ptr" + prop JSName :: "fxnTable" + prop Visible :: 1 + prop Writable :: 1 + } + inst fxnTableType :: "DEV_Fxns" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "DEV_Fxns,IOM_Fxns" + prop Label :: "function table type" + prop JSName :: "fxnTableType" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst driverType :: = self._driverType { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: "DEV_SIOTYPE,DEV_IOMTYPE" + prop Visible :: 0 + } + inst iDevId :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "device id" + prop JSName :: "deviceId" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: (self.iDevId = $1, self.deviceId = self.iDevId, "ok") + } + inst iParams :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "device params ptr" + prop JSName :: "params" + prop Visible :: 1 + prop Writable :: 1 + } + inst deviceId :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "" + prop Visible :: 0 + } + inst initFxn :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop JSName :: "" + prop Visible :: 0 + } + inst iIsStacking :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Stacking Device" + prop JSName :: "stackingDevice" + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst deviceGlobalDataPtr :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "device global data ptr" + prop JSName :: "deviceGlobalDataPtr" + prop Visible :: 1 + prop Writable :: self.fxnTableType == "IOM_Fxns" + } + inst iIsTerminal :: = if self.fxnTableType == "DEV_Fxns" {1} else {0} { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iIsVirtual :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } +} + +type DIO { + isa ObjectMgr + prop Visible :: 1 + prop Label :: "DIO - Class Driver" + prop name :: "DIO" + prop IsContainedIn :: SIODRIVER + prop DependsOn :: "UDEV" + prop GlobalIcon :: 127 + prop InstanceIcon :: 127 + prop GlobalHelpTopic :: (319) + prop InstanceHelpTopic :: (419) + prop InstancePropertyPage :: ("{f80273c0-3838-11d2-a32c-006097656921}") + prop GlobalPropertyPage :: ("{050a0600-3839-11d2-a32c-006097656921}") + prop maxObjs :: (32767) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t .dio: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: self.OBJMEMSEG + prop isDriver :: (1) + prop mdObject :: ($h = nil, $j = nil, scan ($h; UDEV) {if ($h.driverType == "DEV_IOMTYPE") {$j = $h, break} }, $j) + prop localCanCreate :: (if (self.mdObject == nil) {self.error("An IOM type device must be created first.")} else {"ok"}) + prop numTsk :: ($a = 0, $h = nil, scan ($h; DIO) {if ($h.useCallBackFxn == 0) {$a = $a + $h.numTimeUse} }, $a) + prop numSwi :: ($a = 0, $h = nil, scan ($h; DIO) {if ($h.useCallBackFxn == 1) {$a = $a + $h.numTimeUse} }, $a) + prop functionTablePtr :: (if (self.STATIC) {if (self.useCallBackFxn) {@_DIO_cbStaticFxns} else {@_DIO_tskStaticFxns}} else {if (self.useCallBackFxn) {@_DIO_cbDynamicFxns} else {@_DIO_tskDynamicFxns}}) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + global STATIC :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Create all DIO Objects Statically" + prop JSName :: "STATICCREATE" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + global NUMTSKBASE :: = self.numTsk { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "TSK based" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + global NUMSWIBASE :: = self.numSwi { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "SWI based" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst useCallBackFxn :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "use callback version of DIO function table (for SWI)" + prop JSName :: "useCallBackFxn" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst fxnsTable :: = self.functionTablePtr { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 0 + } + inst initFxn :: @_DIO_init { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 0 + } + inst deviceName :: self.mdObject { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: UDEV + prop MemberTest :: $1.driverType == "DEV_IOMTYPE" + prop Label :: "device name" + prop JSName :: "deviceName" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst chanParams :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "channel parameters" + prop JSName :: "chanParams" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst numTimeUse :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDevId :: 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iFxns :: = self.functionTablePtr { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iIsTerminal :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iIsVirtual :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } +} + +type DGN { + isa ObjectMgr + prop name :: "DGN" + prop Label :: "DGN - Software Generator Driver" + prop IsContainedIn :: SIODRIVER + prop GlobalIcon :: 127 + prop InstanceIcon :: 128 + prop GlobalHelpTopic :: (302) + prop InstanceHelpTopic :: (402) + prop InstancePropertyPage :: ("{054FE166-B014-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{054FE167-B014-11d0-9885-0020AFEE33C6}") + prop DependsOn :: "DEV" + prop maxObjs :: (32767) + prop isDriver :: (1) + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: ("%8t .dgn: {}") + prop _placement :: (0x7fffffff / 2) + prop _memSeg :: MEM.CFGOBJSEG + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDevice :: "user" { + prop Type :: "{21455EA1-B96A-11cf-9BFE-0000C0AC14C7}" + prop Enum :: if GBL.DSPARITHMETIC == "FLOAT" {"user,sine,random,constant,printFloat,printHex,printInt"} else {"user,sine,random,constant,printHex,printInt"} + prop Label :: "Device category" + prop JSName :: "device" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + prop Set :: ($a = $1, if ($a != self.iDevice) {self.iDevice = $a, self.iUserFxn = @_FXN_F_nop} , if ($a == "user") {self.iUserFxn = self.iSaveUserFxn} , if ($a == "printFloat") {self.iUserFxn = @_DGN_printFloat} , if ($a == "printHex") {self.iUserFxn = @_DGN_printHex} , if ($a == "printInt") {self.iUserFxn = @_DGN_printInt} , "ok") + } + inst iUseDefaults :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Use default parameters" + prop Visible :: 1 + prop JSName :: "useDefaultParam" + prop Writable :: self.iDevice == "sine" || self.iDevice == "constant" || self.iDevice == "random" || self.iDevice == "user" + } + inst iDevId :: = if self.iDevice == "constant" {@DGN_CONST} else {if self.iDevice == "random" {@DGN_RAND} else {if self.iDevice == "sine" {@DGN_SINE} else {@DGN_USER}}} { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Device ID" + prop JSName :: "deviceId" + prop Visible :: 1 + prop Writable :: 0 + } + inst iIsTerminal :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iIsVirtual :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iConstant :: if GBL.DSPARITHMETIC == "FIXED" {1} else {1.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Constant value" + prop JSName :: "constant" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "constant" || self.iDevice == "user") + } + inst iRandSeed :: 1 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Seed value" + prop JSName :: "seedValue" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "random" || self.iDevice == "user") + } + inst iRandLower :: if GBL.DSPARITHMETIC == "FIXED" {-32767} else {0.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Lower limit" + prop JSName :: "lowerLimit" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "random" || self.iDevice == "user") + } + inst iRandUpper :: if GBL.DSPARITHMETIC == "FIXED" {32767} else {1.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Upper limit" + prop JSName :: "upperLimit" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "random" || self.iDevice == "user") + } + inst iSineGain :: if GBL.DSPARITHMETIC == "FIXED" {32767} else {1.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Gain" + prop JSName :: "gain" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "sine" || self.iDevice == "user") + } + inst iSineFreq :: if GBL.DSPARITHMETIC == "FIXED" {1} else {1000.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Frequency (Hz)" + prop JSName :: "frequency" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "sine" || self.iDevice == "user") + } + inst iSinePhase :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0.0} { + prop Type :: "{3EE4CB80-E273-11d0-BB8F-0000C008F2E9}" + prop Style :: if GBL.DSPARITHMETIC == "FIXED" {0} else {0x04} + prop Format :: if GBL.DSPARITHMETIC == "FIXED" {"%d"} else {"%f"} + prop Label :: "Phase (radians)" + prop JSName :: "phase" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "sine" || self.iDevice == "user") + } + inst iSineRate :: if GBL.DSPARITHMETIC == "FIXED" {256} else {44000} { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Sample rate (samples/sec)" + prop JSName :: "rate" + prop Visible :: 1 + prop Writable :: self.iUseDefaults == 0 && (self.iDevice == "sine" || self.iDevice == "user") + } + inst iUserFxn :: if self.iDevice == "printFloat" {@_DGN_printFloat} else {if self.iDevice == "printHex" {@_DGN_printHex} else {if self.iDevice == "printInt" {@_DGN_printInt} else {@_FXN_F_nop}}} { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "User function" + prop JSName :: "fxn" + prop Visible :: 1 + prop Writable :: self.iDevice == "user" + prop Set :: (self.iUserFxn = $1, self.iSaveUserFxn = self.iUserFxn, "ok") + } + inst iSaveUserFxn :: @_FXN_F_nop { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iUserArg :: = 0 { + prop Type :: "{7C434D01-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "User function argument" + prop JSName :: "arg" + prop Visible :: 1 + prop Writable :: self.iDevice == "user" + } + inst iFxns :: @_DGN_FXNS { + prop NoGen :: 1 + } +} + +type DHL { + isa ObjectMgr + prop name :: "DHL" + prop Label :: "DHL - Host Link Driver" + prop IsContainedIn :: SIODRIVER + prop GlobalHelpTopic :: (303) + prop InstanceHelpTopic :: (403) + prop InstancePropertyPage :: ("{9C29DA20-90F9-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{9C29DA21-90F9-11d1-988B-0020AFEE33C6}") + prop GlobalIcon :: 127 + prop InstanceIcon :: 128 + prop DependsOn :: "DEV" + prop Visible :: 1 + prop isDriver :: 1 + prop objectSize :: (if (GBL.DSPTYPE == 62) {$a = (19)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 1) {$a = (22)} , if (GBL.DSPTYPE == 54 && GBL.FARMODE == 0) {$a = (19)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "LARGE") {$a = (34)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "HUGE") {$a = (34)} , if (GBL.DSPTYPE == 55 && GBL.MEMORYMODEL == "SMALL") {$a = (22)} , if (GBL.DSPTYPE == 28) {$a = (34)} , $a) + prop dataSize :: (DHL.objectSize * DHL.gNumOf * (GBL.DSPWORDSIZE / GBL.DSPCHARSIZE)) + prop localCanCreate :: (if (self.gChannelsAvailable > 0) {"ok"} else {self.warning("No HST channels are available for a new DHL device.")}) + prop localCreate :: (self.gChannelsAvailable--, self.seizeHSTChannel(self.iHSTChannel), "ok") + prop seizeHSTChannel :: ($1.iDelUser = "DHL", $1.iDHLAvailable = 0, $1.notify = @_DHL_notify, $1.arg0 = $1.iId, "ok") + prop localDelete :: (self.gChannelsAvailable++, self.releaseHSTChannel(self.iHSTChannel), "ok") + prop releaseHSTChannel :: ($1.iDelUser = "USER", $1.iDHLAvailable = 1, $1.notify = @_FXN_F_nop, $1.arg0 = 0, "ok") + prop AllocType :: (if (self.gNumOf > 0) {"1\0, _globalAllocDesc, _memSeg, _placement"} ) + prop _globalAllocDesc :: "%8t .dhl: {}" + prop _memSeg :: self.OBJMEMSEG + prop _placement :: (0x7fffffff / 2) + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gChannelsAvailable :: 0 + global OBJMEMSEG :: IRAM { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop MemberType :: MEM + prop MemberTest :: MEM.dataMember($1) + prop Label :: "Object Memory" + prop JSName :: "OBJMEMSEG" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iHSTChannel :: (scan ($i; HST) {if ($i.iDHLAvailable == 1) {$a = $i} }, $a) { + prop Type :: "{7BA2DA00-5A53-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Underlying HST Channel" + prop JSName :: "hstChannel" + prop MemberType :: HST + prop MemberTest :: (if (($1.iDHLAvailable == 1) || ($1 == self.iHSTChannel)) {1} else {0}) + prop Set :: (if ($1.iDHLAvailable != 1) {self.error("This channel is already in use.")} else {self.releaseHSTChannel(self.iHSTChannel), self.seizeHSTChannel($1), self.iHSTChannel = $1, "ok"}) + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } + inst iMode :: = self.iHSTChannel.mode { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Mode" + prop JSName :: "mode" + prop Visible :: 1 + prop Writable :: 0 + prop NoGen :: 0 + } + inst iDevId :: = (self.iHSTChannel.iId) { + prop NoGen :: 0 + } + inst iIsTerminal :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iIsVirtual :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iFxns :: @_DHL_FXNS { + prop NoGen :: 1 + } +} + +type DPI { + isa ObjectMgr + prop name :: "DPI" + prop Label :: "DPI - Pipe Driver" + prop IsContainedIn :: SIODRIVER + prop GlobalIcon :: 127 + prop InstanceIcon :: 128 + prop GlobalHelpTopic :: (304) + prop InstanceHelpTopic :: (404) + prop InstancePropertyPage :: ("{7FE06FA0-2DE9-11d1-988B-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{7FE06FA1-2DE9-11d1-988B-0020AFEE33C6}") + prop DependsOn :: "DEV" + prop maxObjs :: (32767) + prop isDriver :: (1) + prop localCreate :: (self.gCurDevId += 1, "ok") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gCurDevId :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDevId :: DPI.gCurDevId { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop Writable :: 0 + prop Set :: (self.error("DPI.iDevId parameter no longer settable, it is now handled automatically")) + } + inst iIsVirtual :: 0 { + prop Label :: "Allow virtual instances of this device." + prop JSName :: "allowVirtual" + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + prop Set :: (if ($1 == 1) {$a = "ok", $b = 1, scan ($i; SIO) {if ($i.iDevice == self) {$a = self.error("This DPI instance is being used by one or more SIO instances, cannot reconfigure"), $b = 0} }, if ($b == 1) {self.iIsVirtual = 1} , $a} else {self.iIsVirtual = 0, "ok"}) + } + inst iIsTerminal :: 1 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop NoGen :: 1 + } + inst iFxns :: @_DPI_FXNS { + prop NoGen :: 1 + } +} + +type MSGQ { + isa Module + prop Visible :: 1 + prop name :: "MSGQ" + prop Label :: "MSGQ - Message Queue Manager" + prop IsConfMod :: self.USEMSGQ + prop IsContainedIn :: IOF + prop DependsOn :: "GIO,SIO" + prop GlobalIcon :: 131 + prop InstanceIcon :: 132 + prop GlobalHelpTopic :: (323) + prop InstanceHelpTopic :: (423) + prop InstancePropertyPage :: ("{473C4A62-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalPropertyPage :: ("{473C4A63-B1A8-11d0-9885-0020AFEE33C6}") + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global USEMSGQ :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Enable MSGQ Manager" + prop JSName :: "ENABLEMSGQ" + prop Visible :: 1 + prop Writable :: 1 + prop NoGen :: 0 + } +} + +type HOOK { + isa ObjectMgr + prop name :: "HOOK" + prop Label :: "HOOK - Module Hook Manager" + prop IsContainedIn :: SYSTEM + prop DependsOn :: "SWI" + prop InstancePropertyPage :: ("{473C4A64-B1A8-11d0-9885-0020AFEE33C6}") + prop GlobalIcon :: 181 + prop InstanceIcon :: 182 + prop GlobalHelpTopic :: (318) + prop InstanceHelpTopic :: (418) + prop localCreate :: (if (self.gNumOf == 0) {HOOK_KNL.iIsUsed = 1, self.mkId(0)} , "ok") + prop localDelete :: (if (self.gNumOf == 2) {HOOK_KNL.iIsUsed = 0, self.rmId} , "ok") + prop maxObjs :: (32767) + prop SortByField :: "iPri" + prop SortGroups :: 1 + global gUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gSetOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gNumOf :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gDirty :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInitFlag :: 1 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global gInit :: = ($a = 0, $b = 0, scan ($i; self) {if ($i.IsConfObj()) {$a += 1, if (self.isFinite) {$b |= 1 << $i.iId} } }, self.gNumOf = $a, self.gSetOf = $b, if (self.gInitFlag == 0) {self.localInit()} , self.gInitFlag = 1) { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + global KNLID :: = (HOOK_KNL.Order - 1) { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + } + inst iComment :: if self.iDelUser == "USER" {""} else {self.iDelMsg} { + prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "comment" + prop JSName :: "comment" + prop Visible :: 1 + prop Writable :: if self.iDelUser == "USER" {1} else {0} + prop NoGen :: 1 + } + inst iIsUsed :: 0 { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iId :: 0 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop Style :: 0x01 + prop Visible :: 0 + prop Writable :: 1 + prop NoGen :: 1 + } + inst iDelUser :: "USER" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst iDelMsg :: "ok" { + prop Visible :: 0 + prop Writable :: 0 + prop NoGen :: 1 + } + inst initFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Initialization function" + prop JSName :: "initFxn" + prop Visible :: 1 + prop Writable :: 1 + } + inst createFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Create function" + prop JSName :: "createFxn" + prop Visible :: 1 + prop Writable :: self.iDelUser == "USER" + } + inst deleteFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Delete function" + prop JSName :: "deleteFxn" + prop Visible :: 1 + prop Writable :: self.iDelUser == "USER" + } + inst exitFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Exit function" + prop JSName :: "exitFxn" + prop Visible :: 1 + prop Writable :: self.iDelUser == "USER" + } + inst callSwitchFxn :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call switch function" + prop JSName :: "callSwitchFxn" + prop Visible :: 1 + prop Writable :: self.iDelUser == "USER" + } + inst switchFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Switch function" + prop JSName :: "switchFxn" + prop Visible :: 1 + prop Writable :: self.callSwitchFxn + } + inst callReadyFxn :: 0 { + prop Type :: "{21455EA0-B96A-11cf-9BFE-0000C0AC14C7}" + prop Label :: "Call ready function" + prop JSName :: "callReadyFxn" + prop Visible :: 1 + prop Writable :: self.iDelUser == "USER" + } + inst readyFxn :: @_FXN_F_nop { + prop Type :: "{7C434D00-1629-11d0-9BFE-0000C0AC14C7}" + prop Label :: "Ready function" + prop JSName :: "readyFxn" + prop Visible :: 1 + prop Writable :: self.callReadyFxn + } + inst Order :: 2 { + prop Type :: "{21455EA2-B96A-11cf-9BFE-0000C0AC14C7}" + prop JSName :: "order" + prop NoGen :: 1 + prop Writable :: 1 + } + inst iPri :: 0 { + prop Type :: "{A11FE980-C07A-11cf-9BFE-0000C0AC14C7}" + prop Visible :: 0 + prop NoGen :: 1 + } +} + +object HOOK_KNL :: HOOK { + param iComment :: "Used to support TSK function hooks (cannot be deleted)" + param iIsUsed :: 0 + param iId :: 0 + param iDelUser :: "HOOK" + param iDelMsg :: "This hook instance is used by TSK and cannot be deleted" + param initFxn :: @_FXN_F_nop + param createFxn :: @_FXN_F_nop + param deleteFxn :: @_FXN_F_nop + param exitFxn :: @_FXN_F_nop + param callSwitchFxn :: 0 + param switchFxn :: @_FXN_F_nop + param callReadyFxn :: 0 + param readyFxn :: @_FXN_F_nop + param Order :: 1 + param iPri :: 0 +} + +object SDRAM :: MEM { + param iComment :: "This object defines space for the DSP's off-chip memory" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param base :: -2147483648 + param len :: 16777216 + param iAllocHeap :: 1 + param iHeapSize :: 32768 + param iUserHeapId :: 0 + param iHeapId :: @segment_name + param iReqHeapCount :: 0 + param space :: "code/data" + param dynamicLoading :: 0 + param iIsModifiable :: 1 +} + +object IRAM :: MEM { + param iComment :: "Internal L2 memory" + param iIsUsed :: 1 + param iId :: 0 + param iDelUser :: "USER" + param iDelMsg :: "ok" + param base :: 0 + param len :: 1048576 + param iAllocHeap :: 1 + param iHeapSize :: 524288 + param iUserHeapId :: 0 + param iHeapId :: @segment_name + param iReqHeapCount :: 3 + param space :: "code/data" + param dynamicLoading :: 0 + param iIsModifiable :: 1 +} + diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.tcf b/src/pthread/platform/dspbios/pte_test/Configuration1.tcf new file mode 100644 index 000000000..ae4b3f66b --- /dev/null +++ b/src/pthread/platform/dspbios/pte_test/Configuration1.tcf @@ -0,0 +1,47 @@ +utils.loadPlatform("ti.platforms.dsk6416"); + +/* The following DSP/BIOS Features are enabled. */ +bios.enableMemoryHeaps(prog); +bios.enableRealTimeAnalysis(prog); +bios.enableRtdx(prog); +bios.enableTskManager(prog); + +bios.MEM.NOMEMORYHEAPS = 0; +bios.MEM.instance("SDRAM").createHeap = 1; +bios.MEM.BIOSOBJSEG = prog.get("SDRAM"); +bios.MEM.MALLOCSEG = prog.get("SDRAM"); +bios.MEM.instance("IRAM").createHeap = 1; +bios.MEM.BIOSOBJSEG = prog.get("IRAM"); +bios.MEM.MALLOCSEG = prog.get("IRAM"); +bios.TSK.STACKSEG = prog.get("IRAM"); +bios.CLK.CONFIGURETIMER = 1; +bios.CLK.CONFIGURETIMER = 1; +bios.CLK.HIRESTIME = 1; +bios.CLK.HIRESTIME = 1; +bios.CLK.CONFIGURETIMER = 0; +bios.CLK.TIMERSELECT = "Timer 1"; +bios.CLK.CONFIGURETIMER = 1; +bios.CLK.TIMERSELECT = "Timer 0"; +bios.CLK.CONFIGURETIMER = 0; +bios.CLK.HIRESTIME = 0; +bios.CLK.TIMERSELECT = "Timer 1"; +bios.CLK.HIRESTIME = 1; +bios.CLK.TIMERSELECT = "Timer 0"; +bios.RTDX.MODE = "Simulator"; +bios.CLK.HIRESTIME = 0; +bios.CLK.MICROSECONDS = 1.0000; +bios.CLK.MICROSECONDS = 10.0000; +bios.MEM.instance("IRAM").heapSize = 0x00080000; +bios.CLK.MICROSECONDS = 1.0000; +bios.CLK.MICROSECONDS = 10.0000; +bios.CLK.TIMERSELECT = "Timer 0"; +bios.CLK.HIRESTIME = 1; +bios.CLK.MICROSECONDS = 100.0000; +bios.CLK.MICROSECONDS = 10.0000; +bios.GBL.SPECIFYRTSLIB = 1; +bios.GBL.RTSLIB = "rts6400_eh"; +bios.GBL.RTSLIB = "rts6400_eh.lib"; +// !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT! + +prog.gen(); + diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.tco b/src/pthread/platform/dspbios/pte_test/Configuration1.tco new file mode 100644 index 000000000..6ef8fc6e8 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_test/Configuration1.tco @@ -0,0 +1,6 @@ +# GENERATED FILE -- DO NOT EDIT! +# This file contains tconf options for file "Configuration1.tcf", +# for use by the Gconf graphical configuration tool. +# The options are exported from the following CCS project: +# Z:\PTHREAD\PLATFORM\DSPBIOS\PTE_TEST\pte_test.pjt, "C" configuration. +-Dconfig.importPath="C:\CCStudio_v3.3/bios_5_31_02/packages;" diff --git a/src/pthread/platform/dspbios/pte_test/pte_test.pjt b/src/pthread/platform/dspbios/pte_test/pte_test.pjt new file mode 100644 index 000000000..fff0f3357 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_test/pte_test.pjt @@ -0,0 +1,188 @@ +; Code Composer Project File, Version 2.0 (do not modify or remove this line) + +[Project Settings] +ProjectDir="Z:\pthread\platform\dspbios\pte_test\" +ProjectType=Executable +CPUFamily=TMS320C64XX +Tool="Compiler" +Tool="CustomBuilder" +Tool="DspBiosBuilder" +Tool="Linker" +Config="C" +Config="CPP" + +[Source Files] +Source="..\..\..\tests\barrier1.c" +Source="..\..\..\tests\barrier2.c" +Source="..\..\..\tests\barrier3.c" +Source="..\..\..\tests\barrier4.c" +Source="..\..\..\tests\barrier5.c" +Source="..\..\..\tests\benchlib.c" +Source="..\..\..\tests\benchtest1.c" +Source="..\..\..\tests\benchtest2.c" +Source="..\..\..\tests\benchtest3.c" +Source="..\..\..\tests\benchtest4.c" +Source="..\..\..\tests\cancel1.c" +Source="..\..\..\tests\cancel2.c" +Source="..\..\..\tests\cancel3.c" +Source="..\..\..\tests\cancel4.c" +Source="..\..\..\tests\cancel5.c" +Source="..\..\..\tests\cancel6a.c" +Source="..\..\..\tests\cancel6d.c" +Source="..\..\..\tests\cleanup0.c" +Source="..\..\..\tests\cleanup1.c" +Source="..\..\..\tests\cleanup2.c" +Source="..\..\..\tests\cleanup3.c" +Source="..\..\..\tests\condvar1.c" +Source="..\..\..\tests\condvar1_1.c" +Source="..\..\..\tests\condvar1_2.c" +Source="..\..\..\tests\condvar2.c" +Source="..\..\..\tests\condvar2_1.c" +Source="..\..\..\tests\condvar3.c" +Source="..\..\..\tests\condvar3_1.c" +Source="..\..\..\tests\condvar3_2.c" +Source="..\..\..\tests\condvar3_3.c" +Source="..\..\..\tests\condvar4.c" +Source="..\..\..\tests\condvar5.c" +Source="..\..\..\tests\condvar6.c" +Source="..\..\..\tests\condvar7.c" +Source="..\..\..\tests\condvar8.c" +Source="..\..\..\tests\condvar9.c" +Source="..\..\..\tests\count1.c" +Source="..\..\..\tests\create1.c" +Source="..\..\..\tests\create2.c" +Source="..\..\..\tests\create3.c" +Source="..\..\..\tests\delay1.c" +Source="..\..\..\tests\delay2.c" +Source="..\..\..\tests\detach1.c" +Source="..\..\..\tests\equal1.c" +Source="..\..\..\tests\errno1.c" +Source="..\..\..\tests\exception1.c" +Source="..\..\..\tests\exception2.c" +Source="..\..\..\tests\exception3.c" +Source="..\..\..\tests\exit1.c" +Source="..\..\..\tests\exit2.c" +Source="..\..\..\tests\exit3.c" +Source="..\..\..\tests\exit4.c" +Source="..\..\..\tests\exit5.c" +Source="..\..\..\tests\inherit1.c" +Source="..\..\..\tests\join0.c" +Source="..\..\..\tests\join1.c" +Source="..\..\..\tests\join2.c" +Source="..\..\..\tests\join3.c" +Source="..\..\..\tests\join4.c" +Source="..\..\..\tests\kill1.c" +Source="..\..\..\tests\mutex1.c" +Source="..\..\..\tests\mutex1e.c" +Source="..\..\..\tests\mutex1n.c" +Source="..\..\..\tests\mutex1r.c" +Source="..\..\..\tests\mutex2.c" +Source="..\..\..\tests\mutex2e.c" +Source="..\..\..\tests\mutex2r.c" +Source="..\..\..\tests\mutex3.c" +Source="..\..\..\tests\mutex3e.c" +Source="..\..\..\tests\mutex3r.c" +Source="..\..\..\tests\mutex4.c" +Source="..\..\..\tests\mutex5.c" +Source="..\..\..\tests\mutex6.c" +Source="..\..\..\tests\mutex6e.c" +Source="..\..\..\tests\mutex6es.c" +Source="..\..\..\tests\mutex6n.c" +Source="..\..\..\tests\mutex6r.c" +Source="..\..\..\tests\mutex6rs.c" +Source="..\..\..\tests\mutex6s.c" +Source="..\..\..\tests\mutex7.c" +Source="..\..\..\tests\mutex7e.c" +Source="..\..\..\tests\mutex7n.c" +Source="..\..\..\tests\mutex7r.c" +Source="..\..\..\tests\mutex8.c" +Source="..\..\..\tests\mutex8e.c" +Source="..\..\..\tests\mutex8n.c" +Source="..\..\..\tests\mutex8r.c" +Source="..\..\..\tests\once1.c" +Source="..\..\..\tests\once2.c" +Source="..\..\..\tests\once3.c" +Source="..\..\..\tests\once4.c" +Source="..\..\..\tests\priority1.c" +Source="..\..\..\tests\priority2.c" +Source="..\..\..\tests\reuse1.c" +Source="..\..\..\tests\reuse2.c" +Source="..\..\..\tests\rwlock1.c" +Source="..\..\..\tests\rwlock2.c" +Source="..\..\..\tests\rwlock2_t.c" +Source="..\..\..\tests\rwlock3.c" +Source="..\..\..\tests\rwlock3_t.c" +Source="..\..\..\tests\rwlock4.c" +Source="..\..\..\tests\rwlock4_t.c" +Source="..\..\..\tests\rwlock5.c" +Source="..\..\..\tests\rwlock5_t.c" +Source="..\..\..\tests\rwlock6.c" +Source="..\..\..\tests\rwlock6_t.c" +Source="..\..\..\tests\rwlock6_t2.c" +Source="..\..\..\tests\rwlock7.c" +Source="..\..\..\tests\rwlock8.c" +Source="..\..\..\tests\self1.c" +Source="..\..\..\tests\self2.c" +Source="..\..\..\tests\semaphore1.c" +Source="..\..\..\tests\semaphore2.c" +Source="..\..\..\tests\semaphore3.c" +Source="..\..\..\tests\semaphore4.c" +Source="..\..\..\tests\semaphore4t.c" +Source="..\..\..\tests\semaphore5.c" +Source="..\..\..\tests\semaphore6.c" +Source="..\..\..\tests\spin1.c" +Source="..\..\..\tests\spin2.c" +Source="..\..\..\tests\spin3.c" +Source="..\..\..\tests\spin4.c" +Source="..\..\..\tests\stress1.c" +Source="..\..\..\tests\test_main.c" +Source="..\..\..\tests\tsd1.c" +Source="..\..\..\tests\tsd2.c" +Source="..\..\..\tests\valid1.c" +Source="..\..\..\tests\valid2.c" +Source="..\..\helper\tls-helper.c" +Source="..\dspbios-osal.c" +Source="..\main.c" +Source="Configuration1.tcf" +Source="Configuration1cfg.cmd" + +[Generated Files] +Source="Configuration1cfg.s62" +Source="Configuration1cfg_c.c" + +["Compiler" Settings: "C"] +Options=-g -fr"$(Proj_dir)\C" -i"..\platform\dspbios" -i".." -i"..\.." -i"." -i"..\dspbios" -i"..\helper" -d"_DEBUG" -mv6400 + +["Compiler" Settings: "CPP"] +Options=-g -fg -fr"$(Proj_dir)\CPP" -i"..\platform\dspbios" -i".." -i"..\.." -i"." -i"..\dspbios" -i"..\helper" -d"_DEBUG" -mv6400 --exceptions + +["DspBiosBuilder" Settings: "C"] +Options=-Dconfig.importPath="$(Install_dir)/bios_5_31_02/packages;" + +["DspBiosBuilder" Settings: "CPP"] +Options=-Dconfig.importPath="$(Install_dir)/bios_5_31_02/packages;" + +["Linker" Settings: "C"] +Options=-c -m".\C\pte_test.map" -o".\C\pte_test.out" -w -x -i"..\pte_lib\C" -l"pte_lib.lib" + +["Linker" Settings: "CPP"] +Options=-c -m".\CPP\pte_test.map" -o".\CPP\pte_test.out" -w -x -i"..\pte_lib\CPP" -l"pte_lib.lib" + +["..\..\..\tests\exception2.c" Settings: "CPP"] +Options="Compiler" +{-fg --exceptions} + +["..\..\..\tests\exception3.c" Settings: "CPP"] +Options="Compiler" +{-fg --exceptions} + +["..\..\..\tests\test_main.c" Settings: "CPP"] +Options="Compiler" +{-fg} + +["..\main.c" Settings: "CPP"] +Options="Compiler" +{-fg} + +["Configuration1cfg.cmd" Settings: "C"] +LinkOrder=1 + +["Configuration1cfg.cmd" Settings: "CPP"] +LinkOrder=1 + diff --git a/src/pthread/platform/dspbios/pte_types.h b/src/pthread/platform/dspbios/pte_types.h new file mode 100644 index 000000000..6f1260982 --- /dev/null +++ b/src/pthread/platform/dspbios/pte_types.h @@ -0,0 +1,27 @@ +/* pte_types.h */ + +#ifndef PTE_TYPES_H +#define PTE_TYPES_H + +#include + +typedef int pid_t; + +struct timespec +{ + time_t tv_sec; + long tv_nsec; +}; + +typedef unsigned int mode_t; + + +struct timeb +{ + time_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; + +#endif /* PTE_TYPES_H */ diff --git a/src/pthread/platform/helper/tls-helper.c b/src/pthread/platform/helper/tls-helper.c new file mode 100644 index 000000000..5a3b1d502 --- /dev/null +++ b/src/pthread/platform/helper/tls-helper.c @@ -0,0 +1,185 @@ +/* + * tls-helper.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "tls-helper.h" + +static int *keysUsed; + +/* We don't protect this - it's only written on startup */ +static int maxTlsValues; + +pte_osMutexHandle globalTlsLock; + +pte_osResult pteTlsGlobalInit(int maxEntries) +{ + int i; + pte_osResult result; + + pte_osMutexCreate(&globalTlsLock); + + keysUsed = (int *) malloc(maxEntries * sizeof(int)); + + if (keysUsed != NULL) + { + for (i=0;i +#include +#include +#include +#include +#include + + +PSP_MODULE_INFO("Pthread Test", 0, 1, 1); + +extern void pte_test_main(); + +#ifdef JNS +#define printf pspDebugScreenPrintf +#endif + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + + + +int main() +{ + SceCtrlData pad; + + pspDebugScreenInit(); + SetupCallbacks(); + + pte_test_main(); + + while (1) + { + sceCtrlReadBufferPositive(&pad, 1); + if (pad.Buttons & PSP_CTRL_UP) + { + printf("Exiting...\n"); + return 0; + } + + } + return 0; +} + + diff --git a/src/pthread/platform/nautilus/nautilus_osal.c b/src/pthread/platform/nautilus/nautilus_osal.c new file mode 100644 index 000000000..a3887a609 --- /dev/null +++ b/src/pthread/platform/nautilus/nautilus_osal.c @@ -0,0 +1 @@ +/* * psp_osal.c * * Description: * * -------------------------------------------------------------------------- * * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems * Copyright(C) 2008 Jason Schmidlapp * * Contact Email: jschmidlapp@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "pte_osal.h" #include "pthread.h" #include "tls-helper.h" /* For ftime */ #include #include #include #define MAX_PSP_UID 2048 // SWAG #define DEFAULT_STACK_SIZE_BYTES 4096 #define PSP_MAX_TLS 32 #if 1 #define PSP_DEBUG(x) printf(x) #else #define PSP_DEBUG(x) #endif /* TLS key used to access pspThreadData struct for reach thread. */ static unsigned int threadDataKey; /* * Data stored on a per-thread basis - allocated in pte_osThreadCreate * and freed in pte_osThreadDelete. */ typedef struct pspThreadData { /* Entry point and parameters to thread's main function */ pte_osThreadEntryPoint entryPoint; void * argv; /* Semaphore used for cancellation. Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */ SceUID cancelSem; } pspThreadData; /* Structure used to emulate TLS on non-POSIX threads. * This limits us to one non-POSIX thread that can * call pthread functions. */ static void *globalTls; /* Helper functions */ static pspThreadData *getThreadData(SceUID threadHandle); static void *getTlsStructFromThread(SceUID thid); /* A new thread's stub entry point. It retrieves the real entry point from the per thread control * data as well as any parameters to this function, and then calls the entry point. */ int pspStubThreadEntry (unsigned int argc, void *argv) { int result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); result = (*(pThreadData->entryPoint))(pThreadData->argv); return result; } /**************************************************************************** * * Initialization * ***************************************************************************/ pte_osResult pte_osInit(void) { pte_osResult result; pspThreadData *pThreadData; char cancelSemName[64]; /* Allocate and initialize TLS support */ result = pteTlsGlobalInit(PSP_MAX_TLS); if (result == PTE_OS_OK) { /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */ result = pteTlsAlloc(&threadDataKey); if (result == PTE_OS_OK) { /* Initialize the structure used to emulate TLS for * non-POSIX threads */ globalTls = pteTlsThreadInit(); /* Also create a "thread data" structure for a single non-POSIX thread. */ /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { result = PTE_OS_NO_RESOURCES; } else { /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(globalTls, threadDataKey, pThreadData); /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSemGlobal"); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ result = PTE_OS_OK; } } } return result; } /**************************************************************************** * * Threads * ***************************************************************************/ pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle) { char threadName[64]; char cancelSemName[64]; static int threadNum = 1; int pspAttr; void *pTls; SceUID threadId; pte_osResult result; pspThreadData *pThreadData; if (threadNum++ > MAX_PSP_UID) { threadNum = 0; } /* Make sure that the stack we're going to allocate is big enough */ if (stackSize < DEFAULT_STACK_SIZE_BYTES) { stackSize = DEFAULT_STACK_SIZE_BYTES; } /* Allocate TLS structure for this thread. */ pTls = pteTlsThreadInit(); if (pTls == NULL) { PSP_DEBUG("pteTlsThreadInit: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { pteTlsThreadDestroy(pTls); PSP_DEBUG("malloc(pspThreadData): PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(pTls, threadDataKey, pThreadData); pThreadData->entryPoint = entryPoint; pThreadData->argv = argv; /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSem%04d", threadNum); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ /* In order to emulate TLS functionality, we append the address of the TLS structure that we * allocated above to the thread's name. To set or get TLS values for this thread, the user * needs to get the name of the thread from the OS and then parse the name to extract * a pointer to the TLS structure. */ snprintf(threadName, sizeof(threadName), "pthread%04d__%x", threadNum, (unsigned int) pTls); pspAttr = 0; // printf("%s %p %d %d %d\n",threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr); threadId = sceKernelCreateThread(threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr, NULL); if (threadId == (SceUID) SCE_KERNEL_ERROR_NO_MEMORY) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; } else if (threadId < 0) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_GENERAL_FAILURE\n"); result = PTE_OS_GENERAL_FAILURE; } else { *ppte_osThreadHandle = threadId; result = PTE_OS_OK; } FAIL0: return result; } pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle) { sceKernelStartThread(osThreadHandle, 0, NULL); return PTE_OS_OK; } pte_osResult pte_osThreadDelete(pte_osThreadHandle handle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(handle); pThreadData = getThreadData(handle); sceKernelDeleteSema(pThreadData->cancelSem); free(pThreadData); pteTlsThreadDestroy(pTls); sceKernelDeleteThread(handle); return PTE_OS_OK; } pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle) { pte_osThreadDelete(handle); sceKernelExitDeleteThread(0); return PTE_OS_OK; } void pte_osThreadExit() { sceKernelExitThread(0); } /* * This has to be cancellable, so we can't just call sceKernelWaitThreadEnd. * Instead, poll on this in a loop, like we do for a cancellable semaphore. */ pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle) { pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); while (1) { SceKernelThreadRunStatus info; /* Poll task to see if it has ended */ memset(&info,0,sizeof(info)); info.size = sizeof(info); sceKernelReferThreadRunStatus(threadHandle, &info); if (info.status == PSP_THREAD_STOPPED) { /* Thread has ended */ result = PTE_OS_OK; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } pte_osThreadHandle pte_osThreadGetHandle(void) { return sceKernelGetThreadId(); } int pte_osThreadGetPriority(pte_osThreadHandle threadHandle) { SceKernelThreadInfo thinfo; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(threadHandle, &thinfo); return thinfo.currentPriority; } pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority) { sceKernelChangeThreadPriority(threadHandle, newPriority); return PTE_OS_OK; } pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle) { SceUID osResult; pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(threadHandle); osResult = sceKernelSignalSema(pThreadData->cancelSem, 1); if (osResult == SCE_KERNEL_ERROR_OK) { result = PTE_OS_OK; } else { result = PTE_OS_GENERAL_FAILURE; } return result; } pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle) { pspThreadData *pThreadData; SceKernelSemaInfo semInfo; SceUID osResult; pte_osResult result; pThreadData = getThreadData(threadHandle); if (pThreadData != NULL) { osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; } else { result = PTE_OS_OK; } } else { /* sceKernelReferSemaStatus returned an error */ result = PTE_OS_GENERAL_FAILURE; } } else { /* For some reason, we couldn't get thread data */ result = PTE_OS_GENERAL_FAILURE; } return result; } void pte_osThreadSleep(unsigned int msecs) { sceKernelDelayThread(msecs*1000); } int pte_osThreadGetMinPriority() { return 17; } int pte_osThreadGetMaxPriority() { return 30; } int pte_osThreadGetDefaultPriority() { return 18; } /**************************************************************************** * * Mutexes * ****************************************************************************/ pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle) { static int mutexCtr = 0; char mutexName[32]; pte_osMutexHandle handle; if (mutexCtr++ > MAX_PSP_UID) { mutexCtr = 0; } snprintf(mutexName,sizeof(mutexName),"mutex%d",mutexCtr); handle = sceKernelCreateSema(mutexName, 0, /* attributes (default) */ 1, /* initial value */ 1, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osMutexDelete(pte_osMutexHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osMutexLock(pte_osMutexHandle handle) { sceKernelWaitSema(handle, 1, NULL); return PTE_OS_OK; } pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs) { pte_osResult result; SceUInt timeoutUsecs = timeoutMsecs*1000; int status = sceKernelWaitSema(handle, 1, &timeoutUsecs); if (status < 0) { // Assume that any error from sceKernelWaitSema was due to a timeout result = PTE_OS_TIMEOUT; } else { result = PTE_OS_OK; } return result; } pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) { sceKernelSignalSema(handle, 1); return PTE_OS_OK; } /**************************************************************************** * * Semaphores * ***************************************************************************/ pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle) { pte_osSemaphoreHandle handle; static int semCtr = 0; char semName[32]; if (semCtr++ > MAX_PSP_UID) { semCtr = 0; } snprintf(semName,sizeof(semName),"pthread_sem%d",semCtr); handle = sceKernelCreateSema(semName, 0, /* attributes (default) */ initialValue, /* initial value */ SEM_VALUE_MAX, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count) { sceKernelSignalSema(handle, count); return PTE_OS_OK; } pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs) { unsigned int timeoutUsecs; unsigned int *pTimeoutUsecs; SceUInt result; pte_osResult osResult; if (pTimeoutMsecs == NULL) { pTimeoutUsecs = NULL; } else { timeoutUsecs = *pTimeoutMsecs * 1000; pTimeoutUsecs = &timeoutUsecs; } result = sceKernelWaitSema(handle, 1, pTimeoutUsecs); if (result == SCE_KERNEL_ERROR_OK) { osResult = PTE_OS_OK; } else if (result == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { osResult = PTE_OS_TIMEOUT; } else { osResult = PTE_OS_GENERAL_FAILURE; } return osResult; } /* * Pend on a semaphore- and allow the pend to be cancelled. * * PSP OS provides no functionality to asynchronously interrupt a blocked call. We simulte * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout) { pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); clock_t start_time; pte_osResult result = PTE_OS_OK; unsigned int timeout; unsigned char timeoutEnabled; start_time = clock(); // clock() is in microseconds, timeout as passed in was in milliseconds if (pTimeout == NULL) { timeout = 0; timeoutEnabled = 0; } else { timeout = *pTimeout * 1000; timeoutEnabled = 1; } while (1) { SceUInt semTimeout; int status; /* Poll semaphore */ semTimeout = 0; status = sceKernelWaitSema(semHandle, 1, &semTimeout); if (status == SCE_KERNEL_ERROR_OK) { /* User semaphore posted to */ result = PTE_OS_OK; break; } else if ((timeoutEnabled) && ((clock() - start_time) > timeout)) { /* Timeout expired */ result = PTE_OS_TIMEOUT; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } /**************************************************************************** * * Atomic Operations * ***************************************************************************/ int pte_osAtomicExchange(int *ptarg, int val) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *ptarg; *ptarg = val; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *pdest; if (*pdest == comp) { *pdest = exchange; } pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicExchangeAdd(int volatile* pAddend, int value) { int origVal; int intc = pspSdkDisableInterrupts(); origVal = *pAddend; *pAddend += value; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicDecrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)--; val = *pdest; pspSdkEnableInterrupts(intc); return val; } int pte_osAtomicIncrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)++; val = *pdest; pspSdkEnableInterrupts(intc); return val; } /**************************************************************************** * * Helper functions * ***************************************************************************/ static pspThreadData *getThreadData(SceUID threadHandle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(threadHandle); pThreadData = (pspThreadData *) pteTlsGetValue(pTls, threadDataKey); return pThreadData; } static void *getTlsStructFromThread(SceUID thid) { SceKernelThreadInfo thinfo; unsigned int ptr; unsigned int thrNum; void *pTls; int numMatches; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(thid, &thinfo); numMatches = sscanf(thinfo.name,"pthread%04d__%x", &thrNum, &ptr); /* If we were called from a pthread, use the TLS allocated when the thread * was created. Otherwise, we were called from a non-pthread, so use the * "global". This is a pretty bad hack, but necessary due to lack of TLS on PSP. */ if (numMatches == 2) { pTls = (void *) ptr; } else { pTls = globalTls; } return pTls; } /**************************************************************************** * * Thread Local Storage * ***************************************************************************/ pte_osResult pte_osTlsSetValue(unsigned int key, void * value) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsSetValue(pTls, key, value); } void * pte_osTlsGetValue(unsigned int index) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return (void *) pteTlsGetValue(pTls, index); } pte_osResult pte_osTlsAlloc(unsigned int *pKey) { void * pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsAlloc(pKey); } pte_osResult pte_osTlsFree(unsigned int index) { return pteTlsFree(index); } /**************************************************************************** * * Miscellaneous * ***************************************************************************/ int ftime(struct timeb *tb) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); tb->time = tv.tv_sec; tb->millitm = tv.tv_usec / 1000; tb->timezone = tz.tz_minuteswest; tb->dstflag = tz.tz_dsttime; return 0; } \ No newline at end of file diff --git a/src/pthread/platform/nautilus/nautilus_osal.h b/src/pthread/platform/nautilus/nautilus_osal.h new file mode 100644 index 000000000..d92e20b31 --- /dev/null +++ b/src/pthread/platform/nautilus/nautilus_osal.h @@ -0,0 +1,63 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include + +typedef nk_thread_id_t pte_osThreadHandle; + +typedef struct nk_semaphore *pte_osSemaphoreHandle; + +typedef spinlock_t *pte_osMutexHandle; + + +#define OS_IS_HANDLE_VALID(x) ((x) > 0) + + + + +#define OS_MAX_SIMUL_THREADS 1000 + +#define OS_DEFAULT_PRIO 11 + +#define OS_MIN_PRIO 17 +#define OS_MAX_PRIO 32 + +//#define HAVE_THREAD_SAFE_ERRNO + +#define POLLING_DELAY_IN_us 100 + + + +#define OS_MAX_SEM_VALUE 254 + + + + diff --git a/src/pthread/platform/nautilus/nautilus_osal.h~ b/src/pthread/platform/nautilus/nautilus_osal.h~ new file mode 100644 index 000000000..33528ddba --- /dev/null +++ b/src/pthread/platform/nautilus/nautilus_osal.h~ @@ -0,0 +1,66 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +typedef SceUID pte_osThreadHandle; + +typedef SceUID pte_osSemaphoreHandle; + +typedef SceUID pte_osMutexHandle; + + +#define OS_IS_HANDLE_VALID(x) ((x) > 0) + + + + +#define OS_MAX_SIMUL_THREADS 10 + +#define OS_DEFAULT_PRIO 11 + +#define OS_MIN_PRIO 17 +#define OS_MAX_PRIO 32 + +//#define HAVE_THREAD_SAFE_ERRNO + +#define POLLING_DELAY_IN_us 100 + + + +#define OS_MAX_SEM_VALUE 254 + +int PspInterlockedExchange(int *ptarg, int val); +int PspInterlockedCompareExchange(int *pdest, int exchange, int comp); +int PspInterlockedExchangeAdd(int volatile* pAddend, int value); +int PspInterlockedDecrement(int *pdest); +int PspInterlockedIncrement(int *pdest); + + + + diff --git a/src/pthread/platform/nautilus/psp_osal.c b/src/pthread/platform/nautilus/psp_osal.c new file mode 100644 index 000000000..a3887a609 --- /dev/null +++ b/src/pthread/platform/nautilus/psp_osal.c @@ -0,0 +1 @@ +/* * psp_osal.c * * Description: * * -------------------------------------------------------------------------- * * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems * Copyright(C) 2008 Jason Schmidlapp * * Contact Email: jschmidlapp@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "pte_osal.h" #include "pthread.h" #include "tls-helper.h" /* For ftime */ #include #include #include #define MAX_PSP_UID 2048 // SWAG #define DEFAULT_STACK_SIZE_BYTES 4096 #define PSP_MAX_TLS 32 #if 1 #define PSP_DEBUG(x) printf(x) #else #define PSP_DEBUG(x) #endif /* TLS key used to access pspThreadData struct for reach thread. */ static unsigned int threadDataKey; /* * Data stored on a per-thread basis - allocated in pte_osThreadCreate * and freed in pte_osThreadDelete. */ typedef struct pspThreadData { /* Entry point and parameters to thread's main function */ pte_osThreadEntryPoint entryPoint; void * argv; /* Semaphore used for cancellation. Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */ SceUID cancelSem; } pspThreadData; /* Structure used to emulate TLS on non-POSIX threads. * This limits us to one non-POSIX thread that can * call pthread functions. */ static void *globalTls; /* Helper functions */ static pspThreadData *getThreadData(SceUID threadHandle); static void *getTlsStructFromThread(SceUID thid); /* A new thread's stub entry point. It retrieves the real entry point from the per thread control * data as well as any parameters to this function, and then calls the entry point. */ int pspStubThreadEntry (unsigned int argc, void *argv) { int result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); result = (*(pThreadData->entryPoint))(pThreadData->argv); return result; } /**************************************************************************** * * Initialization * ***************************************************************************/ pte_osResult pte_osInit(void) { pte_osResult result; pspThreadData *pThreadData; char cancelSemName[64]; /* Allocate and initialize TLS support */ result = pteTlsGlobalInit(PSP_MAX_TLS); if (result == PTE_OS_OK) { /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */ result = pteTlsAlloc(&threadDataKey); if (result == PTE_OS_OK) { /* Initialize the structure used to emulate TLS for * non-POSIX threads */ globalTls = pteTlsThreadInit(); /* Also create a "thread data" structure for a single non-POSIX thread. */ /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { result = PTE_OS_NO_RESOURCES; } else { /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(globalTls, threadDataKey, pThreadData); /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSemGlobal"); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ result = PTE_OS_OK; } } } return result; } /**************************************************************************** * * Threads * ***************************************************************************/ pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle) { char threadName[64]; char cancelSemName[64]; static int threadNum = 1; int pspAttr; void *pTls; SceUID threadId; pte_osResult result; pspThreadData *pThreadData; if (threadNum++ > MAX_PSP_UID) { threadNum = 0; } /* Make sure that the stack we're going to allocate is big enough */ if (stackSize < DEFAULT_STACK_SIZE_BYTES) { stackSize = DEFAULT_STACK_SIZE_BYTES; } /* Allocate TLS structure for this thread. */ pTls = pteTlsThreadInit(); if (pTls == NULL) { PSP_DEBUG("pteTlsThreadInit: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { pteTlsThreadDestroy(pTls); PSP_DEBUG("malloc(pspThreadData): PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(pTls, threadDataKey, pThreadData); pThreadData->entryPoint = entryPoint; pThreadData->argv = argv; /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSem%04d", threadNum); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ /* In order to emulate TLS functionality, we append the address of the TLS structure that we * allocated above to the thread's name. To set or get TLS values for this thread, the user * needs to get the name of the thread from the OS and then parse the name to extract * a pointer to the TLS structure. */ snprintf(threadName, sizeof(threadName), "pthread%04d__%x", threadNum, (unsigned int) pTls); pspAttr = 0; // printf("%s %p %d %d %d\n",threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr); threadId = sceKernelCreateThread(threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr, NULL); if (threadId == (SceUID) SCE_KERNEL_ERROR_NO_MEMORY) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; } else if (threadId < 0) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_GENERAL_FAILURE\n"); result = PTE_OS_GENERAL_FAILURE; } else { *ppte_osThreadHandle = threadId; result = PTE_OS_OK; } FAIL0: return result; } pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle) { sceKernelStartThread(osThreadHandle, 0, NULL); return PTE_OS_OK; } pte_osResult pte_osThreadDelete(pte_osThreadHandle handle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(handle); pThreadData = getThreadData(handle); sceKernelDeleteSema(pThreadData->cancelSem); free(pThreadData); pteTlsThreadDestroy(pTls); sceKernelDeleteThread(handle); return PTE_OS_OK; } pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle) { pte_osThreadDelete(handle); sceKernelExitDeleteThread(0); return PTE_OS_OK; } void pte_osThreadExit() { sceKernelExitThread(0); } /* * This has to be cancellable, so we can't just call sceKernelWaitThreadEnd. * Instead, poll on this in a loop, like we do for a cancellable semaphore. */ pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle) { pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); while (1) { SceKernelThreadRunStatus info; /* Poll task to see if it has ended */ memset(&info,0,sizeof(info)); info.size = sizeof(info); sceKernelReferThreadRunStatus(threadHandle, &info); if (info.status == PSP_THREAD_STOPPED) { /* Thread has ended */ result = PTE_OS_OK; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } pte_osThreadHandle pte_osThreadGetHandle(void) { return sceKernelGetThreadId(); } int pte_osThreadGetPriority(pte_osThreadHandle threadHandle) { SceKernelThreadInfo thinfo; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(threadHandle, &thinfo); return thinfo.currentPriority; } pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority) { sceKernelChangeThreadPriority(threadHandle, newPriority); return PTE_OS_OK; } pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle) { SceUID osResult; pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(threadHandle); osResult = sceKernelSignalSema(pThreadData->cancelSem, 1); if (osResult == SCE_KERNEL_ERROR_OK) { result = PTE_OS_OK; } else { result = PTE_OS_GENERAL_FAILURE; } return result; } pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle) { pspThreadData *pThreadData; SceKernelSemaInfo semInfo; SceUID osResult; pte_osResult result; pThreadData = getThreadData(threadHandle); if (pThreadData != NULL) { osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; } else { result = PTE_OS_OK; } } else { /* sceKernelReferSemaStatus returned an error */ result = PTE_OS_GENERAL_FAILURE; } } else { /* For some reason, we couldn't get thread data */ result = PTE_OS_GENERAL_FAILURE; } return result; } void pte_osThreadSleep(unsigned int msecs) { sceKernelDelayThread(msecs*1000); } int pte_osThreadGetMinPriority() { return 17; } int pte_osThreadGetMaxPriority() { return 30; } int pte_osThreadGetDefaultPriority() { return 18; } /**************************************************************************** * * Mutexes * ****************************************************************************/ pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle) { static int mutexCtr = 0; char mutexName[32]; pte_osMutexHandle handle; if (mutexCtr++ > MAX_PSP_UID) { mutexCtr = 0; } snprintf(mutexName,sizeof(mutexName),"mutex%d",mutexCtr); handle = sceKernelCreateSema(mutexName, 0, /* attributes (default) */ 1, /* initial value */ 1, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osMutexDelete(pte_osMutexHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osMutexLock(pte_osMutexHandle handle) { sceKernelWaitSema(handle, 1, NULL); return PTE_OS_OK; } pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs) { pte_osResult result; SceUInt timeoutUsecs = timeoutMsecs*1000; int status = sceKernelWaitSema(handle, 1, &timeoutUsecs); if (status < 0) { // Assume that any error from sceKernelWaitSema was due to a timeout result = PTE_OS_TIMEOUT; } else { result = PTE_OS_OK; } return result; } pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) { sceKernelSignalSema(handle, 1); return PTE_OS_OK; } /**************************************************************************** * * Semaphores * ***************************************************************************/ pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle) { pte_osSemaphoreHandle handle; static int semCtr = 0; char semName[32]; if (semCtr++ > MAX_PSP_UID) { semCtr = 0; } snprintf(semName,sizeof(semName),"pthread_sem%d",semCtr); handle = sceKernelCreateSema(semName, 0, /* attributes (default) */ initialValue, /* initial value */ SEM_VALUE_MAX, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count) { sceKernelSignalSema(handle, count); return PTE_OS_OK; } pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs) { unsigned int timeoutUsecs; unsigned int *pTimeoutUsecs; SceUInt result; pte_osResult osResult; if (pTimeoutMsecs == NULL) { pTimeoutUsecs = NULL; } else { timeoutUsecs = *pTimeoutMsecs * 1000; pTimeoutUsecs = &timeoutUsecs; } result = sceKernelWaitSema(handle, 1, pTimeoutUsecs); if (result == SCE_KERNEL_ERROR_OK) { osResult = PTE_OS_OK; } else if (result == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { osResult = PTE_OS_TIMEOUT; } else { osResult = PTE_OS_GENERAL_FAILURE; } return osResult; } /* * Pend on a semaphore- and allow the pend to be cancelled. * * PSP OS provides no functionality to asynchronously interrupt a blocked call. We simulte * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout) { pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); clock_t start_time; pte_osResult result = PTE_OS_OK; unsigned int timeout; unsigned char timeoutEnabled; start_time = clock(); // clock() is in microseconds, timeout as passed in was in milliseconds if (pTimeout == NULL) { timeout = 0; timeoutEnabled = 0; } else { timeout = *pTimeout * 1000; timeoutEnabled = 1; } while (1) { SceUInt semTimeout; int status; /* Poll semaphore */ semTimeout = 0; status = sceKernelWaitSema(semHandle, 1, &semTimeout); if (status == SCE_KERNEL_ERROR_OK) { /* User semaphore posted to */ result = PTE_OS_OK; break; } else if ((timeoutEnabled) && ((clock() - start_time) > timeout)) { /* Timeout expired */ result = PTE_OS_TIMEOUT; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } /**************************************************************************** * * Atomic Operations * ***************************************************************************/ int pte_osAtomicExchange(int *ptarg, int val) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *ptarg; *ptarg = val; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *pdest; if (*pdest == comp) { *pdest = exchange; } pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicExchangeAdd(int volatile* pAddend, int value) { int origVal; int intc = pspSdkDisableInterrupts(); origVal = *pAddend; *pAddend += value; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicDecrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)--; val = *pdest; pspSdkEnableInterrupts(intc); return val; } int pte_osAtomicIncrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)++; val = *pdest; pspSdkEnableInterrupts(intc); return val; } /**************************************************************************** * * Helper functions * ***************************************************************************/ static pspThreadData *getThreadData(SceUID threadHandle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(threadHandle); pThreadData = (pspThreadData *) pteTlsGetValue(pTls, threadDataKey); return pThreadData; } static void *getTlsStructFromThread(SceUID thid) { SceKernelThreadInfo thinfo; unsigned int ptr; unsigned int thrNum; void *pTls; int numMatches; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(thid, &thinfo); numMatches = sscanf(thinfo.name,"pthread%04d__%x", &thrNum, &ptr); /* If we were called from a pthread, use the TLS allocated when the thread * was created. Otherwise, we were called from a non-pthread, so use the * "global". This is a pretty bad hack, but necessary due to lack of TLS on PSP. */ if (numMatches == 2) { pTls = (void *) ptr; } else { pTls = globalTls; } return pTls; } /**************************************************************************** * * Thread Local Storage * ***************************************************************************/ pte_osResult pte_osTlsSetValue(unsigned int key, void * value) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsSetValue(pTls, key, value); } void * pte_osTlsGetValue(unsigned int index) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return (void *) pteTlsGetValue(pTls, index); } pte_osResult pte_osTlsAlloc(unsigned int *pKey) { void * pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsAlloc(pKey); } pte_osResult pte_osTlsFree(unsigned int index) { return pteTlsFree(index); } /**************************************************************************** * * Miscellaneous * ***************************************************************************/ int ftime(struct timeb *tb) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); tb->time = tv.tv_sec; tb->millitm = tv.tv_usec / 1000; tb->timezone = tz.tz_minuteswest; tb->dstflag = tz.tz_dsttime; return 0; } \ No newline at end of file diff --git a/src/pthread/platform/nautilus/psp_osal.h b/src/pthread/platform/nautilus/psp_osal.h new file mode 100644 index 000000000..33528ddba --- /dev/null +++ b/src/pthread/platform/nautilus/psp_osal.h @@ -0,0 +1,66 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +typedef SceUID pte_osThreadHandle; + +typedef SceUID pte_osSemaphoreHandle; + +typedef SceUID pte_osMutexHandle; + + +#define OS_IS_HANDLE_VALID(x) ((x) > 0) + + + + +#define OS_MAX_SIMUL_THREADS 10 + +#define OS_DEFAULT_PRIO 11 + +#define OS_MIN_PRIO 17 +#define OS_MAX_PRIO 32 + +//#define HAVE_THREAD_SAFE_ERRNO + +#define POLLING_DELAY_IN_us 100 + + + +#define OS_MAX_SEM_VALUE 254 + +int PspInterlockedExchange(int *ptarg, int val); +int PspInterlockedCompareExchange(int *pdest, int exchange, int comp); +int PspInterlockedExchangeAdd(int volatile* pAddend, int value); +int PspInterlockedDecrement(int *pdest); +int PspInterlockedIncrement(int *pdest); + + + + diff --git a/src/pthread/platform/nautilus/pte_osal.h b/src/pthread/platform/nautilus/pte_osal.h new file mode 100644 index 000000000..fd5208367 --- /dev/null +++ b/src/pthread/platform/nautilus/pte_osal.h @@ -0,0 +1,15 @@ + +#ifndef _OS_SUPPORT_H_ +#define _OS_SUPPORT_H_ + +// Platform specific one must be included first +//#include "psp_osal.h" + +#include +#include + +#include "pte_generic_osal.h" + + + +#endif // _OS_SUPPORT_H diff --git a/src/pthread/platform/nautilus/pte_osal.h~ b/src/pthread/platform/nautilus/pte_osal.h~ new file mode 100644 index 000000000..2fe8723cd --- /dev/null +++ b/src/pthread/platform/nautilus/pte_osal.h~ @@ -0,0 +1,12 @@ + +#ifndef _OS_SUPPORT_H_ +#define _OS_SUPPORT_H_ + +// Platform specific one must be included first +#include "psp_osal.h" + +#include "pte_generic_osal.h" + + + +#endif // _OS_SUPPORT_H diff --git a/src/pthread/platform/nautilus/pte_types.h b/src/pthread/platform/nautilus/pte_types.h new file mode 100644 index 000000000..4fc2b422b --- /dev/null +++ b/src/pthread/platform/nautilus/pte_types.h @@ -0,0 +1,12 @@ +/* pte_types.h */ + +#ifndef PTE_TYPES_H +#define PTE_TYPES_H + +#include +#include +#include + +typedef int pid_t; + +#endif /* PTE_TYPES_H */ diff --git a/src/pthread/platform/psp/Makefile b/src/pthread/platform/psp/Makefile new file mode 100644 index 000000000..f9491e1f6 --- /dev/null +++ b/src/pthread/platform/psp/Makefile @@ -0,0 +1,194 @@ + +CLEANUP_TYPE=C +#CLEANUP_TYPE=CPP + +VPATH = ../..:../helper + +TARGET_LIB = libpthread-psp.a + + +MUTEX_OBJS = \ + pthread_mutex_unlock.o \ + pthread_mutex_init.o \ + pthread_mutex_destroy.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_trylock.o + +MUTEXATTR_OBJS = \ + pthread_mutexattr_destroy.o \ + pthread_mutexattr_getkind_np.o \ + pthread_mutexattr_getpshared.o \ + pthread_mutexattr_gettype.o \ + pthread_mutexattr_init.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_setpshared.o \ + pthread_mutexattr_settype.o + +SUPPORT_OBJS = \ + pte_relmillisecs.o \ + pte_mutex_check_need_init.o \ + pte_threadDestroy.o \ + pte_new.o \ + pte_threadStart.o \ + global.o \ + pte_reuse.o \ + pthread_init.o \ + pthread_terminate.o + +THREAD_OBJS = \ + create.o \ + pthread_self.o \ + pthread_equal.o \ + pthread_join.o \ + pthread_detach.o \ + pte_detach.o \ + pte_callUserDestroyRoutines.o \ + pte_tkAssocDestroy.o \ + pthread_kill.o \ + pthread_attr_destroy.o \ + pthread_attr_getdetachstate.o \ + pthread_attr_getinheritsched.o \ + pthread_attr_getschedparam.o \ + pthread_attr_getschedpolicy.o \ + pthread_attr_getscope.o \ + pthread_attr_getstackaddr.o \ + pthread_attr_getstacksize.o \ + pthread_attr_init.o \ + pthread_attr_setdetachstate.o \ + pthread_attr_setinheritsched.o \ + pthread_attr_setschedparam.o \ + pthread_attr_setschedpolicy.o \ + pthread_attr_setscope.o \ + pthread_attr_setstackaddr.o \ + pthread_attr_setstacksize.o \ + pte_is_attr.o \ + pthread_exit.o \ + pthread_getschedparam.o \ + pthread_setschedparam.o \ + sched_get_priority_max.o \ + sched_get_priority_min.o + + +TLS_OBJS = \ + pthread_key_create.o \ + pthread_key_delete.o \ + pthread_getspecific.o \ + pthread_setspecific.o \ + pte_tkAssocCreate.o + +MISC_OBJS = \ + sched_yield.o \ + pthread_delay_np.o \ + pthread_testcancel.o \ + pte_throw.o \ + cleanup.o \ + pthread_once.o \ + pthread_num_processors_np.o \ + pte_getprocessors.o \ + pte_spinlock_check_need_init.o \ + global.o \ + pthread_timechange_handler_np.o \ + pte_cond_check_need_init.o \ + pthread_getconcurrency.o \ + pthread_setconcurrency.o \ + pte_cancellable_wait.o + +SEM_OBJS = \ + sem_close.o \ + sem_destroy.o \ + sem_getvalue.o \ + sem_init.o \ + sem_open.o \ + sem_post.o \ + sem_post_multiple.o \ + sem_timedwait.o \ + sem_trywait.o \ + sem_unlink.o \ + sem_wait.o + +BARRIER_OBJS = \ + pthread_barrier_init.o \ + pthread_barrier_destroy.o \ + pthread_barrier_wait.o \ + pthread_barrierattr_init.o \ + pthread_barrierattr_destroy.o \ + pthread_barrierattr_getpshared.o \ + pthread_barrierattr_setpshared.o \ + +SPIN_OBJS = \ + pthread_spin_destroy.o \ + pthread_spin_init.o \ + pthread_spin_lock.o \ + pthread_spin_trylock.o \ + pthread_spin_unlock.o + +CONDVAR_OBJS = \ + pthread_cond_destroy.o \ + pthread_cond_init.o \ + pthread_cond_signal.o \ + pthread_cond_wait.o \ + pthread_condattr_destroy.o \ + pthread_condattr_getpshared.o \ + pthread_condattr_init.o \ + pthread_condattr_setpshared.o + +RWLOCK_OBJS = \ + pthread_rwlock_init.o \ + pthread_rwlock_destroy.o \ + pthread_rwlock_rdlock.o \ + pthread_rwlock_timedrdlock.o \ + pthread_rwlock_timedwrlock.o \ + pthread_rwlock_tryrdlock.o \ + pthread_rwlock_trywrlock.o \ + pthread_rwlock_unlock.o \ + pthread_rwlock_wrlock.o \ + pthread_rwlockattr_init.o \ + pthread_rwlockattr_destroy.o \ + pthread_rwlockattr_getpshared.o \ + pthread_rwlockattr_setpshared.o \ + pte_rwlock_check_need_init.o \ + pte_rwlock_cancelwrwait.o + +CANCEL_OBJS = \ + pthread_cancel.o \ + pthread_setcanceltype.o \ + pthread_setcancelstate.o + +OS_OBJS = \ + psp_osal.o \ + tls-helper.o + +OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) + +INCDIR = +CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper +CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX +ASFLAGS = $(CFLAGS) + +LDFLAGS = +LIBS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + + +ifeq ($(CLEANUP_TYPE),CPPXX) + +CC=psp-g++ + +pte_throw.o: pte_throw.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_throw.c -o pte_throw.o + +pte_threadStart.o: pte_threadStart.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../pte_threadStart.c -o pte_threadStart.o + +endif + +install: $(TARGET_LIB) + @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib + @cp -v *.h `psp-config --psp-prefix`/include + @echo "Done." + diff --git a/src/pthread/platform/psp/Makefile.tests b/src/pthread/platform/psp/Makefile.tests new file mode 100644 index 000000000..9fcdb9cef --- /dev/null +++ b/src/pthread/platform/psp/Makefile.tests @@ -0,0 +1,212 @@ + +CLEANUP_TYPE=C +#CLEANUP_TYPE=CPP + +VPATH = ../../tests + +TARGET = pthread-psp-test + +MUTEX_TEST_OBJS = \ + mutex1.o \ + mutex1e.o \ + mutex1n.o \ + mutex1r.o \ + mutex2.o \ + mutex2e.o \ + mutex2r.o \ + mutex3.o \ + mutex3e.o \ + mutex3r.o \ + mutex4.o \ + mutex5.o \ + mutex6.o \ + mutex6e.o \ + mutex6es.o \ + mutex6n.o \ + mutex6r.o \ + mutex6rs.o \ + mutex6s.o \ + mutex7.o \ + mutex7e.o \ + mutex7n.o \ + mutex7r.o \ + mutex8.o \ + mutex8e.o \ + mutex8n.o \ + mutex8r.o + +MISC_OBJS = \ + main.o \ + test_main.o + + +MISC_TEST_OBJS = \ + valid1.o \ + valid2.o \ + self1.o \ + self2.o \ + equal1.o \ + count1.o \ + delay1.o \ + delay2.o \ + errno1.o \ + tsd1.o \ + tsd2.o \ + stress1.o \ + detach1.o + +SEM_TEST_OBJS = \ + semaphore1.o \ + semaphore2.o \ + semaphore3.o \ + semaphore4.o \ + semaphore4t.o \ + semaphore5.o \ + semaphore6.o + +BARRIER_TEST_OBJS = \ + barrier1.o \ + barrier2.o \ + barrier3.o \ + barrier4.o \ + barrier5.o + +# Tests excluded because cancellation is not implemented +# semaphore4.o +# semaphore4t.o + +THREAD_TEST_OBJS = \ + create1.o \ + create2.o \ + create3.o \ + join0.o \ + join1.o \ + join2.o \ + join3.o \ + join4.o \ + kill1.o \ + once1.o \ + once2.o \ + once3.o \ + once4.o \ + exit1.o \ + exit2.o \ + exit3.o \ + exit4.o \ + exit5.o \ + reuse1.o \ + reuse2.o \ + priority1.o \ + priority2.o \ + inherit1.o + + +SPIN_TEST_OBJS = \ + spin1.o \ + spin2.o \ + spin3.o \ + spin4.o + +CONDVAR_TEST_OBJS = \ + condvar1.o \ + condvar1_1.o \ + condvar1_2.o \ + condvar2.o \ + condvar2_1.o \ + condvar3.o \ + condvar3_1.o \ + condvar3_2.o \ + condvar3_3.o \ + condvar4.o \ + condvar5.o \ + condvar6.o \ + condvar8.o \ + condvar7.o \ + condvar9.o + +RWLOCK_TEST_OBJS = \ + rwlock1.o \ + rwlock2.o \ + rwlock2_t.o \ + rwlock3.o \ + rwlock3_t.o \ + rwlock4.o \ + rwlock4_t.o \ + rwlock5.o \ + rwlock5_t.o \ + rwlock6.o \ + rwlock6_t.o \ + rwlock6_t2.o \ + rwlock7.o \ + rwlock8.o + +CANCEL_TEST_OBJS = \ + cancel1.o \ + cancel2.o \ + cancel3.o \ + cancel4.o \ + cancel5.o \ + cancel6a.o \ + cancel6d.o \ + cleanup0.o \ + cleanup1.o \ + cleanup2.o \ + cleanup3.o + +BENCH_TEST_OBJS = \ + benchlib.o \ + benchtest1.o \ + benchtest2.o \ + benchtest3.o \ + benchtest4.o + +EXCEPTION_TEST_OBJS = \ + exception1.o \ + exception2.o \ + exception3.o + + + +OBJS = $(MUTEX_TEST_OBJS) $(MISC_OBJS) $(MISC_TEST_OBJS) $(THREAD_TEST_OBJS) $(SEM_TEST_OBJS) $(BARRIER_TEST_OBJS) $(SPIN_TEST_OBJS) $(CONDVAR_TEST_OBJS) $(RWLOCK_TEST_OBJS) $(CANCEL_TEST_OBJS) $(BENCH_TEST_OBJS) $(EXCEPTION_TEST_OBJS) + + +INCDIR = +CFLAGS = $(GLOBAL_CFLAGS) -O2 -Wall -g -I.. -fno-strict-aliasing -I../.. -G0 +CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LDFLAGS = -L../.. +LIBS = -lc -lpthread-psp -lstdc++ + +ifeq ($(CLEANUP_TYPE),CPPXX) + +LIBS += -lstdc++ + +endif + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +ifeq ($(CLEANUP_TYPE),CPPXXX) + +CC=psp-g++ + +exception1.o: exception1.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../tests/exception1.c -o exception1.o + +exception2.o: exception2.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../tests/exception2.c -o exception2.o + +exception3.o: exception3.c + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c ../../tests/exception3.c -o exception3.o +endif + + +install: $(TARGET_LIB) + @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib + @cp -v *.h `psp-config --psp-prefix`/include + @echo "Done." + diff --git a/src/pthread/platform/psp/main.c b/src/pthread/platform/psp/main.c new file mode 100644 index 000000000..22e44036d --- /dev/null +++ b/src/pthread/platform/psp/main.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include + + +PSP_MODULE_INFO("Pthread Test", 0, 1, 1); + +extern void pte_test_main(); + +#ifdef JNS +#define printf pspDebugScreenPrintf +#endif + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + + + +int main() +{ + SceCtrlData pad; + + pspDebugScreenInit(); + SetupCallbacks(); + + pte_test_main(); + + while (1) + { + sceCtrlReadBufferPositive(&pad, 1); + if (pad.Buttons & PSP_CTRL_UP) + { + printf("Exiting...\n"); + return 0; + } + + } + return 0; +} + + diff --git a/src/pthread/platform/psp/psp_osal.c b/src/pthread/platform/psp/psp_osal.c new file mode 100644 index 000000000..a3887a609 --- /dev/null +++ b/src/pthread/platform/psp/psp_osal.c @@ -0,0 +1 @@ +/* * psp_osal.c * * Description: * * -------------------------------------------------------------------------- * * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems * Copyright(C) 2008 Jason Schmidlapp * * Contact Email: jschmidlapp@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "pte_osal.h" #include "pthread.h" #include "tls-helper.h" /* For ftime */ #include #include #include #define MAX_PSP_UID 2048 // SWAG #define DEFAULT_STACK_SIZE_BYTES 4096 #define PSP_MAX_TLS 32 #if 1 #define PSP_DEBUG(x) printf(x) #else #define PSP_DEBUG(x) #endif /* TLS key used to access pspThreadData struct for reach thread. */ static unsigned int threadDataKey; /* * Data stored on a per-thread basis - allocated in pte_osThreadCreate * and freed in pte_osThreadDelete. */ typedef struct pspThreadData { /* Entry point and parameters to thread's main function */ pte_osThreadEntryPoint entryPoint; void * argv; /* Semaphore used for cancellation. Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */ SceUID cancelSem; } pspThreadData; /* Structure used to emulate TLS on non-POSIX threads. * This limits us to one non-POSIX thread that can * call pthread functions. */ static void *globalTls; /* Helper functions */ static pspThreadData *getThreadData(SceUID threadHandle); static void *getTlsStructFromThread(SceUID thid); /* A new thread's stub entry point. It retrieves the real entry point from the per thread control * data as well as any parameters to this function, and then calls the entry point. */ int pspStubThreadEntry (unsigned int argc, void *argv) { int result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); result = (*(pThreadData->entryPoint))(pThreadData->argv); return result; } /**************************************************************************** * * Initialization * ***************************************************************************/ pte_osResult pte_osInit(void) { pte_osResult result; pspThreadData *pThreadData; char cancelSemName[64]; /* Allocate and initialize TLS support */ result = pteTlsGlobalInit(PSP_MAX_TLS); if (result == PTE_OS_OK) { /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */ result = pteTlsAlloc(&threadDataKey); if (result == PTE_OS_OK) { /* Initialize the structure used to emulate TLS for * non-POSIX threads */ globalTls = pteTlsThreadInit(); /* Also create a "thread data" structure for a single non-POSIX thread. */ /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { result = PTE_OS_NO_RESOURCES; } else { /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(globalTls, threadDataKey, pThreadData); /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSemGlobal"); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ result = PTE_OS_OK; } } } return result; } /**************************************************************************** * * Threads * ***************************************************************************/ pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle) { char threadName[64]; char cancelSemName[64]; static int threadNum = 1; int pspAttr; void *pTls; SceUID threadId; pte_osResult result; pspThreadData *pThreadData; if (threadNum++ > MAX_PSP_UID) { threadNum = 0; } /* Make sure that the stack we're going to allocate is big enough */ if (stackSize < DEFAULT_STACK_SIZE_BYTES) { stackSize = DEFAULT_STACK_SIZE_BYTES; } /* Allocate TLS structure for this thread. */ pTls = pteTlsThreadInit(); if (pTls == NULL) { PSP_DEBUG("pteTlsThreadInit: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (pspThreadData *) malloc(sizeof(pspThreadData)); if (pThreadData == NULL) { pteTlsThreadDestroy(pTls); PSP_DEBUG("malloc(pspThreadData): PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(pTls, threadDataKey, pThreadData); pThreadData->entryPoint = entryPoint; pThreadData->argv = argv; /* Create a semaphore used to cancel threads */ snprintf(cancelSemName, sizeof(cancelSemName), "pthread_cancelSem%04d", threadNum); pThreadData->cancelSem = sceKernelCreateSema(cancelSemName, 0, /* attributes (default) */ 0, /* initial value */ 255, /* maximum value */ 0); /* options (default) */ /* In order to emulate TLS functionality, we append the address of the TLS structure that we * allocated above to the thread's name. To set or get TLS values for this thread, the user * needs to get the name of the thread from the OS and then parse the name to extract * a pointer to the TLS structure. */ snprintf(threadName, sizeof(threadName), "pthread%04d__%x", threadNum, (unsigned int) pTls); pspAttr = 0; // printf("%s %p %d %d %d\n",threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr); threadId = sceKernelCreateThread(threadName, pspStubThreadEntry, initialPriority, stackSize, pspAttr, NULL); if (threadId == (SceUID) SCE_KERNEL_ERROR_NO_MEMORY) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; } else if (threadId < 0) { free(pThreadData); pteTlsThreadDestroy(pTls); PSP_DEBUG("sceKernelCreateThread: PTE_OS_GENERAL_FAILURE\n"); result = PTE_OS_GENERAL_FAILURE; } else { *ppte_osThreadHandle = threadId; result = PTE_OS_OK; } FAIL0: return result; } pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle) { sceKernelStartThread(osThreadHandle, 0, NULL); return PTE_OS_OK; } pte_osResult pte_osThreadDelete(pte_osThreadHandle handle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(handle); pThreadData = getThreadData(handle); sceKernelDeleteSema(pThreadData->cancelSem); free(pThreadData); pteTlsThreadDestroy(pTls); sceKernelDeleteThread(handle); return PTE_OS_OK; } pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle) { pte_osThreadDelete(handle); sceKernelExitDeleteThread(0); return PTE_OS_OK; } void pte_osThreadExit() { sceKernelExitThread(0); } /* * This has to be cancellable, so we can't just call sceKernelWaitThreadEnd. * Instead, poll on this in a loop, like we do for a cancellable semaphore. */ pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle) { pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); while (1) { SceKernelThreadRunStatus info; /* Poll task to see if it has ended */ memset(&info,0,sizeof(info)); info.size = sizeof(info); sceKernelReferThreadRunStatus(threadHandle, &info); if (info.status == PSP_THREAD_STOPPED) { /* Thread has ended */ result = PTE_OS_OK; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } pte_osThreadHandle pte_osThreadGetHandle(void) { return sceKernelGetThreadId(); } int pte_osThreadGetPriority(pte_osThreadHandle threadHandle) { SceKernelThreadInfo thinfo; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(threadHandle, &thinfo); return thinfo.currentPriority; } pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority) { sceKernelChangeThreadPriority(threadHandle, newPriority); return PTE_OS_OK; } pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle) { SceUID osResult; pte_osResult result; pspThreadData *pThreadData; pThreadData = getThreadData(threadHandle); osResult = sceKernelSignalSema(pThreadData->cancelSem, 1); if (osResult == SCE_KERNEL_ERROR_OK) { result = PTE_OS_OK; } else { result = PTE_OS_GENERAL_FAILURE; } return result; } pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle) { pspThreadData *pThreadData; SceKernelSemaInfo semInfo; SceUID osResult; pte_osResult result; pThreadData = getThreadData(threadHandle); if (pThreadData != NULL) { osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; } else { result = PTE_OS_OK; } } else { /* sceKernelReferSemaStatus returned an error */ result = PTE_OS_GENERAL_FAILURE; } } else { /* For some reason, we couldn't get thread data */ result = PTE_OS_GENERAL_FAILURE; } return result; } void pte_osThreadSleep(unsigned int msecs) { sceKernelDelayThread(msecs*1000); } int pte_osThreadGetMinPriority() { return 17; } int pte_osThreadGetMaxPriority() { return 30; } int pte_osThreadGetDefaultPriority() { return 18; } /**************************************************************************** * * Mutexes * ****************************************************************************/ pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle) { static int mutexCtr = 0; char mutexName[32]; pte_osMutexHandle handle; if (mutexCtr++ > MAX_PSP_UID) { mutexCtr = 0; } snprintf(mutexName,sizeof(mutexName),"mutex%d",mutexCtr); handle = sceKernelCreateSema(mutexName, 0, /* attributes (default) */ 1, /* initial value */ 1, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osMutexDelete(pte_osMutexHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osMutexLock(pte_osMutexHandle handle) { sceKernelWaitSema(handle, 1, NULL); return PTE_OS_OK; } pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs) { pte_osResult result; SceUInt timeoutUsecs = timeoutMsecs*1000; int status = sceKernelWaitSema(handle, 1, &timeoutUsecs); if (status < 0) { // Assume that any error from sceKernelWaitSema was due to a timeout result = PTE_OS_TIMEOUT; } else { result = PTE_OS_OK; } return result; } pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) { sceKernelSignalSema(handle, 1); return PTE_OS_OK; } /**************************************************************************** * * Semaphores * ***************************************************************************/ pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle) { pte_osSemaphoreHandle handle; static int semCtr = 0; char semName[32]; if (semCtr++ > MAX_PSP_UID) { semCtr = 0; } snprintf(semName,sizeof(semName),"pthread_sem%d",semCtr); handle = sceKernelCreateSema(semName, 0, /* attributes (default) */ initialValue, /* initial value */ SEM_VALUE_MAX, /* maximum value */ 0); /* options (default) */ *pHandle = handle; return PTE_OS_OK; } pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle) { sceKernelDeleteSema(handle); return PTE_OS_OK; } pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count) { sceKernelSignalSema(handle, count); return PTE_OS_OK; } pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs) { unsigned int timeoutUsecs; unsigned int *pTimeoutUsecs; SceUInt result; pte_osResult osResult; if (pTimeoutMsecs == NULL) { pTimeoutUsecs = NULL; } else { timeoutUsecs = *pTimeoutMsecs * 1000; pTimeoutUsecs = &timeoutUsecs; } result = sceKernelWaitSema(handle, 1, pTimeoutUsecs); if (result == SCE_KERNEL_ERROR_OK) { osResult = PTE_OS_OK; } else if (result == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { osResult = PTE_OS_TIMEOUT; } else { osResult = PTE_OS_GENERAL_FAILURE; } return osResult; } /* * Pend on a semaphore- and allow the pend to be cancelled. * * PSP OS provides no functionality to asynchronously interrupt a blocked call. We simulte * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout) { pspThreadData *pThreadData; pThreadData = getThreadData(sceKernelGetThreadId()); clock_t start_time; pte_osResult result = PTE_OS_OK; unsigned int timeout; unsigned char timeoutEnabled; start_time = clock(); // clock() is in microseconds, timeout as passed in was in milliseconds if (pTimeout == NULL) { timeout = 0; timeoutEnabled = 0; } else { timeout = *pTimeout * 1000; timeoutEnabled = 1; } while (1) { SceUInt semTimeout; int status; /* Poll semaphore */ semTimeout = 0; status = sceKernelWaitSema(semHandle, 1, &semTimeout); if (status == SCE_KERNEL_ERROR_OK) { /* User semaphore posted to */ result = PTE_OS_OK; break; } else if ((timeoutEnabled) && ((clock() - start_time) > timeout)) { /* Timeout expired */ result = PTE_OS_TIMEOUT; break; } else { SceKernelSemaInfo semInfo; if (pThreadData != NULL) { SceUID osResult; osResult = sceKernelReferSemaStatus(pThreadData->cancelSem, &semInfo); if (osResult == SCE_KERNEL_ERROR_OK) { if (semInfo.currentCount > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sceKernelDelayThread(POLLING_DELAY_IN_us); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; } /**************************************************************************** * * Atomic Operations * ***************************************************************************/ int pte_osAtomicExchange(int *ptarg, int val) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *ptarg; *ptarg = val; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp) { int intc = pspSdkDisableInterrupts(); int origVal; origVal = *pdest; if (*pdest == comp) { *pdest = exchange; } pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicExchangeAdd(int volatile* pAddend, int value) { int origVal; int intc = pspSdkDisableInterrupts(); origVal = *pAddend; *pAddend += value; pspSdkEnableInterrupts(intc); return origVal; } int pte_osAtomicDecrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)--; val = *pdest; pspSdkEnableInterrupts(intc); return val; } int pte_osAtomicIncrement(int *pdest) { int val; int intc = pspSdkDisableInterrupts(); (*pdest)++; val = *pdest; pspSdkEnableInterrupts(intc); return val; } /**************************************************************************** * * Helper functions * ***************************************************************************/ static pspThreadData *getThreadData(SceUID threadHandle) { pspThreadData *pThreadData; void *pTls; pTls = getTlsStructFromThread(threadHandle); pThreadData = (pspThreadData *) pteTlsGetValue(pTls, threadDataKey); return pThreadData; } static void *getTlsStructFromThread(SceUID thid) { SceKernelThreadInfo thinfo; unsigned int ptr; unsigned int thrNum; void *pTls; int numMatches; thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(thid, &thinfo); numMatches = sscanf(thinfo.name,"pthread%04d__%x", &thrNum, &ptr); /* If we were called from a pthread, use the TLS allocated when the thread * was created. Otherwise, we were called from a non-pthread, so use the * "global". This is a pretty bad hack, but necessary due to lack of TLS on PSP. */ if (numMatches == 2) { pTls = (void *) ptr; } else { pTls = globalTls; } return pTls; } /**************************************************************************** * * Thread Local Storage * ***************************************************************************/ pte_osResult pte_osTlsSetValue(unsigned int key, void * value) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsSetValue(pTls, key, value); } void * pte_osTlsGetValue(unsigned int index) { void *pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return (void *) pteTlsGetValue(pTls, index); } pte_osResult pte_osTlsAlloc(unsigned int *pKey) { void * pTls; pTls = getTlsStructFromThread(sceKernelGetThreadId()); return pteTlsAlloc(pKey); } pte_osResult pte_osTlsFree(unsigned int index) { return pteTlsFree(index); } /**************************************************************************** * * Miscellaneous * ***************************************************************************/ int ftime(struct timeb *tb) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); tb->time = tv.tv_sec; tb->millitm = tv.tv_usec / 1000; tb->timezone = tz.tz_minuteswest; tb->dstflag = tz.tz_dsttime; return 0; } \ No newline at end of file diff --git a/src/pthread/platform/psp/psp_osal.h b/src/pthread/platform/psp/psp_osal.h new file mode 100644 index 000000000..33528ddba --- /dev/null +++ b/src/pthread/platform/psp/psp_osal.h @@ -0,0 +1,66 @@ +/* + * psp_osal.h + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +typedef SceUID pte_osThreadHandle; + +typedef SceUID pte_osSemaphoreHandle; + +typedef SceUID pte_osMutexHandle; + + +#define OS_IS_HANDLE_VALID(x) ((x) > 0) + + + + +#define OS_MAX_SIMUL_THREADS 10 + +#define OS_DEFAULT_PRIO 11 + +#define OS_MIN_PRIO 17 +#define OS_MAX_PRIO 32 + +//#define HAVE_THREAD_SAFE_ERRNO + +#define POLLING_DELAY_IN_us 100 + + + +#define OS_MAX_SEM_VALUE 254 + +int PspInterlockedExchange(int *ptarg, int val); +int PspInterlockedCompareExchange(int *pdest, int exchange, int comp); +int PspInterlockedExchangeAdd(int volatile* pAddend, int value); +int PspInterlockedDecrement(int *pdest); +int PspInterlockedIncrement(int *pdest); + + + + diff --git a/src/pthread/platform/psp/pte_osal.h b/src/pthread/platform/psp/pte_osal.h new file mode 100644 index 000000000..2fe8723cd --- /dev/null +++ b/src/pthread/platform/psp/pte_osal.h @@ -0,0 +1,12 @@ + +#ifndef _OS_SUPPORT_H_ +#define _OS_SUPPORT_H_ + +// Platform specific one must be included first +#include "psp_osal.h" + +#include "pte_generic_osal.h" + + + +#endif // _OS_SUPPORT_H diff --git a/src/pthread/platform/psp/pte_types.h b/src/pthread/platform/psp/pte_types.h new file mode 100644 index 000000000..4fc2b422b --- /dev/null +++ b/src/pthread/platform/psp/pte_types.h @@ -0,0 +1,12 @@ +/* pte_types.h */ + +#ifndef PTE_TYPES_H +#define PTE_TYPES_H + +#include +#include +#include + +typedef int pid_t; + +#endif /* PTE_TYPES_H */ diff --git a/src/pthread/pte_callUserDestroyRoutines.c b/src/pthread/pte_callUserDestroyRoutines.c new file mode 100644 index 000000000..07076f23b --- /dev/null +++ b/src/pthread/pte_callUserDestroyRoutines.c @@ -0,0 +1,229 @@ +/* + * pte_callUserDestroyRoutines.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +#include + +#ifdef __cplusplus +#include +using std::terminate; +#endif + +void +pte_callUserDestroyRoutines (pthread_t thread) +/* + * ------------------------------------------------------------------- + * DOCPRIVATE + * + * This the routine runs through all thread keys and calls + * the destroy routines on the user's data for the current thread. + * It simulates the behaviour of POSIX Threads. + * + * PARAMETERS + * thread + * an instance of pthread_t + * + * RETURNS + * N/A + * ------------------------------------------------------------------- + */ +{ + ThreadKeyAssoc * assoc; + + if (thread.p != NULL) + { + int assocsRemaining; + int iterations = 0; + pte_thread_t * sp = (pte_thread_t *) thread.p; + + /* + * Run through all Thread<-->Key associations + * for the current thread. + * + * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times. + */ + do + { + assocsRemaining = 0; + iterations++; + + (void) pthread_mutex_lock(&(sp->threadLock)); + /* + * The pointer to the next assoc is stored in the thread struct so that + * the assoc destructor in pthread_key_delete can adjust it + * if it deletes this assoc. This can happen if we fail to acquire + * both locks below, and are forced to release all of our locks, + * leaving open the opportunity for pthread_key_delete to get in + * before us. + */ + sp->nextAssoc = sp->keys; + (void) pthread_mutex_unlock(&(sp->threadLock)); + + for (;;) + { + void * value; + pthread_key_t k; + void (*destructor) (void *); + + /* + * First we need to serialise with pthread_key_delete by locking + * both assoc guards, but in the reverse order to our convention, + * so we must be careful to avoid deadlock. + */ + (void) pthread_mutex_lock(&(sp->threadLock)); + + if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL) + { + /* Finished */ + pthread_mutex_unlock(&(sp->threadLock)); + break; + } + else + { + /* + * assoc->key must be valid because assoc can't change or be + * removed from our chain while we hold at least one lock. If + * the assoc was on our key chain then the key has not been + * deleted yet. + * + * Now try to acquire the second lock without deadlocking. + * If we fail, we need to relinquish the first lock and the + * processor and then try to acquire them all again. + */ + if (pthread_mutex_trylock(&(assoc->key->keyLock)) == EBUSY) + { + pthread_mutex_unlock(&(sp->threadLock)); + pte_osThreadSleep(1); // Ugly but necessary to avoid priority effects. + /* + * Go around again. + * If pthread_key_delete has removed this assoc in the meantime, + * sp->nextAssoc will point to a new assoc. + */ + continue; + } + } + + /* We now hold both locks */ + + sp->nextAssoc = assoc->nextKey; + + /* + * Key still active; pthread_key_delete + * will block on these same mutexes before + * it can release actual key; therefore, + * key is valid and we can call the destroy + * routine; + */ + k = assoc->key; + destructor = k->destructor; + value = pte_osTlsGetValue(k->key); + pte_osTlsSetValue (k->key, NULL); + + // Every assoc->key exists and has a destructor + if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* + * Unlock both locks before the destructor runs. + * POSIX says pthread_key_delete can be run from destructors, + * and that probably includes with this key as target. + * pthread_setspecific can also be run from destructors and + * also needs to be able to access the assocs. + */ + (void) pthread_mutex_unlock(&(sp->threadLock)); + (void) pthread_mutex_unlock(&(k->keyLock)); + + assocsRemaining++; + +#ifdef __cplusplus + + try + { + /* + * Run the caller's cleanup routine. + */ + destructor (value); + } + catch (...) + { + /* + * A system unexpected exception has occurred + * running the user's destructor. + * We get control back within this block in case + * the application has set up it's own terminate + * handler. Since we are leaving the thread we + * should not get any internal pthreads + * exceptions. + */ + terminate (); + } + +#else /* __cplusplus */ + + /* + * Run the caller's cleanup routine. + */ + destructor (value); + +#endif /* __cplusplus */ + + } + else + { + /* + * Remove association from both the key and thread chains + * and reclaim it's memory resources. + */ + pte_tkAssocDestroy (assoc); + (void) pthread_mutex_unlock(&(sp->threadLock)); + (void) pthread_mutex_unlock(&(k->keyLock)); + } + } + } + while (assocsRemaining); + } +} /* pte_callUserDestroyRoutines */ diff --git a/src/pthread/pte_cancellable_wait.c b/src/pthread/pte_cancellable_wait.c new file mode 100644 index 000000000..2579fcbe8 --- /dev/null +++ b/src/pthread/pte_cancellable_wait.c @@ -0,0 +1,130 @@ +/* + * pte_cancellable_wait.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int pte_cancellable_wait (pte_osSemaphoreHandle semHandle, unsigned int* timeout) +{ + int result = EINVAL; + pte_osResult osResult; + int cancelEnabled = 0; + pthread_t self; + pte_thread_t * sp; + + self = pthread_self(); + sp = (pte_thread_t *) self.p; + + if (sp != NULL) + { + /* + * Get cancelEvent handle + */ + if (sp->cancelState == PTHREAD_CANCEL_ENABLE) + { + cancelEnabled = 1; + } + } + + + if (cancelEnabled) + { + osResult = pte_osSemaphoreCancellablePend(semHandle, timeout); + } + else + { + osResult = pte_osSemaphorePend(semHandle, timeout); + } + + switch (osResult) + { + case PTE_OS_OK: + { + result = 0; + break; + } + + case PTE_OS_TIMEOUT: + { + result = ETIMEDOUT; + break; + } + + case PTE_OS_INTERRUPTED: + { + if (sp != NULL) + { + /* + * Should handle POSIX and implicit POSIX threads.. + * Make sure we haven't been async-canceled in the meantime. + */ + (void) pthread_mutex_lock (&sp->cancelLock); + if (sp->state < PThreadStateCanceling) + { + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock (&sp->cancelLock); + pte_throw (PTE_EPS_CANCEL); + + /* Never reached */ + } + (void) pthread_mutex_unlock (&sp->cancelLock); + } + break; + } + + default: + { + result = EINVAL; + } + + } + + + return (result); + +} /* CancelableWait */ + diff --git a/src/pthread/pte_cond_check_need_init.c b/src/pthread/pte_cond_check_need_init.c new file mode 100644 index 000000000..5b2817637 --- /dev/null +++ b/src/pthread/pte_cond_check_need_init.c @@ -0,0 +1,103 @@ +/* + * pte_cond_check_need_init.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pte_cond_check_need_init (pthread_cond_t * cond) +{ + int result = 0; + + /* + * The following guarded test is specifically for statically + * initialised condition variables (via PTHREAD_OBJECT_INITIALIZER). + * + * Note that by not providing this synchronisation we risk + * introducing race conditions into applications which are + * correctly written. + * + * Approach + * -------- + * We know that static condition variables will not be PROCESS_SHARED + * so we can serialise access to internal state using + * Win32 Critical Sections rather than Win32 Mutexes. + * + * If using a single global lock slows applications down too much, + * multiple global locks could be created and hashed on some random + * value associated with each mutex, the pointer perhaps. At a guess, + * a good value for the optimal number of global locks might be + * the number of processors + 1. + * + */ + + + pte_osMutexLock (pte_cond_test_init_lock); + + /* + * We got here possibly under race + * conditions. Check again inside the critical section. + * If a static cv has been destroyed, the application can + * re-initialise it only by calling pthread_cond_init() + * explicitly. + */ + if (*cond == PTHREAD_COND_INITIALIZER) + { + result = pthread_cond_init (cond, NULL); + } + else if (*cond == NULL) + { + /* + * The cv has been destroyed while we were waiting to + * initialise it, so the operation that caused the + * auto-initialisation should fail. + */ + result = EINVAL; + } + + + pte_osMutexUnlock(pte_cond_test_init_lock); + + return result; +} diff --git a/src/pthread/pte_detach.c b/src/pthread/pte_detach.c new file mode 100644 index 000000000..f6195d7c8 --- /dev/null +++ b/src/pthread/pte_detach.c @@ -0,0 +1,106 @@ +/* + * pthread_win32_attach_detach_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +static int +pte_thread_detach_common (unsigned char threadShouldExit) +{ + if (pte_processInitialized) + { + /* + * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + pte_thread_t * sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey); + + if (sp != NULL) // otherwise OS thread with no implicit POSIX handle. + { + + pte_callUserDestroyRoutines (sp->ptHandle); + + (void) pthread_mutex_lock (&sp->cancelLock); + sp->state = PThreadStateLast; + + /* + * If the thread is joinable at this point then it MUST be joined + * or detached explicitly by the application. + */ + (void) pthread_mutex_unlock (&sp->cancelLock); + + if (sp->detachState == PTHREAD_CREATE_DETACHED) + { + if (threadShouldExit) + { + pte_threadExitAndDestroy (sp->ptHandle); + } + else + { + pte_threadDestroy (sp->ptHandle); + } + + // pte_osTlsSetValue (pte_selfThreadKey->key, NULL); + } + else + { + if (threadShouldExit) + { + pte_osThreadExit(); + } + } + } + } + + return 1; +} + +int pte_thread_detach_and_exit_np() +{ + return pte_thread_detach_common(1); +} + +int pte_thread_detach_np() +{ + return pte_thread_detach_common(0); +} + diff --git a/src/pthread/pte_generic_osal.h b/src/pthread/pte_generic_osal.h new file mode 100644 index 000000000..3ce7f4964 --- /dev/null +++ b/src/pthread/pte_generic_osal.h @@ -0,0 +1,449 @@ +/* + * pte_cancellable_wait.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _GENERIC_OS_SUPPORT_H_ +#define _GENERIC_OS_SUPPORT_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** @name Misc */ +//@{ +typedef enum pte_osResult +{ + + /** Operation completed successfully */ + PTE_OS_OK = 0, + + /** Operation failed because there insufficient resources */ + PTE_OS_NO_RESOURCES, + + /** Operation failed due to a general failure */ + PTE_OS_GENERAL_FAILURE, + + /** Operation did not complete because a user specified timeout expired. */ + PTE_OS_TIMEOUT, + + /** The operation was interrupted before it could complete. */ + PTE_OS_INTERRUPTED, + + /** An invalid parameter was specified */ + PTE_OS_INVALID_PARAM + + +} pte_osResult; + +/** + * Provides a hook for the OSAL to implement any OS specific initialization. This is guaranteed to be + * called before any other OSAL function. + */ +pte_osResult pte_osInit(void); +//@} + +/** @name Mutexes */ +//@{ + +/** + * Creates a mutex + * + * @param pHandle Set to the handle of the newly created mutex. + * + * @return PTE_OS_OK - Mutex successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex + */ +pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle); + +/** + * Deletes a mutex and frees any associated resources. + * + * @param handle Handle of mutex to delete. + * + * @return PTE_OS_OK - Mutex successfully deleted. + */ +pte_osResult pte_osMutexDelete(pte_osMutexHandle handle); + +/** + * Locks the mutex + * + * @param handle Handle of mutex to lock. + * + * @return PTE_OS_OK - Mutex successfully locked. + */ +pte_osResult pte_osMutexLock(pte_osMutexHandle handle); + +/** + * Locks the mutex, returning after @p timeoutMsecs if the resources is not + * available. Can be used for polling mutex by using @p timeoutMsecs of zero. + * + * @param handle Handle of mutex to lock. + * @param timeoutMsecs Number of milliseconds to wait for resource before returning. + * + * @return PTE_OS_OK - Mutex successfully locked. + * @return PTE_OS_TIMEOUT - Timeout expired before lock was obtained. + */ +pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs); + +/** + * Unlocks the mutex + * + * @param handle Handle of mutex to unlock + * + * @return PTE_OS_OK - Mutex successfully unlocked. + */ +pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle); +//@} + +/** @name Threads */ +//@{ +typedef int (*pte_osThreadEntryPoint)(void *params); + + +/** + * Creates a new thread. The thread must be started in a suspended state - it will be + * explicitly started when pte_osThreadStart() is called. + * + * @param entryPoint Entry point to the new thread. + * @param stackSize The initial stack size, in bytes. Note that this can be considered a minimum - + * for instance if the OS requires a larger stack space than what the caller specified. + * @param initialPriority The priority that the new thread should be initially set to. + * @param argv Parameter to pass to the new thread. + * @param ppte_osThreadHandle set to the handle of the new thread. + * + * @return PTE_OS_OK - New thread successfully created. + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create thread + */ +pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, + int stackSize, + int initialPriority, + void *argv, + pte_osThreadHandle* ppte_osThreadHandle); + +/** + * Starts executing the specified thread. + * + * @param osThreadHandle handle of the thread to start. + * + * @return PTE_OS_OK - thread successfully started. + */ +pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle); + +/** + * Causes the current thread to stop executing. + * + * @return Never returns (thread terminated) + */ +void pte_osThreadExit(); + +/** + * Waits for the specified thread to end. If the thread has already terminated, this returns + * immediately. + * + * @param threadHandle Handle fo thread to wait for. + * + * @return PTE_OS_OK - specified thread terminated. + */ +pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle); + +/** + * Returns the handle of the currently executing thread. + */ +pte_osThreadHandle pte_osThreadGetHandle(void); + +/** + * Returns the priority of the specified thread. + */ +int pte_osThreadGetPriority(pte_osThreadHandle threadHandle); + +/** + * Sets the priority of the specified thread. + * + * @return PTE_OS_OK - thread priority successfully set + */ +pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority); + +/** + * Frees resources associated with the specified thread. This is called after the thread has terminated + * and is no longer needed (e.g. after pthread_join returns). This call will always be made + * from a different context than that of the target thread. + */ +pte_osResult pte_osThreadDelete(pte_osThreadHandle handle); + +/** + * Frees resources associated with the specified thread and then causes the thread to exit. + * This is called after the thread has terminated and is no longer needed (e.g. after + * pthread_join returns). This call will always be made from the context of the target thread. + */ +pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle); + +/** + * Cancels the specified thread. This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel() + * to return @p PTE_OS_INTERRUPTED. + * + * @param threadHandle handle to the thread to cancel. + * + * @return Thread successfully canceled. + */ +pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle); + +/** + * Check if pte_osThreadCancel() has been called on the specified thread. + * + * @param threadHandle handle of thread to check the state of. + * + * @return PTE_OS_OK - Thread has not been cancelled + * @return PTE_OS_INTERRUPTED - Thread has been cancelled. + */ +pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle); + +/** + * Causes the current thread to sleep for the specified number of milliseconds. + */ +void pte_osThreadSleep(unsigned int msecs); + +/** + * Returns the maximum allowable priority + */ +int pte_osThreadGetMaxPriority(); + +/** + * Returns the minimum allowable priority + */ +int pte_osThreadGetMinPriority(); + +/** + * Returns the priority that should be used if the caller to pthread_create doesn't + * explicitly set one. + */ +int pte_osThreadGetDefaultPriority(); + +//@} + + +/** @name Semaphores */ +//@{ + +/** + * Creates a semaphore + * + * @param initialValue Initial value of the semaphore + * @param pHandle Set to the handle of the newly created semaphore. + * + * @return PTE_OS_OK - Semaphore successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore + */ +pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle); + +/** + * Deletes a semaphore and frees any associated resources. + * + * @param handle Handle of semaphore to delete. + * + * @return PTE_OS_OK - Semaphore successfully deleted. + */ +pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle); + +/** + * Posts to the semaphore + * + * @param handle Semaphore to release + * @param count Amount to increment the semaphore by. + * + * @return PTE_OS_OK - semaphore successfully released. + */ +pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count); + +/** + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + */ +pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); + +/** + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * Call must return immediately if pte_osThreadCancel() is called on the thread waiting for + * the semaphore. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + */ +pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); +//@} + + +/** @name Thread Local Storage */ +//@{ +/** + * Sets the thread specific value for the specified key for the + * currently executing thread. + * + * @param index The TLS key for the value. + * @param value The value to save + */ +pte_osResult pte_osTlsSetValue(unsigned int key, void * value); + +/** + * Retrieves the thread specific value for the specified key for + * the currently executing thread. If a value has not been set + * for this key, NULL should be returned (i.e. TLS values default + * to NULL). + * + * @param index The TLS key for the value. + * + * @return The value associated with @p key for the current thread. + */ +void * pte_osTlsGetValue(unsigned int key); + +/** + * Initializes the OS TLS support. This is called by the PTE library + * prior to performing ANY TLS operation. + */ +void pte_osTlsInit(void); + +/** + * Allocates a new TLS key. + * + * @param pKey On success will be set to the newly allocated key. + * + * @return PTE_OS_OK - TLS key successfully allocated. + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g. + * maximum number of keys reached). + */ +pte_osResult pte_osTlsAlloc(unsigned int *pKey); + +/** + * Frees the specified TLS key. + * + * @param index TLS key to free + * + * @return PTE_OS_OK - TLS key was successfully freed. + */ +pte_osResult pte_osTlsFree(unsigned int key); +//@} + +/** @name Atomic operations */ +//@{ + +/** + * Sets the target to the specified value as an atomic operation. + * + * \code + * origVal = *ptarg + * *ptarg = val + * return origVal + * \endcode + * + * @param pTarg Pointer to the value to be exchanged. + * @param val Value to be exchanged + * + * @return original value of destination + */ +int pte_osAtomicExchange(int *pTarg, int val); + +/** + * Performs an atomic compare-and-exchange oepration on the specified + * value. That is: + * + * \code + * origVal = *pdest + * if (*pdest == comp) + * then *pdest = exchange + * return origVal + * \endcode + * + * @param pdest Pointer to the destination value. + * @param exchange Exchange value (value to set destination to if destination == comparand) + * @param comp The value to compare to destination. + * + * @return Original value of destination + */ +int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp); + +/** + * Adds the value to target as an atomic operation + * + * \code + * origVal = *pdest + * *pAddend += value + * return origVal + * \endcode + * + * @param pdest Pointer to the variable to be updated. + * @param value Value to be added to the variable. + * + * @return Original value of destination + */ +int pte_osAtomicExchangeAdd(int volatile* pdest, int value); + +/** + * Decrements the destination. + * + * \code + * origVal = *pdest + * *pdest++ + * return origVal + * \endcode + * + * @param pdest Destination value to decrement + * + * @return Original destination value + */ +int pte_osAtomicDecrement(int *pdest); + +/** + * Increments the destination value + * + * \code + * origVal = *pdest; + * *pdest++; + * return origVal; + */ +int pte_osAtomicIncrement(int *pdest); +//@} + +struct timeb; + +int ftime(struct timeb *tb); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _OS_SUPPORT_H_ diff --git a/src/pthread/pte_getprocessors.c b/src/pthread/pte_getprocessors.c new file mode 100644 index 000000000..521d672a4 --- /dev/null +++ b/src/pthread/pte_getprocessors.c @@ -0,0 +1,69 @@ +/* + * pte_getprocessors.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +/* + * pte_getprocessors() + * + * Get the number of CPUs available to the process. + * + * If the available number of CPUs is 1 then pthread_spin_lock() + * will block rather than spin if the lock is already owned. + * + * pthread_spin_init() calls this routine when initialising + * a spinlock. If the number of available processors changes + * (after a call to SetProcessAffinityMask()) then only + * newly initialised spinlocks will notice. + */ +int +pte_getprocessors (int *count) +{ + int result = 0; + + *count = 1; + + return (result); +} diff --git a/src/pthread/pte_is_attr.c b/src/pthread/pte_is_attr.c new file mode 100644 index 000000000..0c869cea5 --- /dev/null +++ b/src/pthread/pte_is_attr.c @@ -0,0 +1,53 @@ +/* + * pte_is_attr.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +int +pte_is_attr (const pthread_attr_t * attr) +{ + /* Return 0 if the attr object is valid, non-zero otherwise. */ + + return (attr == NULL || + *attr == NULL || (*attr)->valid != PTE_ATTR_VALID); +} diff --git a/src/pthread/pte_mutex_check_need_init.c b/src/pthread/pte_mutex_check_need_init.c new file mode 100644 index 000000000..2c923edc6 --- /dev/null +++ b/src/pthread/pte_mutex_check_need_init.c @@ -0,0 +1,129 @@ +/* + * pte_mutex_check_need_init.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "pthread.h" +#include "implement.h" + + +static struct pthread_mutexattr_t_ pte_recursive_mutexattr_s = + { + PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_RECURSIVE + }; +static struct pthread_mutexattr_t_ pte_errorcheck_mutexattr_s = + { + PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK + }; +static pthread_mutexattr_t pte_recursive_mutexattr = &pte_recursive_mutexattr_s; +static pthread_mutexattr_t pte_errorcheck_mutexattr = &pte_errorcheck_mutexattr_s; + + +int +pte_mutex_check_need_init (pthread_mutex_t * mutex) +{ + register int result = 0; + register pthread_mutex_t mtx; + + /* + * The following guarded test is specifically for statically + * initialised mutexes (via PTHREAD_MUTEX_INITIALIZER). + * + * Note that by not providing this synchronisation we risk + * introducing race conditions into applications which are + * correctly written. + * + * Approach + * -------- + * We know that static mutexes will not be PROCESS_SHARED + * so we can serialise access to internal state using + * critical sections rather than mutexes. + * + * If using a single global lock slows applications down too much, + * multiple global locks could be created and hashed on some random + * value associated with each mutex, the pointer perhaps. At a guess, + * a good value for the optimal number of global locks might be + * the number of processors + 1. + * + */ + + + pte_osMutexLock (pte_mutex_test_init_lock); + + /* + * We got here possibly under race + * conditions. Check again inside the critical section + * and only initialise if the mutex is valid (not been destroyed). + * If a static mutex has been destroyed, the application can + * re-initialise it only by calling pthread_mutex_init() + * explicitly. + */ + mtx = *mutex; + + if (mtx == PTHREAD_MUTEX_INITIALIZER) + { + result = pthread_mutex_init (mutex, NULL); + } + else if (mtx == PTHREAD_RECURSIVE_MUTEX_INITIALIZER) + { + result = pthread_mutex_init (mutex, &pte_recursive_mutexattr); + } + else if (mtx == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + result = pthread_mutex_init (mutex, &pte_errorcheck_mutexattr); + } + else if (mtx == NULL) + { + /* + * The mutex has been destroyed while we were waiting to + * initialise it, so the operation that caused the + * auto-initialisation should fail. + */ + result = EINVAL; + } + + pte_osMutexUnlock(pte_mutex_test_init_lock); + + return (result); +} + + + diff --git a/src/pthread/pte_new.c b/src/pthread/pte_new.c new file mode 100644 index 000000000..d3614aa63 --- /dev/null +++ b/src/pthread/pte_new.c @@ -0,0 +1,93 @@ +/* + * pte_new.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + + +#include "pthread.h" +#include "implement.h" + + +pthread_t +pte_new (void) +{ + pthread_t t; + pthread_t nil = {NULL, 0}; + pte_thread_t * tp; + + /* + * If there's a reusable pthread_t then use it. + */ + t = pte_threadReusePop (); + + if (NULL != t.p) + { + tp = (pte_thread_t *) t.p; + } + else + { + /* No reuse threads available */ + tp = (pte_thread_t *) calloc (1, sizeof(pte_thread_t)); + + if (tp == NULL) + { + return nil; + } + + /* ptHandle.p needs to point to it's parent pte_thread_t. */ + t.p = tp->ptHandle.p = tp; + t.x = tp->ptHandle.x = 0; + } + + /* Set default state. */ + tp->sched_priority = pte_osThreadGetMinPriority(); + + tp->detachState = PTHREAD_CREATE_JOINABLE; + tp->cancelState = PTHREAD_CANCEL_ENABLE; + tp->cancelType = PTHREAD_CANCEL_DEFERRED; + tp->cancelLock = PTHREAD_MUTEX_INITIALIZER; + tp->threadLock = PTHREAD_MUTEX_INITIALIZER; + + return t; + +} diff --git a/src/pthread/pte_osal.h b/src/pthread/pte_osal.h new file mode 100644 index 000000000..fd5208367 --- /dev/null +++ b/src/pthread/pte_osal.h @@ -0,0 +1,15 @@ + +#ifndef _OS_SUPPORT_H_ +#define _OS_SUPPORT_H_ + +// Platform specific one must be included first +//#include "psp_osal.h" + +#include +#include + +#include "pte_generic_osal.h" + + + +#endif // _OS_SUPPORT_H diff --git a/src/pthread/pte_relmillisecs.c b/src/pthread/pte_relmillisecs.c new file mode 100644 index 000000000..dc78fd0eb --- /dev/null +++ b/src/pthread/pte_relmillisecs.c @@ -0,0 +1,97 @@ +/* + * pte_relmillisecs.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + +typedef long long int64_t; + +unsigned int +pte_relmillisecs (const struct timespec * abstime) +{ + const long long NANOSEC_PER_MILLISEC = 1000000; + const long long MILLISEC_PER_SEC = 1000; + unsigned int milliseconds; + long long tmpAbsMilliseconds; + long tmpCurrMilliseconds; + struct timeb currSysTime; + + /* + * Calculate timeout as milliseconds from current system time. + */ + + /* + * subtract current system time from abstime in a way that checks + * that abstime is never in the past, or is never equivalent to the + * defined INFINITE value (0xFFFFFFFF). + * + * Assume all integers are unsigned, i.e. cannot test if less than 0. + */ + tmpAbsMilliseconds = (int64_t)abstime->tv_sec * MILLISEC_PER_SEC; + tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; + + /* get current system time */ + + _ftime(&currSysTime); + + tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC; + tmpCurrMilliseconds += (int64_t) currSysTime.millitm; + + if (tmpAbsMilliseconds > tmpCurrMilliseconds) + { + milliseconds = (unsigned int) (tmpAbsMilliseconds - tmpCurrMilliseconds); + if (milliseconds == 0xFFFFFFFF) + { + /* Timeouts must be finite */ + milliseconds--; + } + } + else + { + /* The abstime given is in the past */ + milliseconds = 0; + } + + return milliseconds; +} diff --git a/src/pthread/pte_reuse.c b/src/pthread/pte_reuse.c new file mode 100644 index 000000000..87e3e540a --- /dev/null +++ b/src/pthread/pte_reuse.c @@ -0,0 +1,158 @@ +/* + * pte_threadReuse.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + + +/* + * How it works: + * A pthread_t is a struct which is normally passed/returned by + * value to/from pthreads routines. Applications are therefore storing + * a copy of the struct as it is at that time. + * + * The original pthread_t struct plus all copies of it contain the address of + * the thread state struct pte_thread_t_ (p), plus a reuse counter (x). Each + * pte_thread_t contains the original copy of it's pthread_t. + * Once malloced, a pte_thread_t_ struct is not freed until the process exits. + * + * The thread reuse stack is a simple LILO stack managed through a singly + * linked list element in the pte_thread_t. + * + * Each time a thread is destroyed, the pte_thread_t address is pushed onto the + * reuse stack after it's ptHandle's reuse counter has been incremented. + * + * The following can now be said from this: + * - two pthread_t's are identical if their pte_thread_t reference pointers + * are equal and their reuse counters are equal. That is, + * + * equal = (a.p == b.p && a.x == b.x) + * + * - a pthread_t copy refers to a destroyed thread if the reuse counter in + * the copy is not equal to the reuse counter in the original. + * + * threadDestroyed = (copy.x != ((pte_thread_t *)copy.p)->ptHandle.x) + * + */ + +/* + * Pop a clean pthread_t struct off the reuse stack. + */ +pthread_t +pte_threadReusePop (void) +{ + pthread_t t = {NULL, 0}; + + + pte_osMutexLock (pte_thread_reuse_lock); + + if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseTop) + { + pte_thread_t * tp; + + tp = pte_threadReuseTop; + + pte_threadReuseTop = tp->prevReuse; + + if (PTE_THREAD_REUSE_EMPTY == pte_threadReuseTop) + { + pte_threadReuseBottom = PTE_THREAD_REUSE_EMPTY; + } + + tp->prevReuse = NULL; + + t = tp->ptHandle; + } + + pte_osMutexUnlock(pte_thread_reuse_lock); + + return t; + +} + +/* + * Push a clean pthread_t struct onto the reuse stack. + * Must be re-initialised when reused. + * All object elements (mutexes, events etc) must have been either + * detroyed before this, or never initialised. + */ +void +pte_threadReusePush (pthread_t thread) +{ + pte_thread_t * tp = (pte_thread_t *) thread.p; + pthread_t t; + + + pte_osMutexLock (pte_thread_reuse_lock); + + t = tp->ptHandle; + memset(tp, 0, sizeof(pte_thread_t)); + + /* Must restore the original POSIX handle that we just wiped. */ + tp->ptHandle = t; + + /* Bump the reuse counter now */ +#ifdef PTE_THREAD_ID_REUSE_INCREMENT + tp->ptHandle.x += PTE_THREAD_ID_REUSE_INCREMENT; +#else + tp->ptHandle.x++; +#endif + + tp->prevReuse = PTE_THREAD_REUSE_EMPTY; + + if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseBottom) + { + pte_threadReuseBottom->prevReuse = tp; + } + else + { + pte_threadReuseTop = tp; + } + + pte_threadReuseBottom = tp; + + pte_osMutexUnlock(pte_thread_reuse_lock); +} diff --git a/src/pthread/pte_rwlock_cancelwrwait.c b/src/pthread/pte_rwlock_cancelwrwait.c new file mode 100644 index 000000000..ecac4a593 --- /dev/null +++ b/src/pthread/pte_rwlock_cancelwrwait.c @@ -0,0 +1,56 @@ +/* + * pte_rwlock_cancelwrwait.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +void +pte_rwlock_cancelwrwait (void *arg) +{ + pthread_rwlock_t rwl = (pthread_rwlock_t) arg; + + rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + + (void) pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); +} diff --git a/src/pthread/pte_rwlock_check_need_init.c b/src/pthread/pte_rwlock_check_need_init.c new file mode 100644 index 000000000..3757c7402 --- /dev/null +++ b/src/pthread/pte_rwlock_check_need_init.c @@ -0,0 +1,102 @@ +/* + * pthread_rwlock_check_need_init.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "pthread.h" +#include "implement.h" + +int +pte_rwlock_check_need_init (pthread_rwlock_t * rwlock) +{ + int result = 0; + + /* + * The following guarded test is specifically for statically + * initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER). + * + * Note that by not providing this synchronisation we risk + * introducing race conditions into applications which are + * correctly written. + * + * Approach + * -------- + * We know that static rwlocks will not be PROCESS_SHARED + * so we can serialise access to internal state using + * critical sections rather than mutexes. + * + * If using a single global lock slows applications down too much, + * multiple global locks could be created and hashed on some random + * value associated with each mutex, the pointer perhaps. At a guess, + * a good value for the optimal number of global locks might be + * the number of processors + 1. + * + */ + + + pte_osMutexLock (pte_rwlock_test_init_lock); + + /* + * We got here possibly under race + * conditions. Check again inside the critical section + * and only initialise if the rwlock is valid (not been destroyed). + * If a static rwlock has been destroyed, the application can + * re-initialise it only by calling pthread_rwlock_init() + * explicitly. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pthread_rwlock_init (rwlock, NULL); + } + else if (*rwlock == NULL) + { + /* + * The rwlock has been destroyed while we were waiting to + * initialise it, so the operation that caused the + * auto-initialisation should fail. + */ + result = EINVAL; + } + + pte_osMutexUnlock(pte_rwlock_test_init_lock); + + return result; +} diff --git a/src/pthread/pte_spinlock_check_need_init.c b/src/pthread/pte_spinlock_check_need_init.c new file mode 100644 index 000000000..f21fb3528 --- /dev/null +++ b/src/pthread/pte_spinlock_check_need_init.c @@ -0,0 +1,89 @@ +/* + * pte_spinlock_check_need_init.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pte_spinlock_check_need_init (pthread_spinlock_t * lock) +{ + int result = 0; + + /* + * The following guarded test is specifically for statically + * initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER). + * + * Note that by not providing this synchronisation we risk + * introducing race conditions into applications which are + * correctly written. + */ + + + pte_osMutexLock (pte_spinlock_test_init_lock); + + /* + * We got here possibly under race + * conditions. Check again inside the critical section + * and only initialise if the spinlock is valid (not been destroyed). + * If a static spinlock has been destroyed, the application can + * re-initialise it only by calling pthread_spin_init() + * explicitly. + */ + if (*lock == PTHREAD_SPINLOCK_INITIALIZER) + { + result = pthread_spin_init (lock, PTHREAD_PROCESS_PRIVATE); + } + else if (*lock == NULL) + { + /* + * The spinlock has been destroyed while we were waiting to + * initialise it, so the operation that caused the + * auto-initialisation should fail. + */ + result = EINVAL; + } + + pte_osMutexUnlock(pte_spinlock_test_init_lock); + + return (result); +} diff --git a/src/pthread/pte_threadDestroy.c b/src/pthread/pte_threadDestroy.c new file mode 100644 index 000000000..a60a794b3 --- /dev/null +++ b/src/pthread/pte_threadDestroy.c @@ -0,0 +1,101 @@ +/* + * pte_threadDestroy.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + + + +static void +pte_threadDestroyCommon (pthread_t thread, unsigned char shouldThreadExit) +{ + pte_thread_t * tp = (pte_thread_t *) thread.p; + pte_thread_t threadCopy; + + if (tp != NULL) + { + /* + * Copy thread state so that the thread can be atomically NULLed. + */ + memcpy (&threadCopy, tp, sizeof (threadCopy)); + + /* + * Thread ID structs are never freed. They're NULLed and reused. + * This also sets the thread to PThreadStateInitial (invalid). + */ + pte_threadReusePush (thread); + + (void) pthread_mutex_destroy(&threadCopy.cancelLock); + (void) pthread_mutex_destroy(&threadCopy.threadLock); + + if (threadCopy.threadId != 0) + { + if (shouldThreadExit) + { + pte_osThreadExitAndDelete(threadCopy.threadId); + } + else + { + pte_osThreadDelete(threadCopy.threadId); + } + } + + + + } +} /* pte_threadDestroy */ + +void pte_threadDestroy (pthread_t thread) +{ + pte_threadDestroyCommon(thread,0); +} + +void pte_threadExitAndDestroy (pthread_t thread) +{ + pte_threadDestroyCommon(thread,1); +} + diff --git a/src/pthread/pte_threadStart.c b/src/pthread/pte_threadStart.c new file mode 100644 index 000000000..a58d22661 --- /dev/null +++ b/src/pthread/pte_threadStart.c @@ -0,0 +1,248 @@ +/* + * pte_threadStart.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +#if defined(PTE_CLEANUP_CXX) + +# if defined(__GNUC__) && __GNUC__ < 3 +# include +# else +# include +using +std::terminate_handler; +using +std::terminate; +using +std::set_terminate; +# endif + +typedef terminate_handler terminate_function; + +static terminate_function pte_oldTerminate; + +void +pte_terminate () +{ + set_terminate (pte_oldTerminate); + (void) pte_thread_detach_np(); +// terminate (); +} + +#endif + +int pte_threadStart (void *vthreadParms) +{ + ThreadParms * threadParms = (ThreadParms *) vthreadParms; + pthread_t self; + pte_thread_t * sp; + void *(*start) (void *); + void * arg; + +#ifdef PTE_CLEANUP_C +#include + + int setjmp_rc; +#endif + + void * status = (void *) 0; + + self = threadParms->tid; + sp = (pte_thread_t *) self.p; + start = threadParms->start; + arg = threadParms->arg; +// free (threadParms); + + pthread_setspecific (pte_selfThreadKey, sp); + + sp->state = PThreadStateRunning; + +#ifdef PTE_CLEANUP_C + + + setjmp_rc = setjmp (sp->start_mark); + + + if (0 == setjmp_rc) + { + + /* + * Run the caller's routine; + */ + sp->exitStatus = status = (*start) (arg); + } + else + { + switch (setjmp_rc) + { + case PTE_EPS_CANCEL: + status = sp->exitStatus = PTHREAD_CANCELED; + break; + case PTE_EPS_EXIT: + status = sp->exitStatus; + break; + default: + status = sp->exitStatus = PTHREAD_CANCELED; + break; + } + } + +#else /* PTE_CLEANUP_C */ + +#ifdef PTE_CLEANUP_CXX + + pte_oldTerminate = set_terminate (&pte_terminate); + + try + { + /* + * Run the caller's routine in a nested try block so that we + * can run the user's terminate function, which may call + * pthread_exit() or be canceled. + */ + try + { + status = sp->exitStatus = (*start) (arg); + } + catch (pte_exception &) + { + /* + * Pass these through to the outer block. + */ + throw; + } + catch (...) + { + /* + * We want to run the user's terminate function if supplied. + * That function may call pthread_exit() or be canceled, which will + * be handled by the outer try block. + * + * pte_terminate() will be called if there is no user + * supplied function. + */ + + terminate_function + term_func = set_terminate (0); + set_terminate (term_func); + + if (term_func != 0) + { + term_func (); + } + + throw; + } + } + catch (pte_exception_cancel &) + { + /* + * Thread was canceled. + */ + status = sp->exitStatus = PTHREAD_CANCELED; + } + catch (pte_exception_exit &) + { + /* + * Thread was exited via pthread_exit(). + */ + status = sp->exitStatus; + } + catch (...) + { + /* + * A system unexpected exception has occurred running the user's + * terminate routine. We get control back within this block - cleanup + * and release the exception out of thread scope. + */ + status = sp->exitStatus = PTHREAD_CANCELED; + (void) pthread_mutex_lock (&sp->cancelLock); + sp->state = PThreadStateException; + (void) pthread_mutex_unlock (&sp->cancelLock); + (void) pte_thread_detach_np(); + (void) set_terminate (pte_oldTerminate); + throw; + + /* + * Never reached. + */ + } + + (void) set_terminate (pte_oldTerminate); + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* PTE_CLEANUP_CXX */ +#endif /* PTE_CLEANUP_C */ + + /* + * We need to cleanup the pthread now if we have + * been statically linked, in which case the cleanup + * in dllMain won't get done. Joinable threads will + * only be partially cleaned up and must be fully cleaned + * up by pthread_join() or pthread_detach(). + * + * Note: if this library has been statically linked, + * implicitly created pthreads (those created + * for OS threads which have called pthreads routines) + * must be cleaned up explicitly by the application + * (by calling pte_thread_detach_np()). + */ + (void) pte_thread_detach_and_exit_np (); + + //pte_osThreadExit(status); + + /* + * Never reached. + */ + + return (unsigned) status; + +} /* pte_threadStart */ + diff --git a/src/pthread/pte_throw.c b/src/pthread/pte_throw.c new file mode 100644 index 000000000..81f616f73 --- /dev/null +++ b/src/pthread/pte_throw.c @@ -0,0 +1,142 @@ +/* + * pte_throw.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#include + +#include "pthread.h" +#include "implement.h" + +/* + * pte_throw + * + * All canceled and explicitly exited POSIX threads go through + * here. This routine knows how to exit both POSIX initiated threads and + * 'implicit' POSIX threads for each of the possible language modes (C, + * C++). + */ +void +pte_throw (unsigned int exception) +{ + /* + * Don't use pthread_self() to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + pte_thread_t * sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey); + + + if (exception != PTE_EPS_CANCEL && exception != PTE_EPS_EXIT) + { + /* Should never enter here */ + exit (1); + } + + if (NULL == sp || sp->implicit) + { + /* + * We're inside a non-POSIX initialised OS thread + * so there is no point to jump or throw back to. Just do an + * explicit thread exit here after cleaning up POSIX + * residue (i.e. cleanup handlers, POSIX thread handle etc). + */ + unsigned exitCode = 0; + + switch (exception) + { + case PTE_EPS_CANCEL: + exitCode = (unsigned) PTHREAD_CANCELED; + break; + case PTE_EPS_EXIT: + exitCode = (unsigned) sp->exitStatus;; + break; + } + + pte_thread_detach_and_exit_np (); + +// pte_osThreadExit((void*)exitCode); + + } + +#ifdef PTE_CLEANUP_C + + pte_pop_cleanup_all (1); + longjmp (sp->start_mark, exception); + +#else /* PTE_CLEANUP_C */ + +#ifdef PTE_CLEANUP_CXX + + switch (exception) + { + case PTE_EPS_CANCEL: + throw pte_exception_cancel (); + break; + case PTE_EPS_EXIT: + throw pte_exception_exit (); + break; + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* PTE_CLEANUP_CXX */ + +#endif /* PTE_CLEANUP_C */ + + /* Never reached */ +} + + +void +pte_pop_cleanup_all (int execute) +{ + while (NULL != pte_pop_cleanup (execute)) + { + } +} + + +unsigned int +pte_get_exception_services_code (void) +{ + return (unsigned int) NULL; +} diff --git a/src/pthread/pte_tkAssocCreate.c b/src/pthread/pte_tkAssocCreate.c new file mode 100644 index 000000000..83aec9680 --- /dev/null +++ b/src/pthread/pte_tkAssocCreate.c @@ -0,0 +1,126 @@ +/* + * pte_tkAssocCreate.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pte_tkAssocCreate (pte_thread_t * sp, pthread_key_t key) +/* + * ------------------------------------------------------------------- + * This routine creates an association that + * is unique for the given (thread,key) combination.The association + * is referenced by both the thread and the key. + * This association allows us to determine what keys the + * current thread references and what threads a given key + * references. + * See the detailed description + * at the beginning of this file for further details. + * + * Notes: + * 1) New associations are pushed to the beginning of the + * chain so that the internal pte_selfThreadKey association + * is always last, thus allowing selfThreadExit to + * be implicitly called last by pthread_exit. + * 2) + * + * Parameters: + * thread + * current running thread. + * key + * key on which to create an association. + * Returns: + * 0 - if successful, + * ENOMEM - not enough memory to create assoc or other object + * EINVAL - an internal error occurred + * ENOSYS - an internal error occurred + * ------------------------------------------------------------------- + */ +{ + ThreadKeyAssoc *assoc; + + /* + * Have to create an association and add it + * to both the key and the thread. + * + * Both key->keyLock and thread->threadLock are locked on + * entry to this routine. + */ + assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc)); + + if (assoc == NULL) + { + return ENOMEM; + } + + assoc->thread = sp; + assoc->key = key; + + /* + * Register assoc with key + */ + assoc->prevThread = NULL; + assoc->nextThread = (ThreadKeyAssoc *) key->threads; + if (assoc->nextThread != NULL) + { + assoc->nextThread->prevThread = assoc; + } + key->threads = (void *) assoc; + + /* + * Register assoc with thread + */ + assoc->prevKey = NULL; + assoc->nextKey = (ThreadKeyAssoc *) sp->keys; + if (assoc->nextKey != NULL) + { + assoc->nextKey->prevKey = assoc; + } + sp->keys = (void *) assoc; + + return (0); + +} /* pte_tkAssocCreate */ diff --git a/src/pthread/pte_tkAssocDestroy.c b/src/pthread/pte_tkAssocDestroy.c new file mode 100644 index 000000000..c874c2ee5 --- /dev/null +++ b/src/pthread/pte_tkAssocDestroy.c @@ -0,0 +1,122 @@ +/* + * pte_tkAssocDestroy.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +void +pte_tkAssocDestroy (ThreadKeyAssoc * assoc) +/* + * ------------------------------------------------------------------- + * This routine releases all resources for the given ThreadKeyAssoc + * once it is no longer being referenced + * ie) either the key or thread has stopped referencing it. + * + * Parameters: + * assoc + * an instance of ThreadKeyAssoc. + * Returns: + * N/A + * ------------------------------------------------------------------- + */ +{ + + /* + * Both key->keyLock and thread->threadLock are locked on + * entry to this routine. + */ + if (assoc != NULL) + { + ThreadKeyAssoc * prev, * next; + + /* Remove assoc from thread's keys chain */ + prev = assoc->prevKey; + next = assoc->nextKey; + if (prev != NULL) + { + prev->nextKey = next; + } + if (next != NULL) + { + next->prevKey = prev; + } + + if (assoc->thread->keys == assoc) + { + /* We're at the head of the thread's keys chain */ + assoc->thread->keys = next; + } + if (assoc->thread->nextAssoc == assoc) + { + /* + * Thread is exiting and we're deleting the assoc to be processed next. + * Hand thread the assoc after this one. + */ + assoc->thread->nextAssoc = next; + } + + /* Remove assoc from key's threads chain */ + prev = assoc->prevThread; + next = assoc->nextThread; + if (prev != NULL) + { + prev->nextThread = next; + } + if (next != NULL) + { + next->prevThread = prev; + } + + if (assoc->key->threads == assoc) + { + /* We're at the head of the key's threads chain */ + assoc->key->threads = next; + } + + free (assoc); + } + +} /* pte_tkAssocDestroy */ diff --git a/src/pthread/pte_types.h b/src/pthread/pte_types.h new file mode 100644 index 000000000..4fc2b422b --- /dev/null +++ b/src/pthread/pte_types.h @@ -0,0 +1,12 @@ +/* pte_types.h */ + +#ifndef PTE_TYPES_H +#define PTE_TYPES_H + +#include +#include +#include + +typedef int pid_t; + +#endif /* PTE_TYPES_H */ diff --git a/src/pthread/pthread.h b/src/pthread/pthread.h new file mode 100644 index 000000000..a66a371da --- /dev/null +++ b/src/pthread/pthread.h @@ -0,0 +1,1010 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +#include + +#include + +#define PTE_VERSION 2,8,0,0 +#define PTE_VERSION_STRING "2, 8, 0, 0\0" + +/* There are two implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The two implementations are: + * + * C + * C++ + * + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( PTE_CLEANUP_CXX ) && !defined( PTE_CLEANUP_C ) +# define PTE_CLEANUP_C +#endif + +#undef PTE_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTE_LEVEL +#define PTE_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTE_LEVEL +#define PTE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTE_LEVEL_MAX 3 + +#if !defined(PTE_LEVEL) +#define PTE_LEVEL PTE_LEVEL_MAX +/* Include everything */ +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +#include + +#include +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum +{ + PTE_FALSE = 0, + PTE_TRUE = (! PTE_FALSE) +}; + + + /* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-embedded. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + + /* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200112L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200112L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200112L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200112L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + + /* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + + /* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + + /* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-embedded. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + + /* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ + typedef struct + { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ + } pte_handle_t; + + typedef pte_handle_t pthread_t; + typedef struct pthread_attr_t_ * pthread_attr_t; + typedef struct pthread_once_t_ pthread_once_t; + typedef struct pthread_key_t_ * pthread_key_t; + typedef struct pthread_mutex_t_ * pthread_mutex_t; + typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; + typedef struct pthread_cond_t_ * pthread_cond_t; + typedef struct pthread_condattr_t_ * pthread_condattr_t; + typedef struct pthread_rwlock_t_ * pthread_rwlock_t; + typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; + typedef struct pthread_spinlock_t_ * pthread_spinlock_t; + typedef struct pthread_barrier_t_ * pthread_barrier_t; + typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + + /* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + + enum + { + /* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + + /* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + + /* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + PTHREAD_SCOPE_PROCESS_VFPU = 2, /* PSP specific */ + + /* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + + /* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + + /* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + + /* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 + }; + + /* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *) -1) + + + /* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTE_FALSE, 0, 0, 0} + + struct pthread_once_t_ + { + int state; + void * semaphore; + int numSemaphoreUsers; + int done; /* indicates if user function has been executed */ +// void * lock; +// int reserved1; +// int reserved2; + }; + + + /* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) + + /* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + + /* + * Mutex types. + */ + enum + { + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL + }; + + + typedef struct pte_cleanup_t pte_cleanup_t; + + typedef void (* pte_cleanup_callback_t)(void *); + + struct pte_cleanup_t + { + pte_cleanup_callback_t routine; + void *arg; + struct pte_cleanup_t *prev; + }; + +#ifdef PTE_CLEANUP_C + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + pte_cleanup_t _cleanup; \ + \ + pte_push_cleanup( &_cleanup, (pte_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) pte_pop_cleanup( _execute ); \ + } + +#else /* PTE_CLEANUP_C */ + +#ifdef PTE_CLEANUP_CXX + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup + { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + pte_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + pte_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((pte_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* PTE_CLEANUP_CXX */ + +#endif /* PTE_CLEANUP_C */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + + int pthread_init (void); + void pthread_terminate (void); + + /* + * PThread Attribute Functions + */ + int pthread_attr_init (pthread_attr_t * attr); + + int pthread_attr_destroy (pthread_attr_t * attr); + + int pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + + int pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + + int pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + + int pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + + int pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + + int pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + + int pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + + int pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + + int pthread_attr_setschedpolicy (pthread_attr_t *, + int); + + int pthread_attr_getschedpolicy (pthread_attr_t *, + int *); + + int pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + + int pthread_attr_getinheritsched(pthread_attr_t * attr, + int * inheritsched); + + int pthread_attr_setscope (pthread_attr_t *, + int); + + int pthread_attr_getscope (const pthread_attr_t *, + int *); + + /* + * PThread Functions + */ + int pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), + void *arg); + + int pthread_detach (pthread_t tid); + + int pthread_equal (pthread_t t1, + pthread_t t2); + + void pthread_exit (void *value_ptr); + + int pthread_join (pthread_t thread, + void **value_ptr); + + pthread_t pthread_self (void); + + int pthread_cancel (pthread_t thread); + + int pthread_setcancelstate (int state, + int *oldstate); + + int pthread_setcanceltype (int type, + int *oldtype); + + void pthread_testcancel (void); + + int pthread_once (pthread_once_t * once_control, + void (*init_routine) (void)); + +#if PTE_LEVEL >= PTE_LEVEL_MAX + pte_cleanup_t * pte_pop_cleanup (int execute); + + void pte_push_cleanup (pte_cleanup_t * cleanup, + void (*routine) (void *), + void *arg); +#endif /* PTE_LEVEL >= PTE_LEVEL_MAX */ + + /* + * Thread Specific Data Functions + */ + int pthread_key_create (pthread_key_t * key, + void (*destructor) (void *)); + + int pthread_key_delete (pthread_key_t key); + + int pthread_setspecific (pthread_key_t key, + const void *value); + + void * pthread_getspecific (pthread_key_t key); + + + /* + * Mutex Attribute Functions + */ + int pthread_mutexattr_init (pthread_mutexattr_t * attr); + + int pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + + int pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + + int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + + int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); + int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + + /* + * Barrier Attribute Functions + */ + int pthread_barrierattr_init (pthread_barrierattr_t * attr); + + int pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + + int pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + + int pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + + /* + * Mutex Functions + */ + int pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + + int pthread_mutex_destroy (pthread_mutex_t * mutex); + + int pthread_mutex_lock (pthread_mutex_t * mutex); + + int pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abstime); + + int pthread_mutex_trylock (pthread_mutex_t * mutex); + + int pthread_mutex_unlock (pthread_mutex_t * mutex); + + /* + * Spinlock Functions + */ + int pthread_spin_init (pthread_spinlock_t * lock, int pshared); + + int pthread_spin_destroy (pthread_spinlock_t * lock); + + int pthread_spin_lock (pthread_spinlock_t * lock); + + int pthread_spin_trylock (pthread_spinlock_t * lock); + + int pthread_spin_unlock (pthread_spinlock_t * lock); + + /* + * Barrier Functions + */ + int pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + + int pthread_barrier_destroy (pthread_barrier_t * barrier); + + int pthread_barrier_wait (pthread_barrier_t * barrier); + + /* + * Condition Variable Attribute Functions + */ + int pthread_condattr_init (pthread_condattr_t * attr); + + int pthread_condattr_destroy (pthread_condattr_t * attr); + + int pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + + int pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + + /* + * Condition Variable Functions + */ + int pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + + int pthread_cond_destroy (pthread_cond_t * cond); + + int pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + + int pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + + int pthread_cond_signal (pthread_cond_t * cond); + + int pthread_cond_broadcast (pthread_cond_t * cond); + + /* + * Scheduling + */ + int pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + + int pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + + int pthread_setconcurrency (int); + + int pthread_getconcurrency (void); + + /* + * Read-Write Lock Functions + */ + int pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + + int pthread_rwlock_destroy(pthread_rwlock_t *lock); + + int pthread_rwlock_tryrdlock(pthread_rwlock_t *); + + int pthread_rwlock_trywrlock(pthread_rwlock_t *); + + int pthread_rwlock_rdlock(pthread_rwlock_t *lock); + + int pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + + int pthread_rwlock_wrlock(pthread_rwlock_t *lock); + + int pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + + int pthread_rwlock_unlock(pthread_rwlock_t *lock); + + int pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + + int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + + int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + + int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTE_LEVEL >= PTE_LEVEL_MAX - 1 + + /* + * Signal Functions. Should be defined in but we might + * already have signal.h that don't define these. + */ + int pthread_kill(pthread_t thread, int sig); + + /* + * Non-portable functions + */ + + /* + * Compatibility with Linux. + */ + int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); + int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + + /* + * Possibly supported by other POSIX threads implementations + */ + int pthread_delay_np (struct timespec * interval); + int pthread_num_processors_np(void); + + /* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ + void * pthread_timechange_handler_np(void *); + +#endif /*PTE_LEVEL >= PTE_LEVEL_MAX - 1 */ + +#ifdef __cplusplus +} +#endif /* cplusplus */ + +#if PTE_LEVEL >= PTE_LEVEL_MAX + + + +#endif /* PTE_LEVEL >= PTE_LEVEL_MAX */ + + /* + * Some compiler environments don't define some things. + */ +# define _ftime ftime +# define _timeb timeb + +#ifdef __cplusplus + + /* + * Internal exceptions + */ + class pte_exception {}; + class pte_exception_cancel : public pte_exception {}; + class pte_exception_exit : public pte_exception {}; + +#endif + + +#ifdef PTE_CXX_EXCEPTIONS + + /* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define catch( E ) \ + catch( pte_exception & ) { throw; } \ + catch( E ) + +#endif /* ! PTE_CXX_EXCEPTIONS */ + +#undef PTE_LEVEL +#undef PTE_LEVEL_MAX + +#endif /* PTHREAD_H */ diff --git a/src/pthread/pthread_attr_destroy.c b/src/pthread/pthread_attr_destroy.c new file mode 100644 index 000000000..221218c94 --- /dev/null +++ b/src/pthread/pthread_attr_destroy.c @@ -0,0 +1,87 @@ +/* + * pthread_attr_destroy.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_destroy (pthread_attr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Destroys a thread attributes object. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * + * DESCRIPTION + * Destroys a thread attributes object. + * + * NOTES: + * 1) Does not affect threads created with 'attr'. + * + * RESULTS + * 0 successfully destroyed attr, + * EINVAL 'attr' is invalid. + * + * ------------------------------------------------------ + */ +{ + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + /* + * Set the attribute object to a specific invalid value. + */ + (*attr)->valid = 0; + free (*attr); + *attr = NULL; + + return 0; +} diff --git a/src/pthread/pthread_attr_getdetachstate.c b/src/pthread/pthread_attr_getdetachstate.c new file mode 100644 index 000000000..0729377b3 --- /dev/null +++ b/src/pthread/pthread_attr_getdetachstate.c @@ -0,0 +1,93 @@ +/* + * pthread_attr_getdetachstate.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function determines whether threads created with + * 'attr' will run detached. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * detachstate + * pointer to an integer into which is returned one + * of: + * + * PTHREAD_CREATE_JOINABLE + * Thread ID is valid, must be joined + * + * PTHREAD_CREATE_DETACHED + * Thread ID is invalid, cannot be joined, + * canceled, or modified + * + * + * DESCRIPTION + * This function determines whether threads created with + * 'attr' will run detached. + * + * NOTES: + * 1) You cannot join or cancel detached threads. + * + * RESULTS + * 0 successfully retrieved detach state, + * EINVAL 'attr' is invalid + * + * ------------------------------------------------------ + */ +{ + if (pte_is_attr (attr) != 0 || detachstate == NULL) + { + *detachstate = PTHREAD_CREATE_DETACHED; + return EINVAL; + } + + *detachstate = (*attr)->detachstate; + return 0; +} diff --git a/src/pthread/pthread_attr_getinheritsched.c b/src/pthread/pthread_attr_getinheritsched.c new file mode 100644 index 000000000..a46a7407d --- /dev/null +++ b/src/pthread/pthread_attr_getinheritsched.c @@ -0,0 +1,57 @@ +/* + * pthread_attr_getinheritsched.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_getinheritsched (pthread_attr_t * attr, int *inheritsched) +{ + if (pte_is_attr (attr) != 0 || inheritsched == NULL) + { + return EINVAL; + } + + *inheritsched = (*attr)->inheritsched; + return 0; +} diff --git a/src/pthread/pthread_attr_getschedparam.c b/src/pthread/pthread_attr_getschedparam.c new file mode 100644 index 000000000..782403d59 --- /dev/null +++ b/src/pthread/pthread_attr_getschedparam.c @@ -0,0 +1,61 @@ +/* + * pthread_attr_getschedparam.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_getschedparam (const pthread_attr_t * attr, + struct sched_param *param) +{ + if (pte_is_attr (attr) != 0 || param == NULL) + { + return EINVAL; + } + + memcpy (param, &(*attr)->param, sizeof (*param)); + return 0; +} diff --git a/src/pthread/pthread_attr_getschedpolicy.c b/src/pthread/pthread_attr_getschedpolicy.c new file mode 100644 index 000000000..9742d6db1 --- /dev/null +++ b/src/pthread/pthread_attr_getschedpolicy.c @@ -0,0 +1,67 @@ +/* + * pthread_attr_getschedpolicy.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_getschedpolicy (pthread_attr_t * attr, int *policy) +{ + if (pte_is_attr (attr) != 0 || policy == NULL) + { + return EINVAL; + } + + /* + * Validate the policy arg. + * Check that a policy constant wasn't passed rather than &policy. + */ + if (policy <= (int *) SCHED_MAX) + { + return EINVAL; + } + + *policy = SCHED_OTHER; + + return 0; +} diff --git a/src/pthread/pthread_attr_getscope.c b/src/pthread/pthread_attr_getscope.c new file mode 100644 index 000000000..76aa83fcd --- /dev/null +++ b/src/pthread/pthread_attr_getscope.c @@ -0,0 +1,56 @@ +/* + * pthread_attr_getscope.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + *contentionscope = (*attr)->contentionscope; + return 0; +#else + return ENOSYS; +#endif +} diff --git a/src/pthread/pthread_attr_getstackaddr.c b/src/pthread/pthread_attr_getstackaddr.c new file mode 100644 index 000000000..75be282bd --- /dev/null +++ b/src/pthread/pthread_attr_getstackaddr.c @@ -0,0 +1,99 @@ +/* + * pthread_attr_getstackaddr.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function determines the address of the stack + * on which threads created with 'attr' will run. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * stackaddr + * pointer into which is returned the stack address. + * + * + * DESCRIPTION + * This function determines the address of the stack + * on which threads created with 'attr' will run. + * + * NOTES: + * 1) Function supported only if this macro is + * defined: + * + * _POSIX_THREAD_ATTR_STACKADDR + * + * 2) Create only one thread for each stack + * address.. + * + * RESULTS + * 0 successfully retreived stack address, + * EINVAL 'attr' is invalid + * ENOSYS function not supported + * + * ------------------------------------------------------ + */ +{ +#if defined( _POSIX_THREAD_ATTR_STACKADDR ) + + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + *stackaddr = (*attr)->stackaddr; + return 0; + +#else + + return ENOSYS; + +#endif /* _POSIX_THREAD_ATTR_STACKADDR */ +} diff --git a/src/pthread/pthread_attr_getstacksize.c b/src/pthread/pthread_attr_getstacksize.c new file mode 100644 index 000000000..74ad839ee --- /dev/null +++ b/src/pthread/pthread_attr_getstacksize.c @@ -0,0 +1,102 @@ +/* + * pthread_attr_getstacksize.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function determines the size of the stack on + * which threads created with 'attr' will run. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * stacksize + * pointer to size_t into which is returned the + * stack size, in bytes. + * + * + * DESCRIPTION + * This function determines the size of the stack on + * which threads created with 'attr' will run. + * + * NOTES: + * 1) Function supported only if this macro is + * defined: + * + * _POSIX_THREAD_ATTR_STACKSIZE + * + * 2) Use on newly created attributes object to + * find the default stack size. + * + * RESULTS + * 0 successfully retrieved stack size, + * EINVAL 'attr' is invalid + * ENOSYS function not supported + * + * ------------------------------------------------------ + */ +{ +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + /* Everything is okay. */ + *stacksize = (*attr)->stacksize; + return 0; + +#else + + return ENOSYS; + +#endif /* _POSIX_THREAD_ATTR_STACKSIZE */ + +} diff --git a/src/pthread/pthread_attr_init.c b/src/pthread/pthread_attr_init.c new file mode 100644 index 000000000..bf20d3c17 --- /dev/null +++ b/src/pthread/pthread_attr_init.c @@ -0,0 +1,119 @@ +/* + * pthread_attr_init.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_init (pthread_attr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Initializes a thread attributes object with default + * attributes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * + * DESCRIPTION + * Initializes a thread attributes object with default + * attributes. + * + * NOTES: + * 1) Used to define thread attributes + * + * RESULTS + * 0 successfully initialized attr, + * ENOMEM insufficient memory for attr. + * + * ------------------------------------------------------ + */ +{ + pthread_attr_t attr_result; + + if (attr == NULL) + { + /* This is disallowed. */ + return EINVAL; + } + + attr_result = (pthread_attr_t) malloc (sizeof (*attr_result)); + + if (attr_result == NULL) + { + return ENOMEM; + } + +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + /* + * Default to zero size? + */ + attr_result->stacksize = 0; +#endif + +#ifdef _POSIX_THREAD_ATTR_STACKADDR + /* FIXME: Set this to something sensible when we support it. */ + attr_result->stackaddr = NULL; +#endif + + attr_result->detachstate = PTHREAD_CREATE_JOINABLE; + + /* + * Win32 sets new threads to THREAD_PRIORITY_NORMAL and + * not to that of the parent thread. We choose to default to + * this arrangement. + */ + attr_result->param.sched_priority = pte_osThreadGetDefaultPriority(); + attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED; + attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM; + + attr_result->valid = PTE_ATTR_VALID; + + *attr = attr_result; + + return 0; +} diff --git a/src/pthread/pthread_attr_setdetachstate.c b/src/pthread/pthread_attr_setdetachstate.c new file mode 100644 index 000000000..591b837c3 --- /dev/null +++ b/src/pthread/pthread_attr_setdetachstate.c @@ -0,0 +1,97 @@ +/* + * pthread_attr_setdetachstate.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function specifies whether threads created with + * 'attr' will run detached. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * detachstate + * an integer containing one of: + * + * PTHREAD_CREATE_JOINABLE + * Thread ID is valid, must be joined + * + * PTHREAD_CREATE_DETACHED + * Thread ID is invalid, cannot be joined, + * canceled, or modified + * + * + * DESCRIPTION + * This function specifies whether threads created with + * 'attr' will run detached. + * + * NOTES: + * 1) You cannot join or cancel detached threads. + * + * RESULTS + * 0 successfully set detach state, + * EINVAL 'attr' or 'detachstate' is invalid + * + * ------------------------------------------------------ + */ +{ + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + if (detachstate != PTHREAD_CREATE_JOINABLE && + detachstate != PTHREAD_CREATE_DETACHED) + { + return EINVAL; + } + + (*attr)->detachstate = detachstate; + return 0; +} diff --git a/src/pthread/pthread_attr_setinheritsched.c b/src/pthread/pthread_attr_setinheritsched.c new file mode 100644 index 000000000..2dcad893b --- /dev/null +++ b/src/pthread/pthread_attr_setinheritsched.c @@ -0,0 +1,63 @@ +/* + * pthread_attr_setinheritsched.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched) +{ + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + if (PTHREAD_INHERIT_SCHED != inheritsched + && PTHREAD_EXPLICIT_SCHED != inheritsched) + { + return EINVAL; + } + + (*attr)->inheritsched = inheritsched; + return 0; +} diff --git a/src/pthread/pthread_attr_setschedparam.c b/src/pthread/pthread_attr_setschedparam.c new file mode 100644 index 000000000..ef33a2b32 --- /dev/null +++ b/src/pthread/pthread_attr_setschedparam.c @@ -0,0 +1,72 @@ +/* + * pthread_attr_setschedparam.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_setschedparam (pthread_attr_t * attr, + const struct sched_param *param) +{ + int priority; + + if (pte_is_attr (attr) != 0 || param == NULL) + { + return EINVAL; + } + + priority = param->sched_priority; + + /* Validate priority level. */ + if (priority < sched_get_priority_min (SCHED_OTHER) || + priority > sched_get_priority_max (SCHED_OTHER)) + { + return EINVAL; + } + + memcpy (&(*attr)->param, param, sizeof (*param)); + return 0; +} diff --git a/src/pthread/pthread_attr_setschedpolicy.c b/src/pthread/pthread_attr_setschedpolicy.c new file mode 100644 index 000000000..fc317582c --- /dev/null +++ b/src/pthread/pthread_attr_setschedpolicy.c @@ -0,0 +1,61 @@ +/* + * pthread_attr_setschedpolicy.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy) +{ + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + if (policy != SCHED_OTHER) + { + return ENOTSUP; + } + + return 0; +} diff --git a/src/pthread/pthread_attr_setscope.c b/src/pthread/pthread_attr_setscope.c new file mode 100644 index 000000000..a302d277f --- /dev/null +++ b/src/pthread/pthread_attr_setscope.c @@ -0,0 +1,64 @@ +/* + * pthread_attr_setscope.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_setscope (pthread_attr_t * attr, int contentionscope) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + switch (contentionscope) + { + case PTHREAD_SCOPE_SYSTEM: + (*attr)->contentionscope = contentionscope; + return 0; + case PTHREAD_SCOPE_PROCESS: + return ENOTSUP; + default: + return EINVAL; + } +#else + return ENOSYS; +#endif +} diff --git a/src/pthread/pthread_attr_setstackaddr.c b/src/pthread/pthread_attr_setstackaddr.c new file mode 100644 index 000000000..52e8b51ff --- /dev/null +++ b/src/pthread/pthread_attr_setstackaddr.c @@ -0,0 +1,103 @@ +/* + * pthread_attr_setstackaddr.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Threads created with 'attr' will run on the stack + * starting at 'stackaddr'. + * Stack must be at least PTHREAD_STACK_MIN bytes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * stacksize + * stack size, in bytes. + * + * + * DESCRIPTION + * Threads created with 'attr' will run on the stack + * starting at 'stackaddr'. + * Stack must be at least PTHREAD_STACK_MIN bytes. + * + * NOTES: + * 1) Function supported only if this macro is + * defined: + * + * _POSIX_THREAD_ATTR_STACKADDR + * + * 2) Create only one thread for each stack + * address.. + * + * 3) Ensure that stackaddr is aligned. + * + * RESULTS + * 0 successfully set stack address, + * EINVAL 'attr' is invalid + * ENOSYS function not supported + * + * ------------------------------------------------------ + */ +{ +#if defined( _POSIX_THREAD_ATTR_STACKADDR ) + + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + (*attr)->stackaddr = stackaddr; + return 0; + +#else + + return ENOSYS; + +#endif /* _POSIX_THREAD_ATTR_STACKADDR */ +} diff --git a/src/pthread/pthread_attr_setstacksize.c b/src/pthread/pthread_attr_setstacksize.c new file mode 100644 index 000000000..e668027fc --- /dev/null +++ b/src/pthread/pthread_attr_setstacksize.c @@ -0,0 +1,116 @@ +/* + * pthread_attr_setstacksize.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function specifies the size of the stack on + * which threads created with 'attr' will run. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_attr_t + * + * stacksize + * stack size, in bytes. + * + * + * DESCRIPTION + * This function specifies the size of the stack on + * which threads created with 'attr' will run. + * + * NOTES: + * 1) Function supported only if this macro is + * defined: + * + * _POSIX_THREAD_ATTR_STACKSIZE + * + * 2) Find the default first (using + * pthread_attr_getstacksize), then increase + * by multiplying. + * + * 3) Only use if thread needs more than the + * default. + * + * RESULTS + * 0 successfully set stack size, + * EINVAL 'attr' is invalid or stacksize too + * small or too big. + * ENOSYS function not supported + * + * ------------------------------------------------------ + */ +{ +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + +#if PTHREAD_STACK_MIN > 0 + + /* Verify that the stack size is within range. */ + if (stacksize < PTHREAD_STACK_MIN) + { + return EINVAL; + } + +#endif + + if (pte_is_attr (attr) != 0) + { + return EINVAL; + } + + /* Everything is okay. */ + (*attr)->stacksize = stacksize; + return 0; + +#else + + return ENOSYS; + +#endif /* _POSIX_THREAD_ATTR_STACKSIZE */ + +} diff --git a/src/pthread/pthread_barrier_destroy.c b/src/pthread/pthread_barrier_destroy.c new file mode 100644 index 000000000..305f36398 --- /dev/null +++ b/src/pthread/pthread_barrier_destroy.c @@ -0,0 +1,75 @@ +/* + * pthread_barrier_destroy.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrier_destroy (pthread_barrier_t * barrier) +{ + int result = 0; + pthread_barrier_t b; + + if (barrier == NULL || *barrier == (pthread_barrier_t) PTE_OBJECT_INVALID) + { + return EINVAL; + } + + b = *barrier; + *barrier = NULL; + + if (0 == (result = sem_destroy (&(b->semBarrierBreeched[0])))) + { + if (0 == (result = sem_destroy (&(b->semBarrierBreeched[1])))) + { + (void) free (b); + return 0; + } + (void) sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0); + } + + *barrier = b; + return (result); +} diff --git a/src/pthread/pthread_barrier_init.c b/src/pthread/pthread_barrier_init.c new file mode 100644 index 000000000..6659fec8f --- /dev/null +++ b/src/pthread/pthread_barrier_init.c @@ -0,0 +1,89 @@ +/* + * pthread_barrier_init.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, unsigned int count) +{ + pthread_barrier_t b; + + if (barrier == NULL || count == 0) + { + return EINVAL; + } + + if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b)))) + { + b->pshared = (attr != NULL && *attr != NULL + ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE); + + b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count; + b->iStep = 0; + + /* + * Two semaphores are used in the same way as two stepping + * stones might be used in crossing a stream. Once all + * threads are safely on one stone, the other stone can + * be moved ahead, and the threads can start moving to it. + * If some threads decide to eat their lunch before moving + * then the other threads have to wait. + */ + if (0 == sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0)) + { + if (0 == sem_init (&(b->semBarrierBreeched[1]), b->pshared, 0)) + { + *barrier = b; + return 0; + } + (void) sem_destroy (&(b->semBarrierBreeched[0])); + } + (void) free (b); + } + + return ENOMEM; +} diff --git a/src/pthread/pthread_barrier_wait.c b/src/pthread/pthread_barrier_wait.c new file mode 100644 index 000000000..b6a0724ce --- /dev/null +++ b/src/pthread/pthread_barrier_wait.c @@ -0,0 +1,101 @@ +/* + * pthread_barrier_wait.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrier_wait (pthread_barrier_t * barrier) +{ + int result; + int step; + pthread_barrier_t b; + + if (barrier == NULL || *barrier == (pthread_barrier_t) PTE_OBJECT_INVALID) + { + return EINVAL; + } + + b = *barrier; + step = b->iStep; + + if (0 == PTE_ATOMIC_DECREMENT ((int *) &(b->nCurrentBarrierHeight))) + { + /* Must be done before posting the semaphore. */ + b->nCurrentBarrierHeight = b->nInitialBarrierHeight; + + /* + * There is no race condition between the semaphore wait and post + * because we are using two alternating semas and all threads have + * entered barrier_wait and checked nCurrentBarrierHeight before this + * barrier's sema can be posted. Any threads that have not quite + * entered sem_wait below when the multiple_post has completed + * will nevertheless continue through the semaphore (barrier) + * and will not be left stranded. + */ + result = (b->nInitialBarrierHeight > 1 + ? sem_post_multiple (&(b->semBarrierBreeched[step]), + b->nInitialBarrierHeight - 1) : 0); + } + else + { + /* + * Use the non-cancelable version of sem_wait(). + */ + result = sem_wait (&(b->semBarrierBreeched[step])); +// result = sem_wait_nocancel (&(b->semBarrierBreeched[step])); + } + + /* + * The first thread across will be the PTHREAD_BARRIER_SERIAL_THREAD. + * This also sets up the alternate semaphore as the next barrier. + */ + if (0 == result) + { + result = (step == + PTE_ATOMIC_COMPARE_EXCHANGE (& (b->iStep),(1L - step),step) ? + PTHREAD_BARRIER_SERIAL_THREAD : 0); + } + + return (result); +} diff --git a/src/pthread/pthread_barrierattr_destroy.c b/src/pthread/pthread_barrierattr_destroy.c new file mode 100644 index 000000000..bc3b5711b --- /dev/null +++ b/src/pthread/pthread_barrierattr_destroy.c @@ -0,0 +1,91 @@ +/* + * pthread_barrier_attr_destroy.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrierattr_destroy (pthread_barrierattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Destroys a barrier attributes object. The object can + * no longer be used. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_barrierattr_t + * + * + * DESCRIPTION + * Destroys a barrier attributes object. The object can + * no longer be used. + * + * NOTES: + * 1) Does not affect barrieres created using 'attr' + * + * RESULTS + * 0 successfully released attr, + * EINVAL 'attr' is invalid. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (attr == NULL || *attr == NULL) + { + result = EINVAL; + } + else + { + pthread_barrierattr_t ba = *attr; + + *attr = NULL; + free (ba); + } + + return (result); +} /* pthread_barrierattr_destroy */ diff --git a/src/pthread/pthread_barrierattr_getpshared.c b/src/pthread/pthread_barrierattr_getpshared.c new file mode 100644 index 000000000..af85ae10d --- /dev/null +++ b/src/pthread/pthread_barrierattr_getpshared.c @@ -0,0 +1,101 @@ +/* + * pthread_barrier_attr_getpshared.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr, + int *pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Determine whether barriers created with 'attr' can be + * shared between processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_barrierattr_t + * + * pshared + * will be set to one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * + * DESCRIPTION + * Mutexes creatd with 'attr' can be shared between + * processes if pthread_barrier_t variable is allocated + * in memory shared by these processes. + * NOTES: + * 1) pshared barriers MUST be allocated in shared + * memory. + * 2) The following macro is defined if shared barriers + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully retrieved attribute, + * EINVAL 'attr' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && (pshared != NULL)) + { + *pshared = (*attr)->pshared; + result = 0; + } + else + { + result = EINVAL; + } + + return (result); +} /* pthread_barrierattr_getpshared */ diff --git a/src/pthread/pthread_barrierattr_init.c b/src/pthread/pthread_barrierattr_init.c new file mode 100644 index 000000000..bd653f180 --- /dev/null +++ b/src/pthread/pthread_barrierattr_init.c @@ -0,0 +1,93 @@ +/* + * pthread_barrier_attr_init.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrierattr_init (pthread_barrierattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Initializes a barrier attributes object with default + * attributes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_barrierattr_t + * + * + * DESCRIPTION + * Initializes a barrier attributes object with default + * attributes. + * + * NOTES: + * 1) Used to define barrier types + * + * RESULTS + * 0 successfully initialized attr, + * ENOMEM insufficient memory for attr. + * + * ------------------------------------------------------ + */ +{ + pthread_barrierattr_t ba; + int result = 0; + + ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba)); + + if (ba == NULL) + { + result = ENOMEM; + } + else + { + ba->pshared = PTHREAD_PROCESS_PRIVATE; + } + + *attr = ba; + + return (result); +} /* pthread_barrierattr_init */ diff --git a/src/pthread/pthread_barrierattr_setpshared.c b/src/pthread/pthread_barrierattr_setpshared.c new file mode 100644 index 000000000..cadae1499 --- /dev/null +++ b/src/pthread/pthread_barrierattr_setpshared.c @@ -0,0 +1,125 @@ +/* + * pthread_barrier_attr_setpshared.c + * + * Description: + * This translation unit implements barrier primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Barriers created with 'attr' can be shared between + * processes if pthread_barrier_t variable is allocated + * in memory shared by these processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_barrierattr_t + * + * pshared + * must be one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * DESCRIPTION + * Mutexes creatd with 'attr' can be shared between + * processes if pthread_barrier_t variable is allocated + * in memory shared by these processes. + * + * NOTES: + * 1) pshared barriers MUST be allocated in shared + * memory. + * + * 2) The following macro is defined if shared barriers + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or pshared is invalid, + * ENOSYS PTHREAD_PROCESS_SHARED not supported, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && + ((pshared == PTHREAD_PROCESS_SHARED) || + (pshared == PTHREAD_PROCESS_PRIVATE))) + { + if (pshared == PTHREAD_PROCESS_SHARED) + { + +#if !defined( _POSIX_THREAD_PROCESS_SHARED ) + + result = ENOSYS; + pshared = PTHREAD_PROCESS_PRIVATE; + +#else + + result = 0; + +#endif /* _POSIX_THREAD_PROCESS_SHARED */ + + } + else + { + result = 0; + } + + (*attr)->pshared = pshared; + } + else + { + result = EINVAL; + } + + return (result); + +} /* pthread_barrierattr_setpshared */ diff --git a/src/pthread/pthread_cancel.c b/src/pthread/pthread_cancel.c new file mode 100644 index 000000000..dce60b282 --- /dev/null +++ b/src/pthread/pthread_cancel.c @@ -0,0 +1,173 @@ +/* + * pthread_cancel.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include + +int +pthread_cancel (pthread_t thread) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function requests cancellation of 'thread'. + * + * PARAMETERS + * thread + * reference to an instance of pthread_t + * + * + * DESCRIPTION + * This function requests cancellation of 'thread'. + * NOTE: cancellation is asynchronous; use pthread_join to + * wait for termination of 'thread' if necessary. + * + * RESULTS + * 0 successfully requested cancellation, + * ESRCH no thread found corresponding to 'thread', + * ENOMEM implicit self thread create failed. + * ------------------------------------------------------ + */ +{ + int result; + int cancel_self; + pthread_t self; + pte_thread_t * tp; + + result = pthread_kill (thread, 0); + + if (0 != result) + { + return result; + } + + if ((self = pthread_self ()).p == NULL) + { + return ENOMEM; + }; + + /* + * FIXME!! + * + * Can a thread cancel itself? + * + * The standard doesn't + * specify an error to be returned if the target + * thread is itself. + * + * If it may, then we need to ensure that a thread can't + * deadlock itself trying to cancel itself asyncronously + * (pthread_cancel is required to be an async-cancel + * safe function). + */ + cancel_self = pthread_equal (thread, self); + + tp = (pte_thread_t *) thread.p; + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock (&tp->cancelLock); + + if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS + && tp->cancelState == PTHREAD_CANCEL_ENABLE + && tp->state < PThreadStateCanceling) + { + if (cancel_self) + { + tp->state = PThreadStateCanceling; + tp->cancelState = PTHREAD_CANCEL_DISABLE; + + (void) pthread_mutex_unlock (&tp->cancelLock); + pte_throw (PTE_EPS_CANCEL); + + /* Never reached */ + } + else + { + /* + * We don't support asynchronous cancellation for thread other than ourselves. + * as it requires significant platform and OS specific functionality (see below). + * + * We should never get here, as we don't allow the cancellability type to be + * sent to async. + * + * If you really wanted to implement async cancellation, you would probably need to + * do something like the Win32 implement did, which is: + * 1. Suspend the target thread. + * 2. Replace the PC for the target thread to a routine that throws an exception + * or does a longjmp, depending on cleanup method. + * 3. Resume the target thread. + * + * Note that most of the async cancellation code is still in here if anyone + * wanted to add the OS/platform specific stuff. + */ + (void) pthread_mutex_unlock (&tp->cancelLock); + + result = EPERM; + + } + } + else + { + /* + * Set for deferred cancellation. + */ + if (tp->state < PThreadStateCancelPending) + { + tp->state = PThreadStateCancelPending; + + if (pte_osThreadCancel(tp->threadId) != PTE_OS_OK) + { + result = ESRCH; + } + } + else if (tp->state >= PThreadStateCanceling) + { + result = ESRCH; + } + + (void) pthread_mutex_unlock (&tp->cancelLock); + } + + return (result); +} diff --git a/src/pthread/pthread_cond_destroy.c b/src/pthread/pthread_cond_destroy.c new file mode 100644 index 000000000..c17a02f04 --- /dev/null +++ b/src/pthread/pthread_cond_destroy.c @@ -0,0 +1,256 @@ +/* + * pthread_cond_destroy.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_cond_destroy (pthread_cond_t * cond) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function destroys a condition variable + * + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * + * DESCRIPTION + * This function destroys a condition variable. + * + * NOTES: + * 1) A condition variable can be destroyed + * immediately after all the threads that + * are blocked on it are awakened. e.g. + * + * struct list { + * pthread_mutex_t lm; + * ... + * } + * + * struct elt { + * key k; + * int busy; + * pthread_cond_t notbusy; + * ... + * } + * + * + * struct elt * + * list_find(struct list *lp, key k) + * { + * struct elt *ep; + * + * pthread_mutex_lock(&lp->lm); + * while ((ep = find_elt(l,k) != NULL) && ep->busy) + * pthread_cond_wait(&ep->notbusy, &lp->lm); + * if (ep != NULL) + * ep->busy = 1; + * pthread_mutex_unlock(&lp->lm); + * return(ep); + * } + * + * delete_elt(struct list *lp, struct elt *ep) + * { + * pthread_mutex_lock(&lp->lm); + * assert(ep->busy); + * ... remove ep from list ... + * ep->busy = 0; + * (A) pthread_cond_broadcast(&ep->notbusy); + * pthread_mutex_unlock(&lp->lm); + * (B) pthread_cond_destroy(&rp->notbusy); + * free(ep); + * } + * + * In this example, the condition variable + * and its list element may be freed (line B) + * immediately after all threads waiting for + * it are awakened (line A), since the mutex + * and the code ensure that no other thread + * can touch the element to be deleted. + * + * RESULTS + * 0 successfully released condition variable, + * EINVAL 'cond' is invalid, + * EBUSY 'cond' is in use, + * + * ------------------------------------------------------ + */ +{ + pthread_cond_t cv; + int result = 0, result1 = 0, result2 = 0; + + /* + * Assuming any race condition here is harmless. + */ + if (cond == NULL || *cond == NULL) + { + return EINVAL; + } + + if (*cond != PTHREAD_COND_INITIALIZER) + { + + pte_osMutexLock (pte_cond_list_lock); + + cv = *cond; + + /* + * Close the gate; this will synchronize this thread with + * all already signaled waiters to let them retract their + * waiter status - SEE NOTE 1 ABOVE!!! + */ + if (sem_wait (&(cv->semBlockLock)) != 0) + { + return errno; + } + + /* + * !TRY! lock mtxUnblockLock; try will detect busy condition + * and will not cause a deadlock with respect to concurrent + * signal/broadcast. + */ + if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0) + { + (void) sem_post (&(cv->semBlockLock)); + return result; + } + + /* + * Check whether cv is still busy (still has waiters) + */ + if (cv->nWaitersBlocked > cv->nWaitersGone) + { + if (sem_post (&(cv->semBlockLock)) != 0) + { + result = errno; + } + result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock)); + result2 = EBUSY; + } + else + { + /* + * Now it is safe to destroy + */ + *cond = NULL; + + if (sem_destroy (&(cv->semBlockLock)) != 0) + { + result = errno; + } + if (sem_destroy (&(cv->semBlockQueue)) != 0) + { + result1 = errno; + } + if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) + { + result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock)); + } + + /* Unlink the CV from the list */ + + if (pte_cond_list_head == cv) + { + pte_cond_list_head = cv->next; + } + else + { + cv->prev->next = cv->next; + } + + if (pte_cond_list_tail == cv) + { + pte_cond_list_tail = cv->prev; + } + else + { + cv->next->prev = cv->prev; + } + + (void) free (cv); + } + + pte_osMutexUnlock(pte_cond_list_lock); + + } + else + { + /* + * See notes in pte_cond_check_need_init() above also. + */ + + pte_osMutexLock (pte_cond_test_init_lock); + + /* + * Check again. + */ + if (*cond == PTHREAD_COND_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised cond that has not yet been used (initialised). + * If we get to here, another thread waiting to initialise + * this cond will get an EINVAL. That's OK. + */ + *cond = NULL; + } + else + { + /* + * The cv has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + pte_osMutexUnlock(pte_cond_test_init_lock); + } + + return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); +} diff --git a/src/pthread/pthread_cond_init.c b/src/pthread/pthread_cond_init.c new file mode 100644 index 000000000..607a0d255 --- /dev/null +++ b/src/pthread/pthread_cond_init.c @@ -0,0 +1,174 @@ +/* + * pthread_cond_init.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function initializes a condition variable. + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * attr + * specifies optional creation attributes. + * + * + * DESCRIPTION + * This function initializes a condition variable. + * + * RESULTS + * 0 successfully created condition variable, + * EINVAL 'attr' is invalid, + * EAGAIN insufficient resources (other than + * memory, + * ENOMEM insufficient memory, + * EBUSY 'cond' is already initialized, + * + * ------------------------------------------------------ + */ +{ + int result; + pthread_cond_t cv = NULL; + + if (cond == NULL) + { + return EINVAL; + } + + if ((attr != NULL && *attr != NULL) && + ((*attr)->pshared == PTHREAD_PROCESS_SHARED)) + { + /* + * Creating condition variable that can be shared between + * processes. + */ + result = ENOSYS; + goto DONE; + } + + cv = (pthread_cond_t) calloc (1, sizeof (*cv)); + + if (cv == NULL) + { + result = ENOMEM; + goto DONE; + } + + cv->nWaitersBlocked = 0; + cv->nWaitersToUnblock = 0; + cv->nWaitersGone = 0; + + if (sem_init (&(cv->semBlockLock), 0, 1) != 0) + { + result = errno; + goto FAIL0; + } + + if (sem_init (&(cv->semBlockQueue), 0, 0) != 0) + { + result = errno; + goto FAIL1; + } + + if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0) + { + goto FAIL2; + } + + result = 0; + + goto DONE; + + /* + * ------------- + * Failed... + * ------------- + */ +FAIL2: + (void) sem_destroy (&(cv->semBlockQueue)); + +FAIL1: + (void) sem_destroy (&(cv->semBlockLock)); + +FAIL0: + (void) free (cv); + cv = NULL; + +DONE: + if (0 == result) + { + + pte_osMutexLock (pte_cond_list_lock); + + cv->next = NULL; + cv->prev = pte_cond_list_tail; + + if (pte_cond_list_tail != NULL) + { + pte_cond_list_tail->next = cv; + } + + pte_cond_list_tail = cv; + + if (pte_cond_list_head == NULL) + { + pte_cond_list_head = cv; + } + + pte_osMutexUnlock(pte_cond_list_lock); + } + + *cond = cv; + + return result; + +} /* pthread_cond_init */ diff --git a/src/pthread/pthread_cond_signal.c b/src/pthread/pthread_cond_signal.c new file mode 100644 index 000000000..a25259cd6 --- /dev/null +++ b/src/pthread/pthread_cond_signal.c @@ -0,0 +1,238 @@ +/* + * pthread_cond_signal.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * ------------------------------------------------------------- + * Algorithm: + * See the comments at the top of pthread_cond_wait.c. + */ + +#include "pthread.h" +#include "implement.h" + +static int +pte_cond_unblock (pthread_cond_t * cond, int unblockAll) +/* + * Notes. + * + * Does not use the external mutex for synchronisation, + * therefore semBlockLock is needed. + * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the + * state where the external mutex is not necessarily locked by + * any thread, ie. between cond_wait unlocking and re-acquiring + * the lock after having been signaled or a timeout or + * cancellation. + * + * Uses the following CV elements: + * nWaitersBlocked + * nWaitersToUnblock + * nWaitersGone + * mtxUnblockLock + * semBlockLock + * semBlockQueue + */ +{ + int result; + pthread_cond_t cv; + int nSignalsToIssue; + + if (cond == NULL || *cond == NULL) + { + return EINVAL; + } + + cv = *cond; + + /* + * No-op if the CV is static and hasn't been initialised yet. + * Assuming that any race condition is harmless. + */ + if (cv == PTHREAD_COND_INITIALIZER) + { + return 0; + } + + if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0) + { + return result; + } + + if (0 != cv->nWaitersToUnblock) + { + if (0 == cv->nWaitersBlocked) + { + return pthread_mutex_unlock (&(cv->mtxUnblockLock)); + } + if (unblockAll) + { + cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked); + cv->nWaitersBlocked = 0; + } + else + { + nSignalsToIssue = 1; + cv->nWaitersToUnblock++; + cv->nWaitersBlocked--; + } + } + else if (cv->nWaitersBlocked > cv->nWaitersGone) + { + /* Use the non-cancellable version of sem_wait() */ +// if (sem_wait_nocancel (&(cv->semBlockLock)) != 0) + if (sem_wait (&(cv->semBlockLock)) != 0) + { + result = errno; + (void) pthread_mutex_unlock (&(cv->mtxUnblockLock)); + return result; + } + if (0 != cv->nWaitersGone) + { + cv->nWaitersBlocked -= cv->nWaitersGone; + cv->nWaitersGone = 0; + } + if (unblockAll) + { + nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked; + cv->nWaitersBlocked = 0; + } + else + { + nSignalsToIssue = cv->nWaitersToUnblock = 1; + cv->nWaitersBlocked--; + } + } + else + { + return pthread_mutex_unlock (&(cv->mtxUnblockLock)); + } + + if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) + { + if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0) + { + result = errno; + } + } + + return result; + +} /* pte_cond_unblock */ + +int +pthread_cond_signal (pthread_cond_t * cond) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function signals a condition variable, waking + * one waiting thread. + * If SCHED_FIFO or SCHED_RR policy threads are waiting + * the highest priority waiter is awakened; otherwise, + * an unspecified waiter is awakened. + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * + * DESCRIPTION + * This function signals a condition variable, waking + * one waiting thread. + * If SCHED_FIFO or SCHED_RR policy threads are waiting + * the highest priority waiter is awakened; otherwise, + * an unspecified waiter is awakened. + * + * NOTES: + * + * 1) Use when any waiter can respond and only one need + * respond (all waiters being equal). + * + * RESULTS + * 0 successfully signaled condition, + * EINVAL 'cond' is invalid, + * + * ------------------------------------------------------ + */ +{ + /* + * The '0'(FALSE) unblockAll arg means unblock ONE waiter. + */ + return (pte_cond_unblock (cond, 0)); + +} /* pthread_cond_signal */ + +int +pthread_cond_broadcast (pthread_cond_t * cond) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function broadcasts the condition variable, + * waking all current waiters. + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * + * DESCRIPTION + * This function signals a condition variable, waking + * all waiting threads. + * + * NOTES: + * + * 1) Use when more than one waiter may respond to + * predicate change or if any waiting thread may + * not be able to respond + * + * RESULTS + * 0 successfully signalled condition to all + * waiting threads, + * EINVAL 'cond' is invalid + * ENOSPC a required resource has been exhausted, + * + * ------------------------------------------------------ + */ +{ + /* + * The TRUE unblockAll arg means unblock ALL waiters. + */ + return (pte_cond_unblock (cond, PTE_TRUE)); + +} /* pthread_cond_broadcast */ diff --git a/src/pthread/pthread_cond_wait.c b/src/pthread/pthread_cond_wait.c new file mode 100644 index 000000000..8b75f0279 --- /dev/null +++ b/src/pthread/pthread_cond_wait.c @@ -0,0 +1,568 @@ +/* + * pthread_cond_wait.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * ------------------------------------------------------------- + * Algorithm: + * The algorithm used in this implementation is that developed by + * Alexander Terekhov in colaboration with Louis Thomas. The bulk + * of the discussion is recorded in the file README.CV, which contains + * several generations of both colaborators original algorithms. The final + * algorithm used here is the one referred to as + * + * Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL + * + * presented below in pseudo-code as it appeared: + * + * + * given: + * semBlockLock - bin.semaphore + * semBlockQueue - semaphore + * mtxExternal - mutex or CS + * mtxUnblockLock - mutex or CS + * nWaitersGone - int + * nWaitersBlocked - int + * nWaitersToUnblock - int + * + * wait( timeout ) { + * + * [auto: register int result ] // error checking omitted + * [auto: register int nSignalsWasLeft ] + * [auto: register int nWaitersWasGone ] + * + * sem_wait( semBlockLock ); + * nWaitersBlocked++; + * sem_post( semBlockLock ); + * + * unlock( mtxExternal ); + * bTimedOut = sem_wait( semBlockQueue,timeout ); + * + * lock( mtxUnblockLock ); + * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { + * if ( bTimeout ) { // timeout (or canceled) + * if ( 0 != nWaitersBlocked ) { + * nWaitersBlocked--; + * } + * else { + * nWaitersGone++; // count spurious wakeups. + * } + * } + * if ( 0 == --nWaitersToUnblock ) { + * if ( 0 != nWaitersBlocked ) { + * sem_post( semBlockLock ); // open the gate. + * nSignalsWasLeft = 0; // do not open the gate + * // below again. + * } + * else if ( 0 != (nWaitersWasGone = nWaitersGone) ) { + * nWaitersGone = 0; + * } + * } + * } + * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or + * // spurious semaphore :-) + * sem_wait( semBlockLock ); + * nWaitersBlocked -= nWaitersGone; // something is going on here + * // - test of timeouts? :-) + * sem_post( semBlockLock ); + * nWaitersGone = 0; + * } + * unlock( mtxUnblockLock ); + * + * if ( 1 == nSignalsWasLeft ) { + * if ( 0 != nWaitersWasGone ) { + * // sem_adjust( semBlockQueue,-nWaitersWasGone ); + * while ( nWaitersWasGone-- ) { + * sem_wait( semBlockQueue ); // better now than spurious later + * } + * } sem_post( semBlockLock ); // open the gate + * } + * + * lock( mtxExternal ); + * + * return ( bTimedOut ) ? ETIMEOUT : 0; + * } + * + * signal(bAll) { + * + * [auto: register int result ] + * [auto: register int nSignalsToIssue] + * + * lock( mtxUnblockLock ); + * + * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!! + * if ( 0 == nWaitersBlocked ) { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * if (bAll) { + * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = 1; + * nWaitersToUnblock++; + * nWaitersBlocked--; + * } + * } + * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION! + * sem_wait( semBlockLock ); // close the gate + * if ( 0 != nWaitersGone ) { + * nWaitersBlocked -= nWaitersGone; + * nWaitersGone = 0; + * } + * if (bAll) { + * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = nWaitersToUnblock = 1; + * nWaitersBlocked--; + * } + * } + * else { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * + * unlock( mtxUnblockLock ); + * sem_post( semBlockQueue,nSignalsToIssue ); + * return result; + * } + * ------------------------------------------------------------- + * + * Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL + * + * presented below in pseudo-code; basically 8a... + * ...BUT W/O "spurious wakes" prevention: + * + * + * given: + * semBlockLock - bin.semaphore + * semBlockQueue - semaphore + * mtxExternal - mutex or CS + * mtxUnblockLock - mutex or CS + * nWaitersGone - int + * nWaitersBlocked - int + * nWaitersToUnblock - int + * + * wait( timeout ) { + * + * [auto: register int result ] // error checking omitted + * [auto: register int nSignalsWasLeft ] + * + * sem_wait( semBlockLock ); + * ++nWaitersBlocked; + * sem_post( semBlockLock ); + * + * unlock( mtxExternal ); + * bTimedOut = sem_wait( semBlockQueue,timeout ); + * + * lock( mtxUnblockLock ); + * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { + * --nWaitersToUnblock; + * } + * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or + * // spurious semaphore :-) + * sem_wait( semBlockLock ); + * nWaitersBlocked -= nWaitersGone; // something is going on here + * // - test of timeouts? :-) + * sem_post( semBlockLock ); + * nWaitersGone = 0; + * } + * unlock( mtxUnblockLock ); + * + * if ( 1 == nSignalsWasLeft ) { + * sem_post( semBlockLock ); // open the gate + * } + * + * lock( mtxExternal ); + * + * return ( bTimedOut ) ? ETIMEOUT : 0; + * } + * + * signal(bAll) { + * + * [auto: register int result ] + * [auto: register int nSignalsToIssue] + * + * lock( mtxUnblockLock ); + * + * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!! + * if ( 0 == nWaitersBlocked ) { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * if (bAll) { + * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = 1; + * ++nWaitersToUnblock; + * --nWaitersBlocked; + * } + * } + * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION! + * sem_wait( semBlockLock ); // close the gate + * if ( 0 != nWaitersGone ) { + * nWaitersBlocked -= nWaitersGone; + * nWaitersGone = 0; + * } + * if (bAll) { + * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = nWaitersToUnblock = 1; + * --nWaitersBlocked; + * } + * } + * else { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * + * unlock( mtxUnblockLock ); + * sem_post( semBlockQueue,nSignalsToIssue ); + * return result; + * } + * ------------------------------------------------------------- + * + */ + +#include "pthread.h" +#include "implement.h" + +/* + * Arguments for cond_wait_cleanup, since we can only pass a + * single void * to it. + */ +typedef struct + { + pthread_mutex_t *mutexPtr; + pthread_cond_t cv; + int *resultPtr; + } pte_cond_wait_cleanup_args_t; + +static void +pte_cond_wait_cleanup (void *args) +{ + pte_cond_wait_cleanup_args_t *cleanup_args = + (pte_cond_wait_cleanup_args_t *) args; + pthread_cond_t cv = cleanup_args->cv; + int *resultPtr = cleanup_args->resultPtr; + int nSignalsWasLeft; + int result; + + /* + * Whether we got here as a result of signal/broadcast or because of + * timeout on wait or thread cancellation we indicate that we are no + * longer waiting. The waiter is responsible for adjusting waiters + * (to)unblock(ed) counts (protected by unblock lock). + */ + if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0) + { + *resultPtr = result; + return; + } + + if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock)) + { + --(cv->nWaitersToUnblock); + } + else if (INT_MAX / 2 == ++(cv->nWaitersGone)) + { + /* Use the non-cancellable version of sem_wait() */ +// if (sem_wait_nocancel (&(cv->semBlockLock)) != 0) + if (sem_wait (&(cv->semBlockLock)) != 0) + { + *resultPtr = errno; + /* + * This is a fatal error for this CV, + * so we deliberately don't unlock + * cv->mtxUnblockLock before returning. + */ + return; + } + cv->nWaitersBlocked -= cv->nWaitersGone; + if (sem_post (&(cv->semBlockLock)) != 0) + { + *resultPtr = errno; + /* + * This is a fatal error for this CV, + * so we deliberately don't unlock + * cv->mtxUnblockLock before returning. + */ + return; + } + cv->nWaitersGone = 0; + } + + if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0) + { + *resultPtr = result; + return; + } + + if (1 == nSignalsWasLeft) + { + if (sem_post (&(cv->semBlockLock)) != 0) + { + *resultPtr = errno; + return; + } + } + + /* + * XSH: Upon successful return, the mutex has been locked and is owned + * by the calling thread. + */ + if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0) + { + *resultPtr = result; + } +} /* pte_cond_wait_cleanup */ + +static int +pte_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, const struct timespec *abstime) +{ + int result = 0; + pthread_cond_t cv; + pte_cond_wait_cleanup_args_t cleanup_args; + + if (cond == NULL || *cond == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static condition variable. We check + * again inside the guarded section of pte_cond_check_need_init() + * to avoid race conditions. + */ + if (*cond == PTHREAD_COND_INITIALIZER) + { + result = pte_cond_check_need_init (cond); + } + + if (result != 0 && result != EBUSY) + { + return result; + } + + cv = *cond; + + /* Thread can be cancelled in sem_wait() but this is OK */ + if (sem_wait (&(cv->semBlockLock)) != 0) + { + return errno; + } + + ++(cv->nWaitersBlocked); + + if (sem_post (&(cv->semBlockLock)) != 0) + { + return errno; + } + + /* + * Setup this waiter cleanup handler + */ + cleanup_args.mutexPtr = mutex; + cleanup_args.cv = cv; + cleanup_args.resultPtr = &result; + + pthread_cleanup_push (pte_cond_wait_cleanup, (void *) &cleanup_args); + + /* + * Now we can release 'mutex' and... + */ + if ((result = pthread_mutex_unlock (mutex)) == 0) + { + /* + * ...wait to be awakened by + * pthread_cond_signal, or + * pthread_cond_broadcast, or + * timeout, or + * thread cancellation + * + * Note: + * + * sem_timedwait is a cancellation point, + * hence providing the mechanism for making + * pthread_cond_wait a cancellation point. + * We use the cleanup mechanism to ensure we + * re-lock the mutex and adjust (to)unblock(ed) waiters + * counts if we are cancelled, timed out or signalled. + */ + if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0) + { + result = errno; + } + } + + + /* + * Always cleanup + */ + pthread_cleanup_pop (1); + + /* + * "result" can be modified by the cleanup handler. + */ + return result; + +} /* pte_cond_timedwait */ + + +int +pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a condition variable until + * awakened by a signal or broadcast. + * + * Caller MUST be holding the mutex lock; the + * lock is released and the caller is blocked waiting + * on 'cond'. When 'cond' is signaled, the mutex + * is re-acquired before returning to the caller. + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * mutex + * pointer to an instance of pthread_mutex_t + * + * + * DESCRIPTION + * This function waits on a condition variable until + * awakened by a signal or broadcast. + * + * NOTES: + * + * 1) The function must be called with 'mutex' LOCKED + * by the calling thread, or undefined behaviour + * will result. + * + * 2) This routine atomically releases 'mutex' and causes + * the calling thread to block on the condition variable. + * The blocked thread may be awakened by + * pthread_cond_signal or + * pthread_cond_broadcast. + * + * Upon successful completion, the 'mutex' has been locked and + * is owned by the calling thread. + * + * + * RESULTS + * 0 caught condition; mutex released, + * EINVAL 'cond' or 'mutex' is invalid, + * EINVAL different mutexes for concurrent waits, + * EINVAL mutex is not held by the calling thread, + * + * ------------------------------------------------------ + */ +{ + /* + * The NULL abstime arg means INFINITE waiting. + */ + return (pte_cond_timedwait (cond, mutex, NULL)); + +} /* pthread_cond_wait */ + + +int +pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a condition variable either until + * awakened by a signal or broadcast; or until the time + * specified by abstime passes. + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * mutex + * pointer to an instance of pthread_mutex_t + * + * abstime + * pointer to an instance of (const struct timespec) + * + * + * DESCRIPTION + * This function waits on a condition variable either until + * awakened by a signal or broadcast; or until the time + * specified by abstime passes. + * + * NOTES: + * 1) The function must be called with 'mutex' LOCKED + * by the calling thread, or undefined behaviour + * will result. + * + * 2) This routine atomically releases 'mutex' and causes + * the calling thread to block on the condition variable. + * The blocked thread may be awakened by + * pthread_cond_signal or + * pthread_cond_broadcast. + * + * + * RESULTS + * 0 caught condition; mutex released, + * EINVAL 'cond', 'mutex', or abstime is invalid, + * EINVAL different mutexes for concurrent waits, + * EINVAL mutex is not held by the calling thread, + * ETIMEDOUT abstime ellapsed before cond was signaled. + * + * ------------------------------------------------------ + */ +{ + if (abstime == NULL) + { + return EINVAL; + } + + return (pte_cond_timedwait (cond, mutex, abstime)); + +} /* pthread_cond_timedwait */ diff --git a/src/pthread/pthread_condattr_destroy.c b/src/pthread/pthread_condattr_destroy.c new file mode 100644 index 000000000..b56f76c29 --- /dev/null +++ b/src/pthread/pthread_condattr_destroy.c @@ -0,0 +1,94 @@ +/* + * condvar_attr_destroy.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_condattr_destroy (pthread_condattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Destroys a condition variable attributes object. + * The object can no longer be used. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_condattr_t + * + * + * DESCRIPTION + * Destroys a condition variable attributes object. + * The object can no longer be used. + * + * NOTES: + * 1) Does not affect condition variables created + * using 'attr' + * + * RESULTS + * 0 successfully released attr, + * EINVAL 'attr' is invalid. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (attr == NULL || *attr == NULL) + { + result = EINVAL; + } + else + { + (void) free (*attr); + + *attr = NULL; + result = 0; + } + + return result; + +} /* pthread_condattr_destroy */ diff --git a/src/pthread/pthread_condattr_getpshared.c b/src/pthread/pthread_condattr_getpshared.c new file mode 100644 index 000000000..20fa08504 --- /dev/null +++ b/src/pthread/pthread_condattr_getpshared.c @@ -0,0 +1,103 @@ +/* + * pthread_condattr_getpshared.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Determine whether condition variables created with 'attr' + * can be shared between processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_condattr_t + * + * pshared + * will be set to one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * + * DESCRIPTION + * Condition Variables created with 'attr' can be shared + * between processes if pthread_cond_t variable is allocated + * in memory shared by these processes. + * NOTES: + * 1) pshared condition variables MUST be allocated in + * shared memory. + * + * 2) The following macro is defined if shared mutexes + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully retrieved attribute, + * EINVAL 'attr' or 'pshared' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && (pshared != NULL)) + { + *pshared = (*attr)->pshared; + result = 0; + } + else + { + result = EINVAL; + } + + return result; + +} /* pthread_condattr_getpshared */ diff --git a/src/pthread/pthread_condattr_init.c b/src/pthread/pthread_condattr_init.c new file mode 100644 index 000000000..393cf0499 --- /dev/null +++ b/src/pthread/pthread_condattr_init.c @@ -0,0 +1,95 @@ +/* + * pthread_condattr_init.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_condattr_init (pthread_condattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Initializes a condition variable attributes object + * with default attributes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_condattr_t + * + * + * DESCRIPTION + * Initializes a condition variable attributes object + * with default attributes. + * + * NOTES: + * 1) Use to define condition variable types + * 2) It is up to the application to ensure + * that it doesn't re-init an attribute + * without destroying it first. Otherwise + * a memory leak is created. + * + * RESULTS + * 0 successfully initialized attr, + * ENOMEM insufficient memory for attr. + * + * ------------------------------------------------------ + */ +{ + pthread_condattr_t attr_result; + int result = 0; + + attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result)); + + if (attr_result == NULL) + { + result = ENOMEM; + } + + *attr = attr_result; + + return result; + +} /* pthread_condattr_init */ diff --git a/src/pthread/pthread_condattr_setpshared.c b/src/pthread/pthread_condattr_setpshared.c new file mode 100644 index 000000000..f8e7f1345 --- /dev/null +++ b/src/pthread/pthread_condattr_setpshared.c @@ -0,0 +1,123 @@ +/* + * pthread_condattr_setpshared.c + * + * Description: + * This translation unit implements condition variables and their primitives. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Mutexes created with 'attr' can be shared between + * processes if pthread_mutex_t variable is allocated + * in memory shared by these processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * pshared + * must be one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * DESCRIPTION + * Mutexes creatd with 'attr' can be shared between + * processes if pthread_mutex_t variable is allocated + * in memory shared by these processes. + * + * NOTES: + * 1) pshared mutexes MUST be allocated in shared + * memory. + * + * 2) The following macro is defined if shared mutexes + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or pshared is invalid, + * ENOSYS PTHREAD_PROCESS_SHARED not supported, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) + && ((pshared == PTHREAD_PROCESS_SHARED) + || (pshared == PTHREAD_PROCESS_PRIVATE))) + { + if (pshared == PTHREAD_PROCESS_SHARED) + { + +#if !defined( _POSIX_THREAD_PROCESS_SHARED ) + result = ENOSYS; + pshared = PTHREAD_PROCESS_PRIVATE; +#else + result = 0; + +#endif /* _POSIX_THREAD_PROCESS_SHARED */ + + } + else + { + result = 0; + } + + (*attr)->pshared = pshared; + } + else + { + result = EINVAL; + } + + return result; + +} /* pthread_condattr_setpshared */ diff --git a/src/pthread/pthread_delay_np.c b/src/pthread/pthread_delay_np.c new file mode 100644 index 000000000..c954e610c --- /dev/null +++ b/src/pthread/pthread_delay_np.c @@ -0,0 +1,166 @@ +/* + * pthreads_delay_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +/* + * pthread_delay_np + * + * DESCRIPTION + * + * This routine causes a thread to delay execution for a specific period of time. + * This period ends at the current time plus the specified interval. The routine + * will not return before the end of the period is reached, but may return an + * arbitrary amount of time after the period has gone by. This can be due to + * system load, thread priorities, and system timer granularity. + * + * Specifying an interval of zero (0) seconds and zero (0) nanoseconds is + * allowed and can be used to force the thread to give up the processor or to + * deliver a pending cancelation request. + * + * The timespec structure contains the following two fields: + * + * tv_sec is an integer number of seconds. + * tv_nsec is an integer number of nanoseconds. + * + * Return Values + * + * If an error condition occurs, this routine returns an integer value indicating + * the type of error. Possible return values are as follows: + * + * 0 + * Successful completion. + * [EINVAL] + * The value specified by interval is invalid. + * + * Example + * + * The following code segment would wait for 5 and 1/2 seconds + * + * struct timespec tsWait; + * int intRC; + * + * tsWait.tv_sec = 5; + * tsWait.tv_nsec = 500000000L; + * intRC = pthread_delay_np(&tsWait); + */ +int +pthread_delay_np (struct timespec *interval) +{ + unsigned int wait_time; + unsigned int secs_in_millisecs; + unsigned int millisecs; + pthread_t self; + pte_thread_t * sp; + + if (interval == NULL) + { + return EINVAL; + } + + if (interval->tv_sec == 0L && interval->tv_nsec == 0L) + { + pthread_testcancel (); + pte_osThreadSleep (1); + pthread_testcancel (); + return (0); + } + + /* convert secs to millisecs */ + secs_in_millisecs = interval->tv_sec * 1000L; + + /* convert nanosecs to millisecs (rounding up) */ + millisecs = (interval->tv_nsec + 999999L) / 1000000L; + + wait_time = secs_in_millisecs + millisecs; + + if (NULL == (self = pthread_self ()).p) + { + return ENOMEM; + } + + sp = (pte_thread_t *) self.p; + + if (sp->cancelState == PTHREAD_CANCEL_ENABLE) + { + pte_osResult cancelStatus; + /* + * Async cancelation won't catch us until wait_time is up. + * Deferred cancelation will cancel us immediately. + */ + cancelStatus = pte_osThreadCheckCancel(sp->threadId); + + if (cancelStatus == PTE_OS_INTERRUPTED) + { + /* + * Canceling! + */ + (void) pthread_mutex_lock (&sp->cancelLock); + if (sp->state < PThreadStateCanceling) + { + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock (&sp->cancelLock); + + pte_throw (PTE_EPS_CANCEL); + } + + (void) pthread_mutex_unlock (&sp->cancelLock); + return ESRCH; + } + else if (cancelStatus != PTE_OS_OK) + { + return EINVAL; + } + } + else + + { + pte_osThreadSleep (wait_time); + } + + return (0); +} diff --git a/src/pthread/pthread_detach.c b/src/pthread/pthread_detach.c new file mode 100644 index 000000000..21e4da28d --- /dev/null +++ b/src/pthread/pthread_detach.c @@ -0,0 +1,142 @@ +/* + * pthread_detach.c + * + * Description: + * This translation unit implements functions related to thread + * synchronisation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_detach (pthread_t thread) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function detaches the given thread. + * + * PARAMETERS + * thread + * an instance of a pthread_t + * + * + * DESCRIPTION + * This function detaches the given thread. You may use it to + * detach the main thread or to detach a joinable thread. + * NOTE: detached threads cannot be joined; + * storage is freed immediately on termination. + * + * RESULTS + * 0 successfully detached the thread, + * EINVAL thread is not a joinable thread, + * ENOSPC a required resource has been exhausted, + * ESRCH no thread could be found for 'thread', + * + * ------------------------------------------------------ + */ +{ + int result; + unsigned char destroyIt = PTE_FALSE; + pte_thread_t * tp = (pte_thread_t *) thread.p; + + + pte_osMutexLock (pte_thread_reuse_lock); + + if (NULL == tp + || thread.x != tp->ptHandle.x) + { + result = ESRCH; + } + else if (PTHREAD_CREATE_DETACHED == tp->detachState) + { + result = EINVAL; + } + else + { + /* + * Joinable pte_thread_t structs are not scavenged until + * a join or detach is done. The thread may have exited already, + * but all of the state and locks etc are still there. + */ + result = 0; + + if (pthread_mutex_lock (&tp->cancelLock) == 0) + { + if (tp->state != PThreadStateLast) + { + tp->detachState = PTHREAD_CREATE_DETACHED; + } + else if (tp->detachState != PTHREAD_CREATE_DETACHED) + { + /* + * Thread is joinable and has exited or is exiting. + */ + destroyIt = PTE_TRUE; + } + (void) pthread_mutex_unlock (&tp->cancelLock); + } + else + { + /* cancelLock shouldn't fail, but if it does ... */ + result = ESRCH; + } + } + + pte_osMutexUnlock(pte_thread_reuse_lock); + + if (result == 0) + { + /* Thread is joinable */ + + if (destroyIt) + { + /* The thread has exited or is exiting but has not been joined or + * detached. Need to wait in case it's still exiting. + */ + pte_osThreadWaitForEnd(tp->threadId); + + pte_threadDestroy (thread); + } + } + + return (result); + +} /* pthread_detach */ diff --git a/src/pthread/pthread_equal.c b/src/pthread/pthread_equal.c new file mode 100644 index 000000000..627f9149c --- /dev/null +++ b/src/pthread/pthread_equal.c @@ -0,0 +1,82 @@ +/* + * pthread_equal.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_equal (pthread_t t1, pthread_t t2) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function returns nonzero if t1 and t2 are equal, else + * returns nonzero + * + * PARAMETERS + * t1, + * t2 + * thread IDs + * + * + * DESCRIPTION + * This function returns nonzero if t1 and t2 are equal, else + * returns zero. + * + * RESULTS + * non-zero if t1 and t2 refer to the same thread, + * 0 t1 and t2 do not refer to the same thread + * + * ------------------------------------------------------ + */ +{ + int result; + + /* + * We also accept NULL == NULL - treating NULL as a thread + * for this special case, because there is no error that we can return. + */ + result = ( t1.p == t2.p && t1.x == t2.x ); + + return (result); + +} /* pthread_equal */ diff --git a/src/pthread/pthread_exit.c b/src/pthread/pthread_exit.c new file mode 100644 index 000000000..ef48e9b22 --- /dev/null +++ b/src/pthread/pthread_exit.c @@ -0,0 +1,101 @@ +/* + * pthread_exit.c + * + * Description: + * This translation unit implements routines associated with exiting from + * a thread. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +void +pthread_exit (void *value_ptr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function terminates the calling thread, returning + * the value 'value_ptr' to any joining thread. + * + * PARAMETERS + * value_ptr + * a generic data value (i.e. not the address of a value) + * + * + * DESCRIPTION + * This function terminates the calling thread, returning + * the value 'value_ptr' to any joining thread. + * NOTE: thread should be joinable. + * + * RESULTS + * N/A + * + * ------------------------------------------------------ + */ +{ + pte_thread_t * sp; + + /* + * Don't use pthread_self() to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey); + + if (NULL == sp) + { + /* + * A POSIX thread handle was never created. I.e. this is a + * Win32 thread that has never called a pthreads-win32 routine that + * required a POSIX handle. + * + * Implicit POSIX handles are cleaned up in pte_throw() now. + */ + + /* Terminate thread */ + pte_osThreadExit(); + + /* Never reached */ + } + + sp->exitStatus = value_ptr; + + pte_throw (PTE_EPS_EXIT); + + /* Never reached. */ + +} diff --git a/src/pthread/pthread_getconcurrency.c b/src/pthread/pthread_getconcurrency.c new file mode 100644 index 000000000..ee29b71be --- /dev/null +++ b/src/pthread/pthread_getconcurrency.c @@ -0,0 +1,51 @@ +/* + * pthread_getconcurrency.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_getconcurrency (void) +{ + return pte_concurrency; +} diff --git a/src/pthread/pthread_getschedparam.c b/src/pthread/pthread_getschedparam.c new file mode 100644 index 000000000..3f03902f0 --- /dev/null +++ b/src/pthread/pthread_getschedparam.c @@ -0,0 +1,81 @@ +/* + * sched_getschedparam.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_getschedparam (pthread_t thread, int *policy, + struct sched_param *param) +{ + int result; + + /* Validate the thread id. */ + result = pthread_kill (thread, 0); + if (0 != result) + { + return result; + } + + /* + * Validate the policy and param args. + * Check that a policy constant wasn't passed rather than &policy. + */ + if (policy <= (int *) SCHED_MAX || param == NULL) + { + return EINVAL; + } + + /* Fill out the policy. */ + *policy = SCHED_OTHER; + + /* + * This function must return the priority value set by + * the most recent pthread_setschedparam() or pthread_create() + * for the target thread. It must not return the actual thread + * priority as altered by any system priority adjustments etc. + */ + param->sched_priority = ((pte_thread_t *)thread.p)->sched_priority; + + return 0; +} diff --git a/src/pthread/pthread_getspecific.c b/src/pthread/pthread_getspecific.c new file mode 100644 index 000000000..7dd2f7cb8 --- /dev/null +++ b/src/pthread/pthread_getspecific.c @@ -0,0 +1,86 @@ + +/* + * pthread_getspecific.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "pthread.h" +#include "implement.h" + + +void * +pthread_getspecific (pthread_key_t key) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function returns the current value of key in the + * calling thread. If no value has been set for 'key' in + * the thread, NULL is returned. + * + * PARAMETERS + * key + * an instance of pthread_key_t + * + * + * DESCRIPTION + * This function returns the current value of key in the + * calling thread. If no value has been set for 'key' in + * the thread, NULL is returned. + * + * RESULTS + * key value or NULL on failure + * + * ------------------------------------------------------ + */ +{ + void * ptr; + + if (key == NULL) + { + ptr = NULL; + } + else + { + ptr = pte_osTlsGetValue (key->key); + } + + return ptr; +} diff --git a/src/pthread/pthread_init.c b/src/pthread/pthread_init.c new file mode 100644 index 000000000..316edfe11 --- /dev/null +++ b/src/pthread/pthread_init.c @@ -0,0 +1,91 @@ + +/* + * pthread_init.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int pthread_init(void) +{ + + if (pte_processInitialized) + { + /* + * Ignore if already initialized. this is useful for + * programs that uses a non-dll pthread + * library. Such programs must call pte_processInitialize() explicitly, + * since this initialization routine is automatically called only when + * the dll is loaded. + */ + return PTE_TRUE; + } + + pte_processInitialized = PTE_TRUE; + + // Must happen before creating keys. + pte_osInit(); + + /* + * Initialize Keys + */ + if ((pthread_key_create (&pte_selfThreadKey, NULL) != 0) || + (pthread_key_create (&pte_cleanupKey, NULL) != 0)) + { + pthread_terminate(); + } + + /* + * Set up the global locks. + */ + pte_osMutexCreate (&pte_thread_reuse_lock); + pte_osMutexCreate (&pte_mutex_test_init_lock); + pte_osMutexCreate (&pte_cond_list_lock); + pte_osMutexCreate (&pte_cond_test_init_lock); + pte_osMutexCreate (&pte_rwlock_test_init_lock); + pte_osMutexCreate (&pte_spinlock_test_init_lock); + + + return (pte_processInitialized); + +} diff --git a/src/pthread/pthread_join.c b/src/pthread/pthread_join.c new file mode 100644 index 000000000..2e0545edc --- /dev/null +++ b/src/pthread/pthread_join.c @@ -0,0 +1,164 @@ +/* + * pthread_join.c + * + * Description: + * This translation unit implements functions related to thread + * synchronisation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + +#include + +int +pthread_join (pthread_t thread, void **value_ptr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits for 'thread' to terminate and + * returns the thread's exit value if 'value_ptr' is not + * NULL. This also detaches the thread on successful + * completion. + * + * PARAMETERS + * thread + * an instance of pthread_t + * + * value_ptr + * pointer to an instance of pointer to void + * + * + * DESCRIPTION + * This function waits for 'thread' to terminate and + * returns the thread's exit value if 'value_ptr' is not + * NULL. This also detaches the thread on successful + * completion. + * NOTE: detached threads cannot be joined or canceled + * + * RESULTS + * 0 'thread' has completed + * EINVAL thread is not a joinable thread, + * ESRCH no thread could be found with ID 'thread', + * ENOENT thread couldn't find it's own valid handle, + * EDEADLK attempt to join thread with self + * + * ------------------------------------------------------ + */ +{ + int result; + pthread_t self; + pte_thread_t * tp = (pte_thread_t *) thread.p; + + + pte_osMutexLock (pte_thread_reuse_lock); + + if (NULL == tp + || thread.x != tp->ptHandle.x) + { + result = ESRCH; + } + else if (PTHREAD_CREATE_DETACHED == tp->detachState) + { + result = EINVAL; + } + else + { + result = 0; + } + + pte_osMutexUnlock(pte_thread_reuse_lock); + + if (result == 0) + { + /* + * The target thread is joinable and can't be reused before we join it. + */ + self = pthread_self(); + + if (NULL == self.p) + { + result = ENOENT; + } + else if (pthread_equal (self, thread)) + { + result = EDEADLK; + } + else + { + /* + * Pthread_join is a cancelation point. + * If we are canceled then our target thread must not be + * detached (destroyed). This is guarranteed because + * pthreadCancelableWait will not return if we + * are canceled. + */ + + result = pte_osThreadWaitForEnd(tp->threadId); + + if (PTE_OS_OK == result) + { + if (value_ptr != NULL) + { + *value_ptr = tp->exitStatus; + } + + /* + * The result of making multiple simultaneous calls to + * pthread_join() or pthread_detach() specifying the same + * target is undefined. + */ + result = pthread_detach (thread); + } + else if (result == PTE_OS_INTERRUPTED) + { + /* Call was cancelled, but still return success (per spec) */ + result = 0; + } + else + { + result = ESRCH; + } + } + } + + return (result); + +} /* pthread_join */ diff --git a/src/pthread/pthread_key_create.c b/src/pthread/pthread_key_create.c new file mode 100644 index 000000000..850433c13 --- /dev/null +++ b/src/pthread/pthread_key_create.c @@ -0,0 +1,119 @@ +/* + * pthread_key_create.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pte_osal.h" + +#include "pthread.h" +#include "implement.h" + + +int +pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a thread-specific data key visible + * to all threads. All existing and new threads have a value + * NULL for key until set using pthread_setspecific. When any + * thread with a non-NULL value for key terminates, 'destructor' + * is called with key's current value for that thread. + * + * PARAMETERS + * key + * pointer to an instance of pthread_key_t + * + * + * DESCRIPTION + * This function creates a thread-specific data key visible + * to all threads. All existing and new threads have a value + * NULL for key until set using pthread_setspecific. When any + * thread with a non-NULL value for key terminates, 'destructor' + * is called with key's current value for that thread. + * + * RESULTS + * 0 successfully created semaphore, + * EAGAIN insufficient resources or PTHREAD_KEYS_MAX + * exceeded, + * ENOMEM insufficient memory to create the key, + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_key_t newkey; + + if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL) + { + result = ENOMEM; + } + else + { + pte_osResult osResult = pte_osTlsAlloc(&(newkey->key)); + + if (osResult != PTE_OS_OK) + { + result = EAGAIN; + + free (newkey); + newkey = NULL; + } + else if (destructor != NULL) + { + /* + * Have to manage associations between thread and key; + * Therefore, need a lock that allows multiple threads + * to gain exclusive access to the key->threads list. + * + * The mutex will only be created when it is first locked. + */ + newkey->keyLock = PTHREAD_MUTEX_INITIALIZER; + newkey->destructor = destructor; + } + + } + + *key = newkey; + + return (result); +} diff --git a/src/pthread/pthread_key_delete.c b/src/pthread/pthread_key_delete.c new file mode 100644 index 000000000..37cfcbfb9 --- /dev/null +++ b/src/pthread/pthread_key_delete.c @@ -0,0 +1,140 @@ +/* + * pthread_key_delete.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + + +#include "pthread.h" +#include "implement.h" + + +int +pthread_key_delete (pthread_key_t key) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function deletes a thread-specific data key. This + * does not change the value of the thread specific data key + * for any thread and does not run the key's destructor + * in any thread so it should be used with caution. + * + * PARAMETERS + * key + * pointer to an instance of pthread_key_t + * + * + * DESCRIPTION + * This function deletes a thread-specific data key. This + * does not change the value of the thread specific data key + * for any thread and does not run the key's destructor + * in any thread so it should be used with caution. + * + * RESULTS + * 0 successfully deleted the key, + * EINVAL key is invalid, + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (key != NULL) + { + if (key->threads != NULL && + key->destructor != NULL && + pthread_mutex_lock (&(key->keyLock)) == 0) + { + ThreadKeyAssoc *assoc; + /* + * Run through all Thread<-->Key associations + * for this key. + * + * While we hold at least one of the locks guarding + * the assoc, we know that the assoc pointed to by + * key->threads is valid. + */ + while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL) + { + pte_thread_t * thread = assoc->thread; + + if (assoc == NULL) + { + /* Finished */ + break; + } + + if (pthread_mutex_lock (&(thread->threadLock)) == 0) + { + /* + * Since we are starting at the head of the key's threads + * chain, this will also point key->threads at the next assoc. + * While we hold key->keyLock, no other thread can insert + * a new assoc via pthread_setspecific. + */ + pte_tkAssocDestroy (assoc); + (void) pthread_mutex_unlock (&(thread->threadLock)); + } + else + { + /* Thread or lock is no longer valid? */ + pte_tkAssocDestroy (assoc); + } + } + pthread_mutex_unlock (&(key->keyLock)); + } + + pte_osTlsFree (key->key); + if (key->destructor != NULL) + { + /* A thread could be holding the keyLock */ + while (EBUSY == (result = pthread_mutex_destroy (&(key->keyLock)))) + { + pte_osThreadSleep(1); // Ugly. + } + } + + free (key); + } + + return (result); +} diff --git a/src/pthread/pthread_kill.c b/src/pthread/pthread_kill.c new file mode 100644 index 000000000..d3fd70b03 --- /dev/null +++ b/src/pthread/pthread_kill.c @@ -0,0 +1,107 @@ +/* + * pthread_kill.c + * + * Description: + * This translation unit implements the pthread_kill routine. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_kill (pthread_t thread, int sig) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function requests that a signal be delivered to the + * specified thread. If sig is zero, error checking is + * performed but no signal is actually sent such that this + * function can be used to check for a valid thread ID. + * + * PARAMETERS + * thread reference to an instances of pthread_t + * sig signal. Currently only a value of 0 is supported. + * + * + * DESCRIPTION + * This function requests that a signal be delivered to the + * specified thread. If sig is zero, error checking is + * performed but no signal is actually sent such that this + * function can be used to check for a valid thread ID. + * + * RESULTS + * ESRCH the thread is not a valid thread ID, + * EINVAL the value of the signal is invalid + * or unsupported. + * 0 the signal was successfully sent. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pte_thread_t * tp; + + + pte_osMutexLock (pte_thread_reuse_lock); + + tp = (pte_thread_t *) thread.p; + + if (NULL == tp + || thread.x != tp->ptHandle.x + || 0 == tp->threadId) + { + result = ESRCH; + } + + pte_osMutexUnlock(pte_thread_reuse_lock); + + if (0 == result && 0 != sig) + { + /* + * Currently does not support any signals. + */ + result = EINVAL; + } + + return result; + +} /* pthread_kill */ diff --git a/src/pthread/pthread_mutex_destroy.c b/src/pthread/pthread_mutex_destroy.c new file mode 100644 index 000000000..64a4cde2c --- /dev/null +++ b/src/pthread/pthread_mutex_destroy.c @@ -0,0 +1,154 @@ +/* + * pthread_mutex_destroy.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutex_destroy (pthread_mutex_t * mutex) +{ + int result = 0; + pthread_mutex_t mx; + + /* + * Let the system deal with invalid pointers. + */ + + /* + * Check to see if we have something to delete. + */ + if (*mutex < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + mx = *mutex; + + result = pthread_mutex_trylock (&mx); + + /* + * If trylock succeeded and the mutex is not recursively locked it + * can be destroyed. + */ + if (result == 0) + { + if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count) + { + /* + * FIXME!!! + * The mutex isn't held by another thread but we could still + * be too late invalidating the mutex below since another thread + * may already have entered mutex_lock and the check for a valid + * *mutex != NULL. + * + * Note that this would be an unusual situation because it is not + * common that mutexes are destroyed while they are still in + * use by other threads. + */ + *mutex = NULL; + + result = pthread_mutex_unlock (&mx); + + if (result == 0) + { + pte_osSemaphoreDelete(mx->handle); + + free(mx); + + } + else + { + /* + * Restore the mutex before we return the error. + */ + *mutex = mx; + } + } + else /* mx->recursive_count > 1 */ + { + /* + * The mutex must be recursive and already locked by us (this thread). + */ + mx->recursive_count--; /* Undo effect of pthread_mutex_trylock() above */ + result = EBUSY; + } + } + } + else + { + /* + * See notes in pte_mutex_check_need_init() above also. + */ + + pte_osMutexLock (pte_mutex_test_init_lock); + + + /* + * Check again. + */ + if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised mutex that has not yet been used (initialised). + * If we get to here, another thread + * waiting to initialise this mutex will get an EINVAL. + */ + *mutex = NULL; + } + else + { + /* + * The mutex has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + pte_osMutexUnlock(pte_mutex_test_init_lock); + + } + + return (result); +} diff --git a/src/pthread/pthread_mutex_init.c b/src/pthread/pthread_mutex_init.c new file mode 100644 index 000000000..62f275bc0 --- /dev/null +++ b/src/pthread/pthread_mutex_init.c @@ -0,0 +1,83 @@ +/* + * pthread_mutex_init.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) +{ + int result = 0; + pthread_mutex_t mx; + + + if (mutex == NULL) + { + return EINVAL; + } + + mx = (pthread_mutex_t) calloc (1, sizeof (*mx)); + + if (mx == NULL) + { + result = ENOMEM; + } + else + { + mx->lock_idx = 0; + mx->recursive_count = 0; + mx->kind = (attr == NULL || *attr == NULL + ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); + mx->ownerThread.p = NULL; + + pte_osSemaphoreCreate(0,&mx->handle); + + } + + *mutex = mx; + + return (result); +} diff --git a/src/pthread/pthread_mutex_lock.c b/src/pthread/pthread_mutex_lock.c new file mode 100644 index 000000000..90f5474bc --- /dev/null +++ b/src/pthread/pthread_mutex_lock.c @@ -0,0 +1,140 @@ +/* + * pthread_mutex_lock.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutex_lock (pthread_mutex_t * mutex) +{ + int result = 0; + pthread_mutex_t mx; + + /* + * Let the system deal with invalid pointers. + */ + if (*mutex == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static mutex. We check + * again inside the guarded section of pte_mutex_check_need_init() + * to avoid race conditions. + */ + if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + if ((result = pte_mutex_check_need_init (mutex)) != 0) + { + return (result); + } + } + + mx = *mutex; + + if (mx->kind == PTHREAD_MUTEX_NORMAL) + { + if (PTE_ATOMIC_EXCHANGE( + &mx->lock_idx, + 1) != 0) + { + while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0) + { + if (pte_osSemaphorePend(mx->handle,NULL) != PTE_OS_OK) + { + result = EINVAL; + break; + } + } + } + } + else + { + pthread_t self = pthread_self(); + + if (PTE_ATOMIC_COMPARE_EXCHANGE(&mx->lock_idx,1,0) == 0) + { + mx->recursive_count = 1; + mx->ownerThread = self; + } + else + { + if (pthread_equal (mx->ownerThread, self)) + { + if (mx->kind == PTHREAD_MUTEX_RECURSIVE) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0) + { + if (pte_osSemaphorePend(mx->handle,NULL) != PTE_OS_OK) + { + result = EINVAL; + break; + } + } + + if (0 == result) + { + mx->recursive_count = 1; + mx->ownerThread = self; + } + } + } + + } + + return (result); +} diff --git a/src/pthread/pthread_mutex_timedlock.c b/src/pthread/pthread_mutex_timedlock.c new file mode 100644 index 000000000..7fd42857c --- /dev/null +++ b/src/pthread/pthread_mutex_timedlock.c @@ -0,0 +1,189 @@ +/* + * pthread_mutex_timedlock.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include +#include + +#include "pthread.h" +#include "implement.h" + + +static int +pte_timed_eventwait (pte_osSemaphoreHandle event, const struct timespec *abstime) +/* + * ------------------------------------------------------ + * DESCRIPTION + * This function waits on an event until signaled or until + * abstime passes. + * If abstime has passed when this routine is called then + * it returns a result to indicate this. + * + * If 'abstime' is a NULL pointer then this function will + * block until it can successfully decrease the value or + * until interrupted by a signal. + * + * This routine is not a cancelation point. + * + * RESULTS + * 0 successfully signaled, + * ETIMEDOUT abstime passed + * EINVAL 'event' is not a valid event, + * + * ------------------------------------------------------ + */ +{ + + unsigned int milliseconds; + pte_osResult status; + int retval; + + if (abstime == NULL) + { + status = pte_osSemaphorePend(event, NULL); + } + else + { + /* + * Calculate timeout as milliseconds from current system time. + */ + milliseconds = pte_relmillisecs (abstime); + + status = pte_osSemaphorePend(event, &milliseconds); + } + + + if (status == PTE_OS_TIMEOUT) + { + retval = ETIMEDOUT; + } + else + { + retval = 0; + } + + return retval; + +} /* pte_timed_semwait */ + + +int +pthread_mutex_timedlock (pthread_mutex_t * mutex, + const struct timespec *abstime) +{ + int result; + pthread_mutex_t mx; + + /* + * Let the system deal with invalid pointers. + */ + + /* + * We do a quick check to see if we need to do more work + * to initialise a static mutex. We check + * again inside the guarded section of pte_mutex_check_need_init() + * to avoid race conditions. + */ + if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + if ((result = pte_mutex_check_need_init (mutex)) != 0) + { + return (result); + } + } + + mx = *mutex; + + if (mx->kind == PTHREAD_MUTEX_NORMAL) + { + if (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,1) != 0) + { + while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0) + { + if (0 != (result = pte_timed_eventwait (mx->handle, abstime))) + { + return result; + } + } + } + } + else + { + pthread_t self = pthread_self(); + + if (PTE_ATOMIC_COMPARE_EXCHANGE(&mx->lock_idx,1,0) == 0) + { + mx->recursive_count = 1; + mx->ownerThread = self; + } + else + { + if (pthread_equal (mx->ownerThread, self)) + { + if (mx->kind == PTHREAD_MUTEX_RECURSIVE) + { + mx->recursive_count++; + } + else + { + return EDEADLK; + } + } + else + { + while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0) + { + if (0 != (result = pte_timed_eventwait (mx->handle, abstime))) + { + return result; + } + } + + mx->recursive_count = 1; + mx->ownerThread = self; + } + } + } + + return 0; +} diff --git a/src/pthread/pthread_mutex_trylock.c b/src/pthread/pthread_mutex_trylock.c new file mode 100644 index 000000000..ce1cc7f72 --- /dev/null +++ b/src/pthread/pthread_mutex_trylock.c @@ -0,0 +1,95 @@ +/* + * pthread_mutex_trylock.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutex_trylock (pthread_mutex_t * mutex) +{ + int result = 0; + pthread_mutex_t mx; + + /* + * Let the system deal with invalid pointers. + */ + + /* + * We do a quick check to see if we need to do more work + * to initialise a static mutex. We check + * again inside the guarded section of pte_mutex_check_need_init() + * to avoid race conditions. + */ + if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + if ((result = pte_mutex_check_need_init (mutex)) != 0) + { + return (result); + } + } + + mx = *mutex; + + if (0 == PTE_ATOMIC_COMPARE_EXCHANGE (&mx->lock_idx,1,0)) + { + if (mx->kind != PTHREAD_MUTEX_NORMAL) + { + mx->recursive_count = 1; + mx->ownerThread = pthread_self (); + } + } + else + { + if (mx->kind == PTHREAD_MUTEX_RECURSIVE && + pthread_equal (mx->ownerThread, pthread_self ())) + { + mx->recursive_count++; + } + else + { + result = EBUSY; + } + } + + return (result); +} diff --git a/src/pthread/pthread_mutex_unlock.c b/src/pthread/pthread_mutex_unlock.c new file mode 100644 index 000000000..17bce62a4 --- /dev/null +++ b/src/pthread/pthread_mutex_unlock.c @@ -0,0 +1,130 @@ +/* + * pthread_mutex_unlock.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include +#include + +#include "pthread.h" +#include "implement.h" + + +#define TEST_IE InterlockedExchange + +int +pthread_mutex_unlock (pthread_mutex_t * mutex) +{ + int result = 0; + pthread_mutex_t mx; + + /* + * Let the system deal with invalid pointers. + */ + + mx = *mutex; + + /* + * If the thread calling us holds the mutex then there is no + * race condition. If another thread holds the + * lock then we shouldn't be in here. + */ + if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) + { + if (mx->kind == PTHREAD_MUTEX_NORMAL) + { + int idx; + + idx = PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0); + if (idx != 0) + { + if (idx < 0) + { + /* + * Someone may be waiting on that mutex. + */ + if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK) + { + result = EINVAL; + } + } + } + else + { + /* + * Was not locked (so can't be owned by us). + */ + result = EPERM; + } + } + else + { + if (pthread_equal (mx->ownerThread, pthread_self ())) + { + if (mx->kind != PTHREAD_MUTEX_RECURSIVE + || 0 == --mx->recursive_count) + { + mx->ownerThread.p = NULL; + + if (PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0) < 0) + { + if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK) + { + result = EINVAL; + } + + } + } + } + else + { + result = EPERM; + } + } + } + else + { + result = EINVAL; + } + + return (result); +} diff --git a/src/pthread/pthread_mutexattr_destroy.c b/src/pthread/pthread_mutexattr_destroy.c new file mode 100644 index 000000000..9cef18cad --- /dev/null +++ b/src/pthread/pthread_mutexattr_destroy.c @@ -0,0 +1,91 @@ +/* + * pthread_mutexattr_destroy.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_destroy (pthread_mutexattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Destroys a mutex attributes object. The object can + * no longer be used. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * + * DESCRIPTION + * Destroys a mutex attributes object. The object can + * no longer be used. + * + * NOTES: + * 1) Does not affect mutexes created using 'attr' + * + * RESULTS + * 0 successfully released attr, + * EINVAL 'attr' is invalid. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (attr == NULL || *attr == NULL) + { + result = EINVAL; + } + else + { + pthread_mutexattr_t ma = *attr; + + *attr = NULL; + free (ma); + } + + return (result); +} /* pthread_mutexattr_destroy */ diff --git a/src/pthread/pthread_mutexattr_getkind_np.c b/src/pthread/pthread_mutexattr_getkind_np.c new file mode 100644 index 000000000..d4e201514 --- /dev/null +++ b/src/pthread/pthread_mutexattr_getkind_np.c @@ -0,0 +1,50 @@ +/* + * pthread_mutexattr_getkind_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +int +pthread_mutexattr_getkind_np (pthread_mutexattr_t * attr, int *kind) +{ + return pthread_mutexattr_gettype (attr, kind); +} diff --git a/src/pthread/pthread_mutexattr_getpshared.c b/src/pthread/pthread_mutexattr_getpshared.c new file mode 100644 index 000000000..f965df909 --- /dev/null +++ b/src/pthread/pthread_mutexattr_getpshared.c @@ -0,0 +1,101 @@ +/* + * pthread_mutexattr_getpshared.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr, int *pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Determine whether mutexes created with 'attr' can be + * shared between processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * pshared + * will be set to one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * + * DESCRIPTION + * Mutexes creatd with 'attr' can be shared between + * processes if pthread_mutex_t variable is allocated + * in memory shared by these processes. + * NOTES: + * 1) pshared mutexes MUST be allocated in shared + * memory. + * 2) The following macro is defined if shared mutexes + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully retrieved attribute, + * EINVAL 'attr' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && (pshared != NULL)) + { + *pshared = (*attr)->pshared; + result = 0; + } + else + { + result = EINVAL; + } + + return (result); + +} /* pthread_mutexattr_getpshared */ diff --git a/src/pthread/pthread_mutexattr_gettype.c b/src/pthread/pthread_mutexattr_gettype.c new file mode 100644 index 000000000..ddf66a728 --- /dev/null +++ b/src/pthread/pthread_mutexattr_gettype.c @@ -0,0 +1,62 @@ +/* + * pthread_mutexattr_gettype.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind) +{ + int result = 0; + + if (attr != NULL && *attr != NULL && kind != NULL) + { + *kind = (*attr)->kind; + } + else + { + result = EINVAL; + } + + return (result); +} diff --git a/src/pthread/pthread_mutexattr_init.c b/src/pthread/pthread_mutexattr_init.c new file mode 100644 index 000000000..d2b58127e --- /dev/null +++ b/src/pthread/pthread_mutexattr_init.c @@ -0,0 +1,94 @@ +/* + * pthread_mutexattr_init.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_init (pthread_mutexattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Initializes a mutex attributes object with default + * attributes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * + * DESCRIPTION + * Initializes a mutex attributes object with default + * attributes. + * + * NOTES: + * 1) Used to define mutex types + * + * RESULTS + * 0 successfully initialized attr, + * ENOMEM insufficient memory for attr. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_mutexattr_t ma; + + ma = (pthread_mutexattr_t) calloc (1, sizeof (*ma)); + + if (ma == NULL) + { + result = ENOMEM; + } + else + { + ma->pshared = PTHREAD_PROCESS_PRIVATE; + ma->kind = PTHREAD_MUTEX_DEFAULT; + } + + *attr = ma; + + return (result); +} /* pthread_mutexattr_init */ diff --git a/src/pthread/pthread_mutexattr_setkind_np.c b/src/pthread/pthread_mutexattr_setkind_np.c new file mode 100644 index 000000000..51991a07b --- /dev/null +++ b/src/pthread/pthread_mutexattr_setkind_np.c @@ -0,0 +1,50 @@ +/* + * pthread_mutexattr_setkind_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +int +pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr, int kind) +{ + return pthread_mutexattr_settype (attr, kind); +} diff --git a/src/pthread/pthread_mutexattr_setpshared.c b/src/pthread/pthread_mutexattr_setpshared.c new file mode 100644 index 000000000..80e581d9c --- /dev/null +++ b/src/pthread/pthread_mutexattr_setpshared.c @@ -0,0 +1,125 @@ +/* + * pthread_mutexattr_setpshared.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Mutexes created with 'attr' can be shared between + * processes if pthread_mutex_t variable is allocated + * in memory shared by these processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * pshared + * must be one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * DESCRIPTION + * Mutexes creatd with 'attr' can be shared between + * processes if pthread_mutex_t variable is allocated + * in memory shared by these processes. + * + * NOTES: + * 1) pshared mutexes MUST be allocated in shared + * memory. + * + * 2) The following macro is defined if shared mutexes + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or pshared is invalid, + * ENOSYS PTHREAD_PROCESS_SHARED not supported, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && + ((pshared == PTHREAD_PROCESS_SHARED) || + (pshared == PTHREAD_PROCESS_PRIVATE))) + { + if (pshared == PTHREAD_PROCESS_SHARED) + { + +#if !defined( _POSIX_THREAD_PROCESS_SHARED ) + + result = ENOSYS; + pshared = PTHREAD_PROCESS_PRIVATE; + +#else + + result = 0; + +#endif /* _POSIX_THREAD_PROCESS_SHARED */ + + } + else + { + result = 0; + } + + (*attr)->pshared = pshared; + } + else + { + result = EINVAL; + } + + return (result); + +} /* pthread_mutexattr_setpshared */ diff --git a/src/pthread/pthread_mutexattr_settype.c b/src/pthread/pthread_mutexattr_settype.c new file mode 100644 index 000000000..da510103d --- /dev/null +++ b/src/pthread/pthread_mutexattr_settype.c @@ -0,0 +1,149 @@ +/* + * pthread_mutexattr_settype.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind) +/* + * ------------------------------------------------------ + * + * DOCPUBLIC + * The pthread_mutexattr_settype() and + * pthread_mutexattr_gettype() functions respectively set and + * get the mutex type attribute. This attribute is set in the + * type parameter to these functions. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * type + * must be one of: + * + * PTHREAD_MUTEX_DEFAULT + * + * PTHREAD_MUTEX_NORMAL + * + * PTHREAD_MUTEX_ERRORCHECK + * + * PTHREAD_MUTEX_RECURSIVE + * + * DESCRIPTION + * The pthread_mutexattr_settype() and + * pthread_mutexattr_gettype() functions respectively set and + * get the mutex type attribute. This attribute is set in the + * type parameter to these functions. The default value of the + * type attribute is PTHREAD_MUTEX_DEFAULT. + * + * The type of mutex is contained in the type attribute of the + * mutex attributes. Valid mutex types include: + * + * PTHREAD_MUTEX_NORMAL + * This type of mutex does not detect deadlock. A + * thread attempting to relock this mutex without + * first unlocking it will deadlock. Attempting to + * unlock a mutex locked by a different thread + * results in undefined behavior. Attempting to + * unlock an unlocked mutex results in undefined + * behavior. + * + * PTHREAD_MUTEX_ERRORCHECK + * This type of mutex provides error checking. A + * thread attempting to relock this mutex without + * first unlocking it will return with an error. A + * thread attempting to unlock a mutex which another + * thread has locked will return with an error. A + * thread attempting to unlock an unlocked mutex will + * return with an error. + * + * PTHREAD_MUTEX_DEFAULT + * Same as PTHREAD_MUTEX_NORMAL. + * + * PTHREAD_MUTEX_RECURSIVE + * A thread attempting to relock this mutex without + * first unlocking it will succeed in locking the + * mutex. The relocking deadlock which can occur with + * mutexes of type PTHREAD_MUTEX_NORMAL cannot occur + * with this type of mutex. Multiple locks of this + * mutex require the same number of unlocks to + * release the mutex before another thread can + * acquire the mutex. A thread attempting to unlock a + * mutex which another thread has locked will return + * with an error. A thread attempting to unlock an + * unlocked mutex will return with an error. This + * type of mutex is only supported for mutexes whose + * process shared attribute is + * PTHREAD_PROCESS_PRIVATE. + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or 'type' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if ((attr != NULL && *attr != NULL)) + { + switch (kind) + { + case PTHREAD_MUTEX_FAST_NP: + case PTHREAD_MUTEX_RECURSIVE_NP: + case PTHREAD_MUTEX_ERRORCHECK_NP: + (*attr)->kind = kind; + break; + default: + result = EINVAL; + break; + } + } + else + { + result = EINVAL; + } + + return (result); +} /* pthread_mutexattr_settype */ diff --git a/src/pthread/pthread_num_processors_np.c b/src/pthread/pthread_num_processors_np.c new file mode 100644 index 000000000..a68fb1ad4 --- /dev/null +++ b/src/pthread/pthread_num_processors_np.c @@ -0,0 +1,62 @@ +/* + * pthread_num_processors_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +/* + * pthread_num_processors_np() + * + * Get the number of CPUs available to the process. + */ +int +pthread_num_processors_np (void) +{ + int count; + + if (pte_getprocessors (&count) != 0) + { + count = 1; + } + + return (count); +} diff --git a/src/pthread/pthread_once.c b/src/pthread/pthread_once.c new file mode 100644 index 000000000..a8166f51c --- /dev/null +++ b/src/pthread/pthread_once.c @@ -0,0 +1,186 @@ +/* + * pthread_once.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pte_osal.h" +#include "pthread.h" +#include "implement.h" + +#define PTE_ONCE_STARTED 1 +#define PTE_ONCE_INIT 0 +#define PTE_ONCE_DONE 2 + +static void +pte_once_init_routine_cleanup(void * arg) +{ + pthread_once_t * once_control = (pthread_once_t *) arg; + + (void) PTE_ATOMIC_EXCHANGE(&once_control->state,PTE_ONCE_INIT); + + if (PTE_ATOMIC_EXCHANGE_ADD((int*)&once_control->semaphore, 0L)) /* MBR fence */ + { + pte_osSemaphorePost((pte_osSemaphoreHandle) once_control->semaphore, 1); + } +} + +int +pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * If any thread in a process with a once_control parameter + * makes a call to pthread_once(), the first call will summon + * the init_routine(), but subsequent calls will not. The + * once_control parameter determines whether the associated + * initialization routine has been called. The init_routine() + * is complete upon return of pthread_once(). + * This function guarantees that one and only one thread + * executes the initialization routine, init_routine when + * access is controlled by the pthread_once_t control + * key. + * + * pthread_once() is not a cancelation point, but the init_routine + * can be. If it's cancelled then the effect on the once_control is + * as if pthread_once had never been entered. + * + * + * PARAMETERS + * once_control + * pointer to an instance of pthread_once_t + * + * init_routine + * pointer to an initialization routine + * + * + * DESCRIPTION + * See above. + * + * RESULTS + * 0 success, + * EINVAL once_control or init_routine is NULL + * + * ------------------------------------------------------ + */ +{ + int result; + int state; + pte_osSemaphoreHandle sema; + + if (once_control == NULL || init_routine == NULL) + { + result = EINVAL; + goto FAIL0; + } + else + { + result = 0; + } + + while ((state = + PTE_ATOMIC_COMPARE_EXCHANGE(&once_control->state, + PTE_ONCE_STARTED, + PTE_ONCE_INIT)) + != PTE_ONCE_DONE) + { + if (PTE_ONCE_INIT == state) + { + + + pthread_cleanup_push(pte_once_init_routine_cleanup, (void *) once_control); + (*init_routine)(); + pthread_cleanup_pop(0); + + (void) PTE_ATOMIC_EXCHANGE(&once_control->state,PTE_ONCE_DONE); + + /* + * we didn't create the semaphore. + * it is only there if there is someone waiting. + */ + if (PTE_ATOMIC_EXCHANGE_ADD((int*)&once_control->semaphore, 0L)) /* MBR fence */ + { + pte_osSemaphorePost((pte_osSemaphoreHandle) once_control->semaphore,once_control->numSemaphoreUsers); + } + } + else + { + PTE_ATOMIC_INCREMENT(&once_control->numSemaphoreUsers); + + if (!PTE_ATOMIC_EXCHANGE_ADD((int*)&once_control->semaphore, 0L)) /* MBR fence */ + { + pte_osSemaphoreCreate(0, (pte_osSemaphoreHandle*) &sema); + + if (PTE_ATOMIC_COMPARE_EXCHANGE((int *) &once_control->semaphore, + (int) sema, + 0)) + { + pte_osSemaphoreDelete((pte_osSemaphoreHandle)sema); + } + } + + /* + * Check 'state' again in case the initting thread has finished or + * cancelled and left before seeing that there was a semaphore. + */ + if (PTE_ATOMIC_EXCHANGE_ADD(&once_control->state, 0L) == PTE_ONCE_STARTED) + { + pte_osSemaphorePend((pte_osSemaphoreHandle) once_control->semaphore,NULL); + } + + if (0 == PTE_ATOMIC_DECREMENT(&once_control->numSemaphoreUsers)) + { + /* we were last */ + if ((sema = + (pte_osSemaphoreHandle) PTE_ATOMIC_EXCHANGE((int *) &once_control->semaphore,0))) + { + pte_osSemaphoreDelete(sema); + } + } + } + } + + /* + * ------------ + * Failure Code + * ------------ + */ +FAIL0: + return (result); +} /* pthread_once */ diff --git a/src/pthread/pthread_rwlock_destroy.c b/src/pthread/pthread_rwlock_destroy.c new file mode 100644 index 000000000..0f4904790 --- /dev/null +++ b/src/pthread/pthread_rwlock_destroy.c @@ -0,0 +1,152 @@ +/* + * pthread_rwlock_destroy.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_destroy (pthread_rwlock_t * rwlock) +{ + pthread_rwlock_t rwl; + int result = 0, result1 = 0, result2 = 0; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + if (*rwlock != PTHREAD_RWLOCK_INITIALIZER) + { + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if ((result = + pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + /* + * Check whether any threads own/wait for the lock (wait for ex.access); + * report "BUSY" if so. + */ + if (rwl->nExclusiveAccessCount > 0 + || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount) + { + result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); + result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + result2 = EBUSY; + } + else + { + rwl->nMagic = 0; + + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + pthread_mutex_unlock (&rwl->mtxExclusiveAccess); + return result; + } + + if ((result = + pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + *rwlock = NULL; /* Invalidate rwlock before anything else */ + result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted)); + result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); + result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); + (void) free (rwl); + } + } + else + { + /* + * See notes in pte_rwlock_check_need_init() above also. + */ + + pte_osMutexLock (pte_rwlock_test_init_lock); + + /* + * Check again. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised rwlock that has not yet been used (initialised). + * If we get to here, another thread + * waiting to initialise this rwlock will get an EINVAL. + */ + *rwlock = NULL; + } + else + { + /* + * The rwlock has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + pte_osMutexUnlock(pte_rwlock_test_init_lock); + + } + + return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); +} diff --git a/src/pthread/pthread_rwlock_init.c b/src/pthread/pthread_rwlock_init.c new file mode 100644 index 000000000..847bfab31 --- /dev/null +++ b/src/pthread/pthread_rwlock_init.c @@ -0,0 +1,117 @@ +/* + * pthread_rwlock_init.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_init (pthread_rwlock_t * rwlock, + const pthread_rwlockattr_t * attr) +{ + int result; + pthread_rwlock_t rwl = 0; + + if (rwlock == NULL) + { + return EINVAL; + } + + if (attr != NULL && *attr != NULL) + { + result = EINVAL; /* Not supported */ + goto DONE; + } + + rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl)); + + if (rwl == NULL) + { + result = ENOMEM; + goto DONE; + } + + rwl->nSharedAccessCount = 0; + rwl->nExclusiveAccessCount = 0; + rwl->nCompletedSharedAccessCount = 0; + + result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL); + if (result != 0) + { + goto FAIL0; + } + + result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL); + if (result != 0) + { + goto FAIL1; + } + + result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL); + if (result != 0) + { + goto FAIL2; + } + + rwl->nMagic = PTE_RWLOCK_MAGIC; + + result = 0; + goto DONE; + +FAIL2: + (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); + +FAIL1: + (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); + +FAIL0: + (void) free (rwl); + rwl = NULL; + +DONE: + *rwlock = rwl; + + return result; +} diff --git a/src/pthread/pthread_rwlock_rdlock.c b/src/pthread/pthread_rwlock_rdlock.c new file mode 100644 index 000000000..ad6dd9915 --- /dev/null +++ b/src/pthread/pthread_rwlock_rdlock.c @@ -0,0 +1,109 @@ +/* + * pthread_rwlock_rdlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_rdlock (pthread_rwlock_t * rwlock) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if (++rwl->nSharedAccessCount == INT_MAX) + { + if ((result = + pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + } + + return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))); +} diff --git a/src/pthread/pthread_rwlock_timedrdlock.c b/src/pthread/pthread_rwlock_timedrdlock.c new file mode 100644 index 000000000..111205b52 --- /dev/null +++ b/src/pthread/pthread_rwlock_timedrdlock.c @@ -0,0 +1,116 @@ +/* + * pthread_rwlock_timedrdlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, + const struct timespec *abstime) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = + pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0) + { + return result; + } + + if (++rwl->nSharedAccessCount == INT_MAX) + { + if ((result = + pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted), + abstime)) != 0) + { + if (result == ETIMEDOUT) + { + ++rwl->nCompletedSharedAccessCount; + } + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + } + + return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))); +} diff --git a/src/pthread/pthread_rwlock_timedwrlock.c b/src/pthread/pthread_rwlock_timedwrlock.c new file mode 100644 index 000000000..3611e1b29 --- /dev/null +++ b/src/pthread/pthread_rwlock_timedwrlock.c @@ -0,0 +1,140 @@ +/* + * pthread_rwlock_timedwrlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, + const struct timespec *abstime) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = + pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0) + { + return result; + } + + if ((result = + pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted), + abstime)) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + if (rwl->nExclusiveAccessCount == 0) + { + if (rwl->nCompletedSharedAccessCount > 0) + { + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + } + + if (rwl->nSharedAccessCount > 0) + { + rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; + + /* + * This routine may be a cancelation point + * according to POSIX 1003.1j section 18.1.2. + */ + pthread_cleanup_push (pte_rwlock_cancelwrwait, (void *) rwl); + + do + { + result = + pthread_cond_timedwait (&(rwl->cndSharedAccessCompleted), + &(rwl->mtxSharedAccessCompleted), + abstime); + } + while (result == 0 && rwl->nCompletedSharedAccessCount < 0); + + pthread_cleanup_pop ((result != 0) ? 1 : 0); + + if (result == 0) + { + rwl->nSharedAccessCount = 0; + } + } + } + + if (result == 0) + { + rwl->nExclusiveAccessCount++; + } + + return result; +} diff --git a/src/pthread/pthread_rwlock_tryrdlock.c b/src/pthread/pthread_rwlock_tryrdlock.c new file mode 100644 index 000000000..65b683b20 --- /dev/null +++ b/src/pthread/pthread_rwlock_tryrdlock.c @@ -0,0 +1,109 @@ +/* + * pthread_rwlock_tryrdlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if (++rwl->nSharedAccessCount == INT_MAX) + { + if ((result = + pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + } + + return (pthread_mutex_unlock (&rwl->mtxExclusiveAccess)); +} diff --git a/src/pthread/pthread_rwlock_trywrlock.c b/src/pthread/pthread_rwlock_trywrlock.c new file mode 100644 index 000000000..19172bb52 --- /dev/null +++ b/src/pthread/pthread_rwlock_trywrlock.c @@ -0,0 +1,129 @@ +/* + * pthread_rwlock_trywrlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock) +{ + int result, result1; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if ((result = + pthread_mutex_trylock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return ((result1 != 0) ? result1 : result); + } + + if (rwl->nExclusiveAccessCount == 0) + { + if (rwl->nCompletedSharedAccessCount > 0) + { + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + } + + if (rwl->nSharedAccessCount > 0) + { + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + if ((result = + pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) == 0) + { + result = EBUSY; + } + } + else + { + rwl->nExclusiveAccessCount = 1; + } + } + else + { + result = EBUSY; + } + + return result; +} diff --git a/src/pthread/pthread_rwlock_unlock.c b/src/pthread/pthread_rwlock_unlock.c new file mode 100644 index 000000000..931c8233b --- /dev/null +++ b/src/pthread/pthread_rwlock_unlock.c @@ -0,0 +1,100 @@ +/* + * pthread_rwlock_unlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_unlock (pthread_rwlock_t * rwlock) +{ + int result, result1; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return (EINVAL); + } + + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + /* + * Assume any race condition here is harmless. + */ + return 0; + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if (rwl->nExclusiveAccessCount == 0) + { + if ((result = + pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + return result; + } + + if (++rwl->nCompletedSharedAccessCount == 0) + { + result = pthread_cond_signal (&(rwl->cndSharedAccessCompleted)); + } + + result1 = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); + } + else + { + rwl->nExclusiveAccessCount--; + + result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); + result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + + } + + return ((result != 0) ? result : result1); +} diff --git a/src/pthread/pthread_rwlock_wrlock.c b/src/pthread/pthread_rwlock_wrlock.c new file mode 100644 index 000000000..33ff5c227 --- /dev/null +++ b/src/pthread/pthread_rwlock_wrlock.c @@ -0,0 +1,134 @@ +/* + * pthread_rwlock_wrlock.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_wrlock (pthread_rwlock_t * rwlock) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of pte_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = pte_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTE_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + if (rwl->nExclusiveAccessCount == 0) + { + if (rwl->nCompletedSharedAccessCount > 0) + { + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + } + + if (rwl->nSharedAccessCount > 0) + { + rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; + + /* + * This routine may be a cancelation point + * according to POSIX 1003.1j section 18.1.2. + */ + pthread_cleanup_push (pte_rwlock_cancelwrwait, (void *) rwl); + + do + { + result = pthread_cond_wait (&(rwl->cndSharedAccessCompleted), + &(rwl->mtxSharedAccessCompleted)); + } + while (result == 0 && rwl->nCompletedSharedAccessCount < 0); + + pthread_cleanup_pop ((result != 0) ? 1 : 0); + + if (result == 0) + { + rwl->nSharedAccessCount = 0; + } + } + } + + if (result == 0) + { + rwl->nExclusiveAccessCount++; + } + + return result; +} diff --git a/src/pthread/pthread_rwlockattr_destroy.c b/src/pthread/pthread_rwlockattr_destroy.c new file mode 100644 index 000000000..4587329bc --- /dev/null +++ b/src/pthread/pthread_rwlockattr_destroy.c @@ -0,0 +1,92 @@ +/* + * pthread_rwlockattr_destroy.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Destroys a rwlock attributes object. The object can + * no longer be used. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_rwlockattr_t + * + * + * DESCRIPTION + * Destroys a rwlock attributes object. The object can + * no longer be used. + * + * NOTES: + * 1) Does not affect rwlockss created using 'attr' + * + * RESULTS + * 0 successfully released attr, + * EINVAL 'attr' is invalid. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (attr == NULL || *attr == NULL) + { + result = EINVAL; + } + else + { + pthread_rwlockattr_t rwa = *attr; + + *attr = NULL; + free (rwa); + } + + return (result); +} /* pthread_rwlockattr_destroy */ diff --git a/src/pthread/pthread_rwlockattr_getpshared.c b/src/pthread/pthread_rwlockattr_getpshared.c new file mode 100644 index 000000000..c3e75aed3 --- /dev/null +++ b/src/pthread/pthread_rwlockattr_getpshared.c @@ -0,0 +1,104 @@ +/* + * pthread_rwlockattr_getpshared.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Determine whether rwlocks created with 'attr' can be + * shared between processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_rwlockattr_t + * + * pshared + * will be set to one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * + * DESCRIPTION + * Rwlocks creatd with 'attr' can be shared between + * processes if pthread_rwlock_t variable is allocated + * in memory shared by these processes. + * NOTES: + * 1) pshared rwlocks MUST be allocated in shared + * memory. + * 2) The following macro is defined if shared rwlocks + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully retrieved attribute, + * EINVAL 'attr' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && (pshared != NULL)) + { + *pshared = (*attr)->pshared; + result = 0; + } + else + { + result = EINVAL; + } + + return (result); + +} /* pthread_rwlockattr_getpshared */ diff --git a/src/pthread/pthread_rwlockattr_init.c b/src/pthread/pthread_rwlockattr_init.c new file mode 100644 index 000000000..d1dbaf112 --- /dev/null +++ b/src/pthread/pthread_rwlockattr_init.c @@ -0,0 +1,91 @@ +/* + * pthread_rwlockattr_init.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlockattr_init (pthread_rwlockattr_t * attr) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Initializes a rwlock attributes object with default + * attributes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_rwlockattr_t + * + * + * DESCRIPTION + * Initializes a rwlock attributes object with default + * attributes. + * + * RESULTS + * 0 successfully initialized attr, + * ENOMEM insufficient memory for attr. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_rwlockattr_t rwa; + + rwa = (pthread_rwlockattr_t) calloc (1, sizeof (*rwa)); + + if (rwa == NULL) + { + result = ENOMEM; + } + else + { + rwa->pshared = PTHREAD_PROCESS_PRIVATE; + } + + *attr = rwa; + + return (result); +} /* pthread_rwlockattr_init */ diff --git a/src/pthread/pthread_rwlockattr_setpshared.c b/src/pthread/pthread_rwlockattr_setpshared.c new file mode 100644 index 000000000..58c3f76c7 --- /dev/null +++ b/src/pthread/pthread_rwlockattr_setpshared.c @@ -0,0 +1,127 @@ +/* + * pthread_rwlockattr_setpshared.c + * + * Description: + * This translation unit implements read/write lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Rwlocks created with 'attr' can be shared between + * processes if pthread_rwlock_t variable is allocated + * in memory shared by these processes. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_rwlockattr_t + * + * pshared + * must be one of: + * + * PTHREAD_PROCESS_SHARED + * May be shared if in shared memory + * + * PTHREAD_PROCESS_PRIVATE + * Cannot be shared. + * + * DESCRIPTION + * Rwlocks creatd with 'attr' can be shared between + * processes if pthread_rwlock_t variable is allocated + * in memory shared by these processes. + * + * NOTES: + * 1) pshared rwlocks MUST be allocated in shared + * memory. + * + * 2) The following macro is defined if shared rwlocks + * are supported: + * _POSIX_THREAD_PROCESS_SHARED + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or pshared is invalid, + * ENOSYS PTHREAD_PROCESS_SHARED not supported, + * + * ------------------------------------------------------ + */ +{ + int result; + + if ((attr != NULL && *attr != NULL) && + ((pshared == PTHREAD_PROCESS_SHARED) || + (pshared == PTHREAD_PROCESS_PRIVATE))) + { + if (pshared == PTHREAD_PROCESS_SHARED) + { + +#if !defined( _POSIX_THREAD_PROCESS_SHARED ) + + result = ENOSYS; + pshared = PTHREAD_PROCESS_PRIVATE; + +#else + + result = 0; + +#endif /* _POSIX_THREAD_PROCESS_SHARED */ + + } + else + { + result = 0; + } + + (*attr)->pshared = pshared; + } + else + { + result = EINVAL; + } + + return (result); + +} /* pthread_rwlockattr_setpshared */ diff --git a/src/pthread/pthread_self.c b/src/pthread/pthread_self.c new file mode 100644 index 000000000..20b371fcd --- /dev/null +++ b/src/pthread/pthread_self.c @@ -0,0 +1,117 @@ +/* + * pthread_self.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +pthread_t +pthread_self (void) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function returns a reference to the current running + * thread. + * + * PARAMETERS + * N/A + * + * + * DESCRIPTION + * This function returns a reference to the current running + * thread. + * + * RESULTS + * pthread_t reference to the current thread + * + * ------------------------------------------------------ + */ +{ + pthread_t self; + pte_thread_t * sp; + + sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey); + + if (sp != NULL) + { + self = sp->ptHandle; + } + else + { + /* + * Need to create an implicit 'self' for the currently + * executing thread. + * + * Note that this is a potential memory leak as there is + * no way to free the memory and any resources allocated + * by pte_new! + */ + self = pte_new (); + sp = (pte_thread_t *) self.p; + + if (sp != NULL) + { + /* + * This is a non-POSIX thread which has chosen to call + * a POSIX threads function for some reason. We assume that + * it isn't joinable, but we do assume that it's + * (deferred) cancelable. + */ + sp->implicit = 1; + sp->detachState = PTHREAD_CREATE_DETACHED; + + sp->threadId = pte_osThreadGetHandle(); + /* + * No need to explicitly serialise access to sched_priority + * because the new handle is not yet public. + */ + sp->sched_priority = 0; + + pthread_setspecific (pte_selfThreadKey, (void *) sp); + } + } + + return (self); + +} /* pthread_self */ diff --git a/src/pthread/pthread_setcancelstate.c b/src/pthread/pthread_setcancelstate.c new file mode 100644 index 000000000..b2348c87d --- /dev/null +++ b/src/pthread/pthread_setcancelstate.c @@ -0,0 +1,129 @@ +/* + * pthread_setcancelstate.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_setcancelstate (int state, int *oldstate) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function atomically sets the calling thread's + * cancelability state to 'state' and returns the previous + * cancelability state at the location referenced by + * 'oldstate' + * + * PARAMETERS + * state, + * oldstate + * PTHREAD_CANCEL_ENABLE + * cancellation is enabled, + * + * PTHREAD_CANCEL_DISABLE + * cancellation is disabled + * + * + * DESCRIPTION + * This function atomically sets the calling thread's + * cancelability state to 'state' and returns the previous + * cancelability state at the location referenced by + * 'oldstate'. + * + * NOTES: + * 1) Use to disable cancellation around 'atomic' code that + * includes cancellation points + * + * COMPATIBILITY ADDITIONS + * If 'oldstate' is NULL then the previous state is not returned + * but the function still succeeds. (Solaris) + * + * RESULTS + * 0 successfully set cancelability type, + * EINVAL 'state' is invalid + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_t self = pthread_self (); + pte_thread_t * sp = (pte_thread_t *) self.p; + + if (sp == NULL + || (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)) + { + return EINVAL; + } + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock (&sp->cancelLock); + + if (oldstate != NULL) + { + *oldstate = sp->cancelState; + } + + sp->cancelState = state; + + /* + * Check if there is a pending asynchronous cancel + */ + if (state == PTHREAD_CANCEL_ENABLE + && (sp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS) + && (pte_osThreadCheckCancel(sp->threadId) == PTE_OS_INTERRUPTED) ) + { + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock (&sp->cancelLock); + pte_throw (PTE_EPS_CANCEL); + + /* Never reached */ + } + + (void) pthread_mutex_unlock (&sp->cancelLock); + + return (result); + +} /* pthread_setcancelstate */ diff --git a/src/pthread/pthread_setcanceltype.c b/src/pthread/pthread_setcanceltype.c new file mode 100644 index 000000000..21a273ace --- /dev/null +++ b/src/pthread/pthread_setcanceltype.c @@ -0,0 +1,142 @@ +/* + * pthread_setcanceltype.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_setcanceltype (int type, int *oldtype) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function atomically sets the calling thread's + * cancelability type to 'type' and returns the previous + * cancelability type at the location referenced by + * 'oldtype' + * + * PARAMETERS + * type, + * oldtype + * PTHREAD_CANCEL_DEFERRED + * only deferred cancelation is allowed, + * + * PTHREAD_CANCEL_ASYNCHRONOUS + * Asynchronous cancellation is allowed + * + * + * DESCRIPTION + * This function atomically sets the calling thread's + * cancelability type to 'type' and returns the previous + * cancelability type at the location referenced by + * 'oldtype' + * + * NOTES: + * 1) Use with caution; most code is not safe for use + * with asynchronous cancelability. + * + * COMPATIBILITY ADDITIONS + * If 'oldtype' is NULL then the previous type is not returned + * but the function still succeeds. (Solaris) + * + * RESULTS + * 0 successfully set cancelability type, + * EINVAL 'type' is invalid + * EPERM Async cancellation is not supported. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_t self = pthread_self (); + pte_thread_t * sp = (pte_thread_t *) self.p; + +#ifndef PTE_SUPPORT_ASYNC_CANCEL + if (type == PTHREAD_CANCEL_ASYNCHRONOUS) + { + /* Async cancellation is not supported at this time. See notes in + * pthread_cancel. + */ + return EPERM; + } +#endif /* PTE_SUPPORT_ASYNC_CANCEL */ + + if (sp == NULL + || (type != PTHREAD_CANCEL_DEFERRED + && type != PTHREAD_CANCEL_ASYNCHRONOUS)) + { + return EINVAL; + } + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock (&sp->cancelLock); + + if (oldtype != NULL) + { + *oldtype = sp->cancelType; + } + + sp->cancelType = type; + + /* + * Check if there is a pending asynchronous cancel + */ + + if (sp->cancelState == PTHREAD_CANCEL_ENABLE + && (type == PTHREAD_CANCEL_ASYNCHRONOUS) + && (pte_osThreadCheckCancel(sp->threadId) == PTE_OS_INTERRUPTED) ) + { + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock (&sp->cancelLock); + pte_throw (PTE_EPS_CANCEL); + + /* Never reached */ + } + + (void) pthread_mutex_unlock (&sp->cancelLock); + + return (result); + +} /* pthread_setcanceltype */ diff --git a/src/pthread/pthread_setconcurrency.c b/src/pthread/pthread_setconcurrency.c new file mode 100644 index 000000000..a86e0cf82 --- /dev/null +++ b/src/pthread/pthread_setconcurrency.c @@ -0,0 +1,59 @@ +/* + * pthread_setconcurrency.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_setconcurrency (int level) +{ + if (level < 0) + { + return EINVAL; + } + else + { + pte_concurrency = level; + return 0; + } +} diff --git a/src/pthread/pthread_setschedparam.c b/src/pthread/pthread_setschedparam.c new file mode 100644 index 000000000..64937f07a --- /dev/null +++ b/src/pthread/pthread_setschedparam.c @@ -0,0 +1,115 @@ +/* + * sched_setschedparam.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +pthread_setschedparam (pthread_t thread, int policy, + const struct sched_param *param) +{ + int result; + + /* Validate the thread id. */ + result = pthread_kill (thread, 0); + if (0 != result) + { + return result; + } + + /* Validate the scheduling policy. */ + if (policy < SCHED_MIN || policy > SCHED_MAX) + { + return EINVAL; + } + + /* Ensure the policy is SCHED_OTHER. */ + if (policy != SCHED_OTHER) + { + return ENOTSUP; + } + + return (pte_setthreadpriority (thread, policy, param->sched_priority)); +} + + +int +pte_setthreadpriority (pthread_t thread, int policy, int priority) +{ + int prio; + int result; + pte_thread_t * tp = (pte_thread_t *) thread.p; + + prio = priority; + + /* Validate priority level. */ + if (prio < sched_get_priority_min (policy) || + prio > sched_get_priority_max (policy)) + { + return EINVAL; + } + + result = pthread_mutex_lock (&tp->threadLock); + + if (0 == result) + { + /* If this fails, the current priority is unchanged. */ + + if (0 != pte_osThreadSetPriority(tp->threadId, prio)) + { + result = EINVAL; + } + else + { + /* + * Must record the thread's sched_priority as given, + * not as finally adjusted. + */ + tp->sched_priority = priority; + } + + (void) pthread_mutex_unlock (&tp->threadLock); + } + + return result; +} diff --git a/src/pthread/pthread_setspecific.c b/src/pthread/pthread_setspecific.c new file mode 100644 index 000000000..62928a347 --- /dev/null +++ b/src/pthread/pthread_setspecific.c @@ -0,0 +1,178 @@ +/* + * pthread_setspecific.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "pthread.h" +#include "implement.h" + + + +int +pthread_setspecific (pthread_key_t key, const void *value) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function sets the value of the thread specific + * key in the calling thread. + * + * PARAMETERS + * key + * an instance of pthread_key_t + * value + * the value to set key to + * + * + * DESCRIPTION + * This function sets the value of the thread specific + * key in the calling thread. + * + * RESULTS + * 0 successfully set value + * EAGAIN could not set value + * ENOENT SERIOUS!! + * + * ------------------------------------------------------ + */ +{ + pthread_t self; + int result = 0; + + if (key != pte_selfThreadKey) + { + /* + * Using pthread_self will implicitly create + * an instance of pthread_t for the current + * thread if one wasn't explicitly created + */ + self = pthread_self (); + if (self.p == NULL) + { + return ENOENT; + } + } + else + { + /* + * Resolve catch-22 of registering thread with selfThread + * key + */ + pte_thread_t * sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey); + + if (sp == NULL) + { + if (value == NULL) + { + return ENOENT; + } + + self = *((pthread_t *) value); + } + else + { + self = sp->ptHandle; + } + } + + result = 0; + + if (key != NULL) + { + if (self.p != NULL && key->destructor != NULL && value != NULL) + { + /* + * Only require associations if we have to + * call user destroy routine. + * Don't need to locate an existing association + * when setting data to NULL since the + * data is stored with the operating system; not + * on the association; setting assoc to NULL short + * circuits the search. + */ + ThreadKeyAssoc *assoc; + + if (pthread_mutex_lock(&(key->keyLock)) == 0) + { + pte_thread_t * sp = (pte_thread_t *) self.p; + + (void) pthread_mutex_lock(&(sp->threadLock)); + + assoc = (ThreadKeyAssoc *) sp->keys; + /* + * Locate existing association + */ + while (assoc != NULL) + { + if (assoc->key == key) + { + /* + * Association already exists + */ + break; + } + assoc = assoc->nextKey; + } + + /* + * create an association if not found + */ + if (assoc == NULL) + { + result = pte_tkAssocCreate (sp, key); + } + + (void) pthread_mutex_unlock(&(sp->threadLock)); + } + (void) pthread_mutex_unlock(&(key->keyLock)); + } + + if (result == 0) + { + if (pte_osTlsSetValue (key->key, (void *) value) != PTE_OS_OK) + { + result = EAGAIN; + } + + } + } + + return (result); +} /* pthread_setspecific */ diff --git a/src/pthread/pthread_spin_destroy.c b/src/pthread/pthread_spin_destroy.c new file mode 100644 index 000000000..99c2cd397 --- /dev/null +++ b/src/pthread/pthread_spin_destroy.c @@ -0,0 +1,120 @@ +/* + * pthread_spin_destroy.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_spin_destroy (pthread_spinlock_t * lock) +{ + register pthread_spinlock_t s; + int result = 0; + + if (lock == NULL || *lock == NULL) + { + return EINVAL; + } + + if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER) + { + if (s->interlock == PTE_SPIN_USE_MUTEX) + { + result = pthread_mutex_destroy (&(s->u.mutex)); + } + else if (PTE_SPIN_UNLOCKED != + PTE_ATOMIC_COMPARE_EXCHANGE ( + & (s->interlock), + (int) PTE_OBJECT_INVALID, + PTE_SPIN_UNLOCKED)) + { + result = EINVAL; + } + + if (0 == result) + { + /* + * We are relying on the application to ensure that all other threads + * have finished with the spinlock before destroying it. + */ + *lock = NULL; + (void) free (s); + } + } + else + { + /* + * See notes in pte_spinlock_check_need_init() above also. + */ + + pte_osMutexLock (pte_spinlock_test_init_lock); + + /* + * Check again. + */ + if (*lock == PTHREAD_SPINLOCK_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised spinlock that has not yet been used (initialised). + * If we get to here, another thread + * waiting to initialise this mutex will get an EINVAL. + */ + *lock = NULL; + } + else + { + /* + * The spinlock has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + pte_osMutexUnlock(pte_spinlock_test_init_lock); + + } + + return (result); +} diff --git a/src/pthread/pthread_spin_init.c b/src/pthread/pthread_spin_init.c new file mode 100644 index 000000000..ff4141489 --- /dev/null +++ b/src/pthread/pthread_spin_init.c @@ -0,0 +1,131 @@ +/* + * pthread_spin_init.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "pthread.h" +#include "implement.h" + + +int +pthread_spin_init (pthread_spinlock_t * lock, int pshared) +{ + pthread_spinlock_t s; + int cpus = 0; + int result = 0; + + if (lock == NULL) + { + return EINVAL; + } + + if (0 != pte_getprocessors (&cpus)) + { + cpus = 1; + } + + if (cpus > 1) + { + if (pshared == PTHREAD_PROCESS_SHARED) + { + /* + * Creating spinlock that can be shared between + * processes. + */ +#if _POSIX_THREAD_PROCESS_SHARED >= 0 + + /* + * Not implemented yet. + */ + +#error ERROR [__FILE__, line __LINE__]: Process shared spin locks are not supported yet. + +#else + + return ENOSYS; + +#endif /* _POSIX_THREAD_PROCESS_SHARED */ + + } + } + + s = (pthread_spinlock_t) calloc (1, sizeof (*s)); + + if (s == NULL) + { + return ENOMEM; + } + + if (cpus > 1) + { + s->u.cpus = cpus; + s->interlock = PTE_SPIN_UNLOCKED; + } + else + { + pthread_mutexattr_t ma; + result = pthread_mutexattr_init (&ma); + + if (0 == result) + { + ma->pshared = pshared; + result = pthread_mutex_init (&(s->u.mutex), &ma); + if (0 == result) + { + s->interlock = PTE_SPIN_USE_MUTEX; + } + } + (void) pthread_mutexattr_destroy (&ma); + } + + if (0 == result) + { + *lock = s; + } + else + { + (void) free (s); + *lock = NULL; + } + + return (result); +} diff --git a/src/pthread/pthread_spin_lock.c b/src/pthread/pthread_spin_lock.c new file mode 100644 index 000000000..809c2a918 --- /dev/null +++ b/src/pthread/pthread_spin_lock.c @@ -0,0 +1,86 @@ +/* + * pthread_spin_lock.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_spin_lock (pthread_spinlock_t * lock) +{ + register pthread_spinlock_t s; + + if (NULL == lock || NULL == *lock) + { + return (EINVAL); + } + + if (*lock == PTHREAD_SPINLOCK_INITIALIZER) + { + int result; + + if ((result = pte_spinlock_check_need_init (lock)) != 0) + { + return (result); + } + } + + s = *lock; + + while ( PTE_SPIN_LOCKED == + PTE_ATOMIC_COMPARE_EXCHANGE (&(s->interlock), + PTE_SPIN_LOCKED, + PTE_SPIN_UNLOCKED)) + { + } + + if (s->interlock == PTE_SPIN_LOCKED) + { + return 0; + } + else if (s->interlock == PTE_SPIN_USE_MUTEX) + { + return pthread_mutex_lock (&(s->u.mutex)); + } + + return EINVAL; +} diff --git a/src/pthread/pthread_spin_trylock.c b/src/pthread/pthread_spin_trylock.c new file mode 100644 index 000000000..1b6161556 --- /dev/null +++ b/src/pthread/pthread_spin_trylock.c @@ -0,0 +1,84 @@ +/* + * pthread_spin_trylock.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "pthread.h" +#include "implement.h" + + +int +pthread_spin_trylock (pthread_spinlock_t * lock) +{ + register pthread_spinlock_t s; + + if (NULL == lock || NULL == *lock) + { + return (EINVAL); + } + + if (*lock == PTHREAD_SPINLOCK_INITIALIZER) + { + int result; + + if ((result = pte_spinlock_check_need_init (lock)) != 0) + { + return (result); + } + } + + s = *lock; + + switch ((long) + PTE_ATOMIC_COMPARE_EXCHANGE (&(s->interlock), + PTE_SPIN_LOCKED, + PTE_SPIN_UNLOCKED)) + { + case PTE_SPIN_UNLOCKED: + return 0; + case PTE_SPIN_LOCKED: + return EBUSY; + case PTE_SPIN_USE_MUTEX: + return pthread_mutex_trylock (&(s->u.mutex)); + } + + return EINVAL; +} diff --git a/src/pthread/pthread_spin_unlock.c b/src/pthread/pthread_spin_unlock.c new file mode 100644 index 000000000..e99d60633 --- /dev/null +++ b/src/pthread/pthread_spin_unlock.c @@ -0,0 +1,78 @@ +/* + * pthread_spin_unlock.c + * + * Description: + * This translation unit implements spin lock primitives. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_spin_unlock (pthread_spinlock_t * lock) +{ + register pthread_spinlock_t s; + + if (NULL == lock || NULL == *lock) + { + return (EINVAL); + } + + s = *lock; + + if (s == PTHREAD_SPINLOCK_INITIALIZER) + { + return EPERM; + } + + switch ((long) + PTE_ATOMIC_COMPARE_EXCHANGE (&(s->interlock), + PTE_SPIN_UNLOCKED, + PTE_SPIN_LOCKED)) + { + case PTE_SPIN_LOCKED: + return 0; + case PTE_SPIN_UNLOCKED: + return EPERM; + case PTE_SPIN_USE_MUTEX: + return pthread_mutex_unlock (&(s->u.mutex)); + } + + return EINVAL; +} diff --git a/src/pthread/pthread_terminate.c b/src/pthread/pthread_terminate.c new file mode 100644 index 000000000..a58961296 --- /dev/null +++ b/src/pthread/pthread_terminate.c @@ -0,0 +1,92 @@ +/* + * pthread_terminate.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include + +#include "pthread.h" +#include "implement.h" + + +void pthread_terminate(void) +{ + if (pte_processInitialized) + { + pte_thread_t * tp, * tpNext; + + if (pte_selfThreadKey != NULL) + { + /* + * Release pte_selfThreadKey + */ + pthread_key_delete (pte_selfThreadKey); + + pte_selfThreadKey = NULL; + } + + if (pte_cleanupKey != NULL) + { + /* + * Release pte_cleanupKey + */ + pthread_key_delete (pte_cleanupKey); + + pte_cleanupKey = NULL; + } + + pte_osMutexLock (pte_thread_reuse_lock); + + + tp = pte_threadReuseTop; + while (tp != PTE_THREAD_REUSE_EMPTY) + { + tpNext = tp->prevReuse; + free (tp); + tp = tpNext; + } + + pte_osMutexUnlock(pte_thread_reuse_lock); + + pte_processInitialized = PTE_FALSE; + } + +} diff --git a/src/pthread/pthread_testcancel.c b/src/pthread/pthread_testcancel.c new file mode 100644 index 000000000..d63d8564c --- /dev/null +++ b/src/pthread/pthread_testcancel.c @@ -0,0 +1,107 @@ +/* + * pthread_testcancel.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +void +pthread_testcancel (void) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a deferred cancellation point + * in the calling thread. The call has no effect if the + * current cancelability state is + * PTHREAD_CANCEL_DISABLE + * + * PARAMETERS + * N/A + * + * + * DESCRIPTION + * This function creates a deferred cancellation point + * in the calling thread. The call has no effect if the + * current cancelability state is + * PTHREAD_CANCEL_DISABLE + * + * NOTES: + * 1) Cancellation is asynchronous. Use pthread_join + * to wait for termination of thread if necessary + * + * RESULTS + * N/A + * + * ------------------------------------------------------ + */ +{ + pthread_t self = pthread_self (); + pte_thread_t * sp = (pte_thread_t *) self.p; + + if (sp == NULL) + { + return; + } + + /* + * Pthread_cancel() will have set sp->state to PThreadStateCancelPending + * and set an event, so no need to enter kernel space if + * sp->state != PThreadStateCancelPending - that only slows us down. + */ + if (sp->state != PThreadStateCancelPending) + { + return; + } + + (void) pthread_mutex_lock (&sp->cancelLock); + + if (sp->cancelState != PTHREAD_CANCEL_DISABLE) + { + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + + (void) pthread_mutex_unlock (&sp->cancelLock); + pte_throw (PTE_EPS_CANCEL); + } + + (void) pthread_mutex_unlock (&sp->cancelLock); +} /* pthread_testcancel */ diff --git a/src/pthread/pthread_timechange_handler_np.c b/src/pthread/pthread_timechange_handler_np.c new file mode 100644 index 000000000..c523c1f04 --- /dev/null +++ b/src/pthread/pthread_timechange_handler_np.c @@ -0,0 +1,114 @@ +/* + * pthread_timechange_handler_np.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +/* + * Notes on handling system time adjustments (especially negative ones). + * --------------------------------------------------------------------- + * + * This solution was suggested by Alexander Terekhov, but any errors + * in the implementation are mine - [Ross Johnson] + * + * 1) The problem: threads doing a timedwait on a CV may expect to timeout + * at a specific absolute time according to a system timer. If the + * system clock is adjusted backwards then those threads sleep longer than + * expected. Also, pthreads-embedded converts absolute times to intervals in + * order to make use of the underlying OS, and so waiting threads may + * awake before their proper abstimes. + * + * 2) We aren't able to distinquish between threads on timed or untimed waits, + * so we wake them all at the time of the adjustment so that they can + * re-evaluate their conditions and re-compute their timeouts. + * + * 3) We rely on correctly written applications for this to work. Specifically, + * they must be able to deal properly with spurious wakeups. That is, + * they must re-test their condition upon wakeup and wait again if + * the condition is not satisfied. + */ + +void * +pthread_timechange_handler_np (void *arg) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * Broadcasts all CVs to force re-evaluation and + * new timeouts if required. + * + * PARAMETERS + * NONE + * + * + * DESCRIPTION + * Broadcasts all CVs to force re-evaluation and + * new timeouts if required. + * + * This routine may be passed directly to pthread_create() + * as a new thread in order to run asynchronously. + * + * + * RESULTS + * 0 successfully broadcast all CVs + * EAGAIN Not all CVs were broadcast + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_cond_t cv; + + + pte_osMutexLock (pte_cond_list_lock); + + cv = pte_cond_list_head; + + while (cv != NULL && 0 == result) + { + result = pthread_cond_broadcast (&cv); + cv = cv->next; + } + + pte_osMutexUnlock(pte_cond_list_lock); + + return (void *) (result != 0 ? EAGAIN : 0); +} diff --git a/src/pthread/sched.h b/src/pthread/sched.h new file mode 100644 index 000000000..464d0395f --- /dev/null +++ b/src/pthread/sched.h @@ -0,0 +1,137 @@ +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef _SCHED_H +#define _SCHED_H + +#include + +#undef PTE_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTE_LEVEL +#define PTE_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTE_LEVEL +#define PTE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTE_LEVEL_MAX 3 + +#if !defined(PTE_LEVEL) +#define PTE_LEVEL PTE_LEVEL_MAX +/* Include everything */ +#endif + +/* + * + */ + +/* Thread scheduling policies */ + +enum +{ + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param + { + int sched_priority; + }; + +#ifdef __cplusplus +extern "C" + { +#endif /* __cplusplus */ + + int sched_yield (void); + + int sched_get_priority_min (int policy); + + int sched_get_priority_max (int policy); + + int sched_setscheduler (pid_t pid, int policy); + + /* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#ifdef __cplusplus + } /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTE_LEVEL +#undef PTE_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/src/pthread/sched_get_priority_max.c b/src/pthread/sched_get_priority_max.c new file mode 100644 index 000000000..74357b7ad --- /dev/null +++ b/src/pthread/sched_get_priority_max.c @@ -0,0 +1,51 @@ +/* + * sched_get_priority_max.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +sched_get_priority_max (int policy) +{ + return pte_osThreadGetMaxPriority(); +} diff --git a/src/pthread/sched_get_priority_min.c b/src/pthread/sched_get_priority_min.c new file mode 100644 index 000000000..31a740826 --- /dev/null +++ b/src/pthread/sched_get_priority_min.c @@ -0,0 +1,51 @@ +/* + * sched_get_priority_min.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +sched_get_priority_min (int policy) +{ + return pte_osThreadGetMinPriority(); +} diff --git a/src/pthread/sched_setscheduler.c b/src/pthread/sched_setscheduler.c new file mode 100644 index 000000000..e9bf3352c --- /dev/null +++ b/src/pthread/sched_setscheduler.c @@ -0,0 +1,52 @@ +/* + * sched_setscheduler.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +sched_setscheduler (pid_t pid, int policy) +{ + errno = EPERM; + return -1; +} diff --git a/src/pthread/sched_yield.c b/src/pthread/sched_yield.c new file mode 100644 index 000000000..e0416ab09 --- /dev/null +++ b/src/pthread/sched_yield.c @@ -0,0 +1,82 @@ +/* + * sched_yield.c + * + * Description: + * POSIX thread functions that deal with thread scheduling. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pte_osal.h" + +#include "pthread.h" +#include "implement.h" +#include "sched.h" + +int +sched_yield (void) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function indicates that the calling thread is + * willing to give up some time slices to other threads. + * + * PARAMETERS + * N/A + * + * + * DESCRIPTION + * This function indicates that the calling thread is + * willing to give up some time slices to other threads. + * NOTE: Since this is part of POSIX 1003.1b + * (realtime extensions), it is defined as returning + * -1 if an error occurs and sets errno to the actual + * error. + * + * RESULTS + * 0 successfully created semaphore, + * ENOSYS sched_yield not supported, + * + * ------------------------------------------------------ + */ +{ + pte_osThreadSleep (1); + + return 0; +} diff --git a/src/pthread/sem_close.c b/src/pthread/sem_close.c new file mode 100644 index 000000000..d13f1a51b --- /dev/null +++ b/src/pthread/sem_close.c @@ -0,0 +1,60 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_close.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_close (sem_t * sem) +{ + errno = ENOSYS; + return -1; +} /* sem_close */ diff --git a/src/pthread/sem_destroy.c b/src/pthread/sem_destroy.c new file mode 100644 index 000000000..cf2240f82 --- /dev/null +++ b/src/pthread/sem_destroy.c @@ -0,0 +1,156 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_destroy.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pte_osal.h" + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_destroy (sem_t * sem) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function destroys an unnamed semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function destroys an unnamed semaphore. + * + * RESULTS + * 0 successfully destroyed semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EBUSY threads (or processes) are currently + * blocked on 'sem' + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = NULL; + + if (sem == NULL || *sem == NULL) + { + result = EINVAL; + } + else + { + s = *sem; + + if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + if (s->value < 0) + { + (void) pthread_mutex_unlock (&s->lock); + result = EBUSY; + } + else + { + /* There are no threads currently blocked on this semaphore. */ + pte_osResult osResult = pte_osSemaphoreDelete(s->sem); + + if (osResult != PTE_OS_OK) + { + (void) pthread_mutex_unlock (&s->lock); + result = EINVAL; + } + else + { + /* + * Invalidate the semaphore handle when we have the lock. + * Other sema operations should test this after acquiring the lock + * to check that the sema is still valid, i.e. before performing any + * operations. This may only be necessary before the sema op routine + * returns so that the routine can return EINVAL - e.g. if setting + * s->value to SEM_VALUE_MAX below does force a fall-through. + */ + *sem = NULL; + + /* Prevent anyone else actually waiting on or posting this sema. + */ + s->value = SEM_VALUE_MAX; + + (void) pthread_mutex_unlock (&s->lock); + + do + { + /* Give other threads a chance to run and exit any sema op + * routines. Due to the SEM_VALUE_MAX value, if sem_post or + * sem_wait were blocked by us they should fall through. + */ + pte_osThreadSleep(1); + } + while (pthread_mutex_destroy (&s->lock) == EBUSY); + } + } + } + } + + if (result != 0) + { + errno = result; + return -1; + } + + free (s); + + return 0; + +} /* sem_destroy */ diff --git a/src/pthread/sem_getvalue.c b/src/pthread/sem_getvalue.c new file mode 100644 index 000000000..3e650f470 --- /dev/null +++ b/src/pthread/sem_getvalue.c @@ -0,0 +1,116 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_getvalue.c + * + * Purpose: + * Semaphores aren't actually part of PThreads. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1-2001 + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_getvalue (sem_t * sem, int *sval) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function stores the current count value of the + * semaphore. + * RESULTS + * + * Return value + * + * 0 sval has been set. + * -1 failed, error in errno + * + * in global errno + * + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS this function is not supported, + * + * + * PARAMETERS + * + * sem pointer to an instance of sem_t + * + * sval pointer to int. + * + * DESCRIPTION + * This function stores the current count value of the semaphore + * pointed to by sem in the int pointed to by sval. + */ +{ + if (sem == NULL || *sem == NULL || sval == NULL) + { + errno = EINVAL; + return -1; + } + else + { + long value; + register sem_t s = *sem; + int result = 0; + + if ((result = pthread_mutex_lock(&s->lock)) == 0) + { + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + value = s->value; + (void) pthread_mutex_unlock(&s->lock); + *sval = value; + } + + return result; + } + +} /* sem_getvalue */ diff --git a/src/pthread/sem_init.c b/src/pthread/sem_init.c new file mode 100644 index 000000000..e497098fc --- /dev/null +++ b/src/pthread/sem_init.c @@ -0,0 +1,153 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_init.c + * + * Purpose: + * Semaphores aren't actually part of PThreads. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1-2001 + * + * ------------------------------------------------------------- + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_init (sem_t * sem, int pshared, unsigned int value) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function initializes a semaphore. The + * initial value of the semaphore is 'value' + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * pshared + * if zero, this semaphore may only be shared between + * threads in the same process. + * if nonzero, the semaphore can be shared between + * processes + * + * value + * initial value of the semaphore counter + * + * DESCRIPTION + * This function initializes a semaphore. The + * initial value of the semaphore is set to 'value'. + * + * RESULTS + * 0 successfully created semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, or + * 'value' >= SEM_VALUE_MAX + * ENOMEM out of memory, + * ENOSPC a required resource has been exhausted, + * ENOSYS semaphores are not supported, + * EPERM the process lacks appropriate privilege + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = NULL; + + + if (pshared != 0) + { + /* + * Creating a semaphore that can be shared between + * processes + */ + result = EPERM; + } + else if (value > (unsigned int)SEM_VALUE_MAX) + { + result = EINVAL; + } + else + { + s = (sem_t) calloc (1, sizeof (*s)); + + if (NULL == s) + { + result = ENOMEM; + } + else + { + + s->value = value; + if (pthread_mutex_init(&s->lock, NULL) == 0) + { + + pte_osResult osResult = pte_osSemaphoreCreate(0, &s->sem); + + + + if (osResult != PTE_OS_OK) + { + (void) pthread_mutex_destroy(&s->lock); + result = ENOSPC; + } + + } + else + { + result = ENOSPC; + } + + if (result != 0) + { + free(s); + } + } + } + + if (result != 0) + { + errno = result; + return -1; + } + + *sem = s; + + return 0; + +} /* sem_init */ diff --git a/src/pthread/sem_open.c b/src/pthread/sem_open.c new file mode 100644 index 000000000..14a9bf354 --- /dev/null +++ b/src/pthread/sem_open.c @@ -0,0 +1,60 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_open.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_open (const char *name, int oflag, mode_t mode, unsigned int value) +{ + errno = ENOSYS; + return -1; +} /* sem_open */ diff --git a/src/pthread/sem_post.c b/src/pthread/sem_post.c new file mode 100644 index 000000000..18985e938 --- /dev/null +++ b/src/pthread/sem_post.c @@ -0,0 +1,131 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_post.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post (sem_t * sem) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function posts a wakeup to a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function posts a wakeup to a semaphore. If there + * are waiting threads (or processes), one is awakened; + * otherwise, the semaphore value is incremented by one. + * + * RESULTS + * 0 successfully posted semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * ERANGE semaphore count is too big + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = *sem; + + if (s == NULL) + { + result = EINVAL; + } + else if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + result = EINVAL; + return -1; + } + + if (s->value < SEM_VALUE_MAX) + { + pte_osResult osResult = pte_osSemaphorePost(s->sem, 1); + + if (++s->value <= 0 + && (osResult != PTE_OS_OK)) + { + s->value--; + result = EINVAL; + } + + } + else + { + result = ERANGE; + } + + (void) pthread_mutex_unlock (&s->lock); + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_post */ diff --git a/src/pthread/sem_post_multiple.c b/src/pthread/sem_post_multiple.c new file mode 100644 index 000000000..b7e6d21aa --- /dev/null +++ b/src/pthread/sem_post_multiple.c @@ -0,0 +1,141 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_post_multiple.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post_multiple (sem_t * sem, int count) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function posts multiple wakeups to a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * count + * counter, must be greater than zero. + * + * DESCRIPTION + * This function posts multiple wakeups to a semaphore. If there + * are waiting threads (or processes), n <= count are awakened; + * the semaphore value is incremented by count - n. + * + * RESULTS + * 0 successfully posted semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore + * or count is less than or equal to zero. + * ERANGE semaphore count is too big + * + * ------------------------------------------------------ + */ +{ + int result = 0; + long waiters; + sem_t s = *sem; + + if (s == NULL || count <= 0) + { + result = EINVAL; + } + else if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + result = EINVAL; + return -1; + } + + if (s->value <= (SEM_VALUE_MAX - count)) + { + waiters = -s->value; + s->value += count; + if (waiters > 0) + { + + pte_osSemaphorePost(s->sem, (waiters<=count)?waiters:count); + result = 0; + } + /* + else + { + s->value -= count; + result = EINVAL; + } + */ + } + else + { + result = ERANGE; + } + + (void) pthread_mutex_unlock (&s->lock); + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_post_multiple */ diff --git a/src/pthread/sem_timedwait.c b/src/pthread/sem_timedwait.c new file mode 100644 index 000000000..0601c5742 --- /dev/null +++ b/src/pthread/sem_timedwait.c @@ -0,0 +1,216 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_timedwait.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + +typedef struct + { + sem_t sem; + int * resultPtr; + } sem_timedwait_cleanup_args_t; + +static void +pte_sem_timedwait_cleanup (void * args) +{ + sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args; + sem_t s = a->sem; + + if (pthread_mutex_lock (&s->lock) == 0) + { + /* + * We either timed out or were cancelled. + * If someone has posted between then and now we try to take the semaphore. + * Otherwise the semaphore count may be wrong after we + * return. In the case of a cancellation, it is as if we + * were cancelled just before we return (after taking the semaphore) + * which is ok. + */ + unsigned int timeout = 0; + if (pte_osSemaphorePend(s->sem, &timeout) == PTE_OS_OK) + { + /* We got the semaphore on the second attempt */ + *(a->resultPtr) = 0; + } + else + { + /* Indicate we're no longer waiting */ + s->value++; + + /* + * Don't release the OS sema, it doesn't need adjustment + * because it doesn't record the number of waiters. + */ + + } + (void) pthread_mutex_unlock (&s->lock); + } +} + + +int +sem_timedwait (sem_t * sem, const struct timespec *abstime) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a semaphore possibly until + * 'abstime' time. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * abstime + * pointer to an instance of struct timespec + * + * DESCRIPTION + * This function waits on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value or until interrupted by + * a signal. + * + * If 'abstime' is a NULL pointer then this function will + * block until it can successfully decrease the value or + * until interrupted by a signal. + * + * RESULTS + * 0 successfully decreased semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * ETIMEDOUT abstime elapsed before success. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = *sem; + + + pthread_testcancel(); + + if (sem == NULL) + { + result = EINVAL; + } + else + { + unsigned int milliseconds; + unsigned int *pTimeout; + + if (abstime == NULL) + { + pTimeout = NULL; + } + else + { + /* + * Calculate timeout as milliseconds from current system time. + */ + milliseconds = pte_relmillisecs (abstime); + pTimeout = &milliseconds; + } + + if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + int v; + + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + v = --s->value; + (void) pthread_mutex_unlock (&s->lock); + + if (v < 0) + { + + { + sem_timedwait_cleanup_args_t cleanup_args; + + cleanup_args.sem = s; + cleanup_args.resultPtr = &result; + + /* Must wait */ + pthread_cleanup_push(pte_sem_timedwait_cleanup, (void *) &cleanup_args); + + result = pte_cancellable_wait(s->sem,pTimeout); + + pthread_cleanup_pop(result); + } + } + } + + } + + if (result != 0) + { + + errno = result; + return -1; + + } + + return 0; + +} /* sem_timedwait */ diff --git a/src/pthread/sem_trywait.c b/src/pthread/sem_trywait.c new file mode 100644 index 000000000..bc7eeedc9 --- /dev/null +++ b/src/pthread/sem_trywait.c @@ -0,0 +1,123 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_trywait.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_trywait (sem_t * sem) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function tries to wait on a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function tries to wait on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * this function returns immediately with the error EAGAIN + * + * RESULTS + * 0 successfully decreased semaphore, + * -1 failed, error in errno + * ERRNO + * EAGAIN the semaphore was already locked, + * EINVAL 'sem' is not a valid semaphore, + * ENOTSUP sem_trywait is not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = *sem; + + if (s == NULL) + { + result = EINVAL; + } + else if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + if (s->value > 0) + { + s->value--; + } + else + { + result = EAGAIN; + } + + (void) pthread_mutex_unlock (&s->lock); + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_trywait */ diff --git a/src/pthread/sem_unlink.c b/src/pthread/sem_unlink.c new file mode 100644 index 000000000..130b4788c --- /dev/null +++ b/src/pthread/sem_unlink.c @@ -0,0 +1,60 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_unlink.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_unlink (const char *name) +{ + errno = ENOSYS; + return -1; +} /* sem_unlink */ diff --git a/src/pthread/sem_wait.c b/src/pthread/sem_wait.c new file mode 100644 index 000000000..4fcc8de84 --- /dev/null +++ b/src/pthread/sem_wait.c @@ -0,0 +1,254 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_wait.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +static void +pte_sem_wait_cleanup(void * sem) +{ + sem_t s = (sem_t) sem; + unsigned int timeout; + + if (pthread_mutex_lock (&s->lock) == 0) + { + /* + * If sema is destroyed do nothing, otherwise:- + * If the sema is posted between us being cancelled and us locking + * the sema again above then we need to consume that post but cancel + * anyway. If we don't get the semaphore we indicate that we're no + * longer waiting. + */ + timeout = 0; + if (pte_osSemaphorePend(s->sem, &timeout) != PTE_OS_OK) + { + ++s->value; + + /* + * Don't release the W32 sema, it doesn't need adjustment + * because it doesn't record the number of waiters. + */ + + } + (void) pthread_mutex_unlock (&s->lock); + } +} + + +int +sem_wait (sem_t * sem) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function waits on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value or until interrupted by + * a signal. + * + * RESULTS + * 0 successfully decreased semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = *sem; + + pthread_testcancel(); + + if (s == NULL) + { + result = EINVAL; + } + else + { + if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + int v; + + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + v = --s->value; + (void) pthread_mutex_unlock (&s->lock); + + if (v < 0) + { + /* Must wait */ + pthread_cleanup_push(pte_sem_wait_cleanup, (void *) s); + result = pte_cancellable_wait(s->sem,NULL); + /* Cleanup if we're canceled or on any other error */ + pthread_cleanup_pop(result); + + // Wait was cancelled, indicate that we're no longer waiting on this semaphore. + /* + if (result == PTE_OS_INTERRUPTED) + { + result = EINTR; + ++s->value; + } + */ + } + } + + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_wait */ + + +int +sem_wait_nocancel (sem_t * sem) +/* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a semaphore, and doesn't + * allow cancellation. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function waits on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value or until interrupted by + * a signal. + * + * RESULTS + * 0 successfully decreased semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s = *sem; + + pthread_testcancel(); + + if (s == NULL) + { + result = EINVAL; + } + else + { + if ((result = pthread_mutex_lock (&s->lock)) == 0) + { + int v; + + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + v = --s->value; + (void) pthread_mutex_unlock (&s->lock); + + if (v < 0) + { + pte_osSemaphorePend(s->sem, NULL); + } + } + + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_wait_nocancel */ diff --git a/src/pthread/semaphore.h b/src/pthread/semaphore.h new file mode 100644 index 000000000..08388fbb1 --- /dev/null +++ b/src/pthread/semaphore.h @@ -0,0 +1,114 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#if defined(_POSIX_SOURCE) +#define PTE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(INCLUDE_NP) +#undef PTE_LEVEL +#define PTE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +/* + * + */ + +#define _POSIX_SEMAPHORES + +#ifdef __cplusplus +extern "C" + { +#endif /* __cplusplus */ + + + typedef struct sem_t_ * sem_t; + + int sem_init (sem_t * sem, + int pshared, + unsigned int value); + + int sem_destroy (sem_t * sem); + + int sem_trywait (sem_t * sem); + + int sem_wait (sem_t * sem); + + int sem_timedwait (sem_t * sem, + const struct timespec * abstime); + + int sem_post (sem_t * sem); + + int sem_post_multiple (sem_t * sem, + int count); + + int sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + + int sem_close (sem_t * sem); + + int sem_unlink (const char * name); + + int sem_getvalue (sem_t * sem, + int * sval); + +#ifdef __cplusplus + } /* End of extern "C" */ +#endif /* __cplusplus */ + +#endif /* !SEMAPHORE_H */ diff --git a/src/pthread/tests/ChangeLog b/src/pthread/tests/ChangeLog new file mode 100644 index 000000000..6b2c74250 --- /dev/null +++ b/src/pthread/tests/ChangeLog @@ -0,0 +1,894 @@ +2005-06-12 Ross Johnson + + * stress1.c (millisecondsFromNow): Remove limit 0 <= millisecs < 1000; + now works for -INT_MAX <= millisecs <= INT_MAX; not needed for + stress1.c but should be general anyway. + +2005-05-18 Ross Johnson + + * reuse2.c (main): Must use a read with memory barrier semantics + when polling 'done' to force the cache into coherence on MP systems. + +2005-05-15 Ross Johnson + + * detach1.c: New test. + * join1.c: Reduce sleep times. + * join0.c: Remove MSVCRT conditional compile - join should always + return the thread exit code. + * join1.c: Likewise. + * join2.c: Likewise. + * join3.c: Likewise. + +2005-04-18 Ross Johnson + + * condvar3.c: Remove locks from around signalling calls - should not + be required for normal operation and only serve to mask deficiencies; + ensure that CV destruction is not premature after removing guards. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * condvar3_3.c: Likewise. + * condvar4.c: Likewise. + * condvar5.c: Likewise. + * condvar6.c: Likewise. + * condvar7.c: Likewise. + * condvar8.c: Likewise. + * condvar9.c: Likewise. + +2005-04-11 Ross Johnson + + * once4.c: New test; tries to test priority adjustments + in pthread_once(); set priority class to realtime so that + any failures can be seen. + +2005-04-06 Ross Johnson + + * cleanup0.c: Fix unguarded global variable accesses. + * cleanup1.c: Likewise. + * cleanup2.c: Likewise. + * cleanup3.c: Likewise. + * once2.c: Likewise. + * once3.c: Likewise. + +2005-04-01 Ross Johnson + + * GNUmakefile: Add target to test linking static link library. + * Makefile: Likewise. + * self1.c: Run process attach/detach routines when static linked. + +2005-03-16 Ross Johnson + + * mutex5.c: Prevent optimiser from removing asserts. + +2005-03-12 Ross Johnson + + * once3.c: New test. + +2005-03-08 Ross Johnson + + * once2.c: New test. + +2004-11-19 Ross Johnson + + * Bmakefile: New makefile for Borland. + * Makefile (DLL_VER): Added. + * GNUmakefile (DLL_VER): Added. + * Wmakefile (DLL_VER): Added. + +2004-10-29 Ross Johnson + + * semaphore4.c: New test. + * semaphore4t.c: New test. + * Debug.dsp (et al): Created MSVC Workspace project to aid debugging. + * All: Many tests have been modified to work with the new pthread + ID type; some other corrections were made after some library + functions were semantically strengthened. For example, + pthread_cond_destroy() no longer destroys a busy CV, which + required minor redesigns of some tests, including some where + the mutex associated with the CV was not locked during + signaling and broadcasting. + +2004-10-23 Ross Johnson + + * condvar3.c: Fixed mutex operations that were incorrectly + placed in relation to their condition variable operations. + The error became evident after sem_destroy() was rewritten + and conditions for destroing the semaphore were tightened. + As a result, pthread_cond_destroy() was not able to + destroy the cv queueing sempahore. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * condvar4.c: Likewise. + * condvar5.c: Likewise. + * condvar6.c: Likewise. + * condvar7.c: Likewise. + * condvar8.c: Likewise. + * condvar9.c: Likewise. + +2004-10-19 Ross Johnson + + * semaphore3.c: New test. + +2004-10-14 Ross Johnson + + * rwlock7.c (main): Tidy up statistics reporting; randomise + update accesses. + * rwlock8.c: New test. + +2004-09-08 Alexandre Girao + + * cancel7.c (main): Win98 wants a valid (non-NULL) location + for the last arg of _beginthreadex(). + * cancel8.c (main): Likewise. + * exit4.c (main): Likewise. + * exit5.c (main): Likewise. + +2004-08-26 Ross Johnson + + * create3.c: New test. + +2004-06-21 Ross Johnson + + * mutex2r.c: New test. + * mutex2e.c: New test. + * mutex3r.c: New test. + * mutex3e.c: New test. + * mutex6s.c: New test. + * mutex6rs.c: New test. + * mutex6es.c: New test. + +2004-05-21 Ross Johnson + + * join3.c: New test. + +2004-05-16 Ross Johnson + + * condvar2.c (WIN32_WINNT): Define to avoid redefinition warning + from inclusion of implement.h. + * convar2_1.c: Likewise. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * context1.c: Likewise. + * sizes.c: Likewise. + * Makefile: Don't define _WIN32_WINNT on compiler command line. + * GNUmakefile: Likewise. + * priority1.c (main): Add column to output for actual win32 + priority. + +2004-05-16 Ross Johnson + + * cancel9.c: New test. + * cancel3.c: Remove inappropriate conditional compilation; + GNU C version of test suite no longer quietly skips this test. + * cancel5.c: Likewise. + * GNUmakefile: Can now build individual test app using default + C version of library using 'make clean testname.c'. + * Makefile: Likewise for VC using 'nmake clean test testname.c'. + +2003-10-14 Ross Johnson + + * Wmakefile: New makefile for Watcom testing. + +2003-09-18 Ross Johnson + + * benchtest.h: Move old mutex code into benchlib.c. + * benchlib.c: New statically linked module to ensure that + bench apps don't inline the code and therefore have an unfair + advantage over the pthreads lib routines. Made little or no + difference. + * benchtest1.c: Minor change to avoid compiler warnings. + * benchtest5.c: Likewise. + * benchtest2.c: Fix misinformation in output report. + * README.BENCH: Add comments on results. + +2003-09-14 Ross Johnson + + * priority1.c: Reworked to comply with modified priority + management and provide additional output. + * priority2.c: Likewise. + * inherit1.c: Likewise. + +2003-09-03 Ross Johnson + + * exit4.c: New test. + * exit5.c: New test. + * cancel7.c: New test. + * cancel8.c: New test. + +2003-08-13 Ross Johnson + + * reuse1.c: New test. + * reuse1.c: New test. + * valid1.c: New test. + * valid2.c: New test. + * kill1.c: New test. + * create2.c: Now included in test regime. + +2003-07-19 Ross Johnson + + * eyal1.c (waste_time): Make threads do more work to ensure that + all threads get to do some work. + * semaphore1.c: Make it clear that certain errors are expected. + * exception2.c (non_MSVC code sections): Change to include + C++ standard include file, i.e. change to . + * exception3.c (non_MSVC code sections): Likewise; qualify std:: + namespace entities where necessary. + * GNUmakefile: modified to work in the MsysDTK (newer MinGW) + environment; define CC as gcc or g++ as appropriate because + using gcc -x c++ doesn't link with required c++ libs by default, + but g++ does. + +2002-12-11 Ross Johnson + + * mutex7e.c: Assert EBUSY return instead of EDEADLK. + +2002-06-03 Ross Johnson + + * semaphore2.c: New test. + +2002-03-02 Ross Johnson + + * Makefile (CFLAGS): Changed /MT to /MD to link with + the correct library MSVCRT.LIB. Otherwise errno doesn't + work. + +2002-02-28 Ross Johnson + + * exception3.c: Correct recent change. + + * semaphore1.c: New test. + + * Makefile: Add rule to generate pre-processor output. + +2002-02-28 Ross Johnson + + * exception3.c (terminateFunction): For MSVC++, call + exit() rather than pthread_exit(). Add comments to explain + why. + * Notes from the MSVC++ manual: + * 1) A term_func() should call exit(), otherwise + * abort() will be called on return to the caller. + * abort() raises SIGABRT. The default signal handler + * for all signals terminates the calling program with + * exit code 3. + * 2) A term_func() must not throw an exception. Therefore + * term_func() should not call pthread_exit() if an + * an exception-using version of pthreads-win32 library + * is being used (i.e. either pthreadVCE or pthreadVSE). + + +2002-02-23 Ross Johnson + + * rwlock2_t.c: New test. + * rwlock3_t.c: New test. + * rwlock4_t.c: New test. + * rwlock5_t.c: New test. + * rwlock6_t.c: New test. + * rwlock6_t2.c: New test. + * rwlock6.c (main): Swap thread and result variables + to correspond to actual thread functions. + * rwlock1.c: Change test description comment to correspond + to the actual test. + + * condvar1_2.c: Loop over the test many times in the hope + of detecting any intermittent deadlocks. This is to + test a fixed problem in pthread_cond_destroy.c. + + * spin4.c: Remove unused variable. + +2002-02-17 Ross Johnson + + * condvar1_1.c: New test. + * condvar1_2.c: New test. + +2002-02-07 Ross Johnson + + * delay1.c: New test. + * delay2.c: New test. + * exit4.c: New test. + +2002-02-02 Ross Johnson + + * mutex8: New test. + * mutex8n: New test. + * mutex8e: New test. + * mutex8r: New test. + * cancel6a: New test. + * cancel6d: New test. + * cleanup0.c: Add pragmas for inline optimisation control. + * cleanup1.c: Add pragmas for inline optimisation control. + * cleanup2.c: Add pragmas for inline optimisation control. + * cleanup3.c: Add pragmas for inline optimisation control. + * condvar7.c: Add pragmas for inline optimisation control. + * condvar8.c: Add pragmas for inline optimisation control. + * condvar9.c: Add pragmas for inline optimisation control. + +2002-01-30 Ross Johnson + + * cleanup1.c (): Must be declared __cdecl when compiled + as C++ AND testing the standard C library version. + +2002-01-16 Ross Johnson + + * spin4.c (main): Fix renamed function call. + +2002-01-14 Ross Johnson + + * exception3.c (main): Shorten wait time. + +2002-01-09 Ross Johnson + + * mutex7.c: New test. + * mutex7n.c: New test. + * mutex7e.c: New test. + * mutex7r.c: New test. + * mutex6.c: Modified to avoid leaving the locked mutex + around on exit. + +2001-10-25 Ross Johnson + + * condvar2.c: Remove reference to cv->nWaitersUnblocked. + * condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * count1.c: lower NUMTHREADS from 60 to 30. + * inherit1.c: Determine valid priority values and then + assert values returned by POSIX routines are the same. + * priority1.c: Likewise. + * priority2.c: Likewise. + +2001-07-12 Ross Johnson + + * barrier5.c: Assert that precisely one thread receives + PTHREAD_BARRIER_SERIAL_THREAD at each barrier. + +2001-07-09 Ross Johnson + + * barrier3.c: Fixed. + * barrier4.c: Fixed. + * barrier5.c: New; proves that all threads in the group + reaching the barrier wait and then resume together. Repeats the test + using groups of 1 to 16 threads. Each group of threads must negotiate + a large number of barriers (10000). + * spin4.c: Fixed. + * test.h (error_string): Modified the success (0) value. + +2001-07-07 Ross Johnson + + * spin3.c: Changed test and fixed. + * spin4.c: Fixed. + * barrier3.c: Fixed. + * barrier4.c: Fixed. + +2001-07-05 Ross Johnson + + * spin1.c: New; testing spinlocks. + * spin2.c: New; testing spinlocks. + * spin3.c: New; testing spinlocks. + * spin4.c: New; testing spinlocks. + * barrier1.c: New; testing barriers. + * barrier2.c: New; testing barriers. + * barrier3.c: New; testing barriers. + * barrier4.c: New; testing barriers. + * GNUmakefile: Add new tests. + * Makefile: Add new tests. + +2001-07-01 Ross Johnson + + * benchtest3.c: New; timing mutexes. + * benchtest4.c: New; time mutexes. + * condvar3_1.c: Fixed bug - Alexander Terekhov + * condvar3_3.c: New test. + +2001-06-25 Ross Johnson + + * priority1.c: New test. + * priority2.c: New test. + * inherit1.c: New test. + * benchtest1.c: New; timing mutexes. + * benchtest2.c: New; timing mutexes. + * mutex4.c: Modified to test all mutex types. + +2001-06-8 Ross Johnson + + * mutex5.c: Insert inert change to quell compiler warnings. + * condvar3_2.c: Remove unused variable. + +2001-06-3 Ross Johnson + + * condvar2_1.c: New test. + * condvar3_1.c: New test. + * condvar3_2.c: New test. + +2001-05-30 Ross Johnson + + * mutex1n.c: New test. + * mutex1e.c: New test. + * mutex1r.c: New test. + * mutex4.c: Now locks and unlocks a mutex. + * mutex5.c: New test. + * mutex6.c: New test. + * mutex6n.c: New test. + * mutex6e.c: New test. + * mutex6r.c: New test. + * Makefile: Added new tests; reorganised. + * GNUmakefile: Likewise. + * rwlock6.c: Fix to properly prove read-while-write locking + and single writer locking. + +2001-05-29 Ross Johnson + + * Makefile: Reorganisation. + * GNUmakefile: Likewise. + - Thomas Pfaff + + * exception1.c: Add stdio.h include to define fprintf and stderr + in non-exception C version of main(). + * exception2.c: Likewise. + * exception3.c: Likewise. + + * Makefile (rwlock7): Add new test. + * GNUmakefile (rwlock7): Add new test. + * rwlock7.c: New test. + * rwlock6.c: Changed to test that writer has priority. + + * eyal1.c (main): Unlock each mutex_start lock before destroying + it. + +2000-12-29 Ross Johnson + + * GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is + removed for "clean" target. + * Makefile: Add mutex4 test. + + * exception3.c: Remove SEH code; automatically pass the test + under SEH (which is an N/A environment). + + * mutex4.c: New test. + + * eyal1.c (do_work_unit): Add a dummy "if" to force the + optimiser to retain code; reduce thread work loads. + + * condvar8.c (main): Add an additional "assert" for debugging; + increase pthread_cond_signal timeout. + +2000-12-28 Ross Johnson + + * eyal1.c: Increase thread work loads. + * exception2.c: New test. + * exception3.c: New test. + * Makefile: Add new tests exception2.c and exception3.c. + * GNUmakefile: Likewise. + +2000-12-11 Ross Johnson + + * cleanup3.c: Remove unused variable. + * cleanup2.c: Likewise. + * exception1.c: Throw an exception rather than use + a deliberate zero divide so that catch(...) will + handle it under Mingw32. Mingw32 now builds the + library correctly to pass all tests - see Thomas + Pfaff's detailed instructions re needed changes + to Mingw32 in the Pthreads-Win32 FAQ. + +2000-09-08 Ross Johnson + + * cancel5.c: New; tests calling pthread_cancel() + from the main thread without first creating a + POSIX thread struct for the non-POSIX main thread + - this forces pthread_cancel() to create one via + pthread_self(). + * Makefile (cancel5): Add new test. + * GNUmakefile (cancel5): Likewise. + +2000-08-17 Ross Johnson + + * create2.c: New; Test that pthread_t contains + the W32 HANDLE before it calls the thread routine + proper. + +2000-08-13 Ross Johnson + + * condvar3.c: Minor change to eliminate compiler + warning. + + * condvar4.c: ditto. + + * condvar5.c: ditto. + + * condvar6.c: ditto. + + * condvar7.c: ditto. + + * condvar8.c: ditto. + + * condvar9.c: ditto. + + * exit1.c: Function needed return statement. + + * cleanup1.c: Remove unnecessary printf arg. + + * cleanup2.c: Fix cast. + + * rwlock6.c: Fix casts. + + * exception1.c (PtW32CatchAll): Had the wrong name; + fix casts. + + * cancel3.c: Remove unused waitLock variable. + + * GNUmakefile: Change library/dll naming; add new tests; + general minor changes. + + * Makefile: Change library/dll naming; add targets for + testing each of the two VC++ EH scheme versions; + default target now issues help message; compile warnings + now interpreted as errors to stop the make; add new + tests; restructure to remove prerequisites needed + otherwise. + + * README: Updated. + + +2000-08-10 Ross Johnson + + * eyal1.c (main): Change implicit cast to explicit + cast when passing "print_server" function pointer; + G++ no longer allows implicit func parameter casts. + + * cleanup1.c: Remove unused "waitLock". + (main): Fix implicit parameter cast. + + * cancel2.c (main): Fix implicit parameter cast. + + * cancel4.c (main): Fix implicit parameter cast. + + * cancel3.c (main): Fix implicit parameter cast. + + * GNUmakefile: Renamed from Makefile; Add missing + cancel1 and cancel2 test targets. + + * Makefile: Converted for use with MS nmake. + +2000-08-06 Ross Johnson + + * ccl.bat: Add /nologo to remove extraneous output. + + * exception1.c (exceptionedThread): Init 'dummy'; + put expression into if condition to prevent optimising away; + remove unused variable. + + * cancel4.c (mythread): Cast return value to avoid warnings. + + * cancel2.c (mythread): Missing #endif. + + * condvar9.c (mythread): Cast return value to avoid warnings. + + * condvar8.c (mythread): Cast return value to avoid warnings. + + * condvar7.c (mythread): Cast return value to avoid warnings. + + * cleanup3.c (mythread): Cast return value to avoid warnings. + + * cleanup2.c (mythread): Cast return value to avoid warnings. + + * cleanup1.c (mythread): Cast return value to avoid warnings. + + * condvar5.c (mythread): Cast return value to avoid warnings. + + * condvar3.c (mythread): Cast return value to avoid warnings. + + * condvar6.c (mythread): Cast return value to avoid warnings. + + * condvar4.c (mythread): Cast return value to avoid warnings. + +2000-08-05 Ross Johnson + + * cancel2.c: Use PtW32CatchAll macro if defined. + + * exception1.c: Use PtW32CatchAll macro if defined. + +2000-08-02 Ross Johnson + + * tsd1.c: Fix typecasts of &result [g++ is now very fussy]. + + * test.h (assert): Return 0's explicitly to allay + g++ errors. + + * join2.c: Add explicit typecasts. + + * join1.c: Add explicit typecasts. + + * join0.c: Add explicit typecasts. + + * eyal1.c: Add explicit typecasts. + + * count1.c (main): Add type cast to remove g++ parse warning + [gcc-2.95.2 seems to have tightened up on this]. + + * Makefile (GLANG): Use c++ explicitly. + Remove MSVC sections (was commented out). + Add target to generate cpp output. + +2000-07-25 Ross Johnson + + * runtest.bat: modified to work under W98. + + * runall.bat: Add new tests; modified to work under W98. + It was ok under NT. + + * Makefile: Add new tests. + + * exception1.c: New; Test passing exceptions back to the + application and retaining library internal exceptions. + + * join0.c: New; Test a single join. + +2000-01-06 Ross Johnson + + * cleanup1.c: New; Test cleanup handler executes (when thread is + canceled). + + * cleanup2.c: New; Test cleanup handler executes (when thread is + not canceled). + + * cleanup3.c: New; Test cleanup handler does not execute + (when thread is not canceled). + +2000-01-04 Ross Johnson + + * cancel4.c: New; Test cancelation does not occur in deferred + cancelation threads with no cancelation points. + + * cancel3.c: New; Test asynchronous cancelation. + + * context1.c: New; Test context switching method for async + cancelation. + +1999-11-23 Ross Johnson + + * test.h: Add header includes; include local header versions rather + than system versions; rearrange the assert macro defines. + +1999-11-07 Ross Johnson + + * loadfree.c: New. Test loading and freeing the library (DLL). + +1999-10-30 Ross Johnson + + * cancel1.c: New. Test pthread_setcancelstate and + pthread_setcanceltype functions. + * eyal1.c (waste_time): Change calculation to avoid FP exception + on Aplhas + - Rich Peters + +Oct 14 1999 Ross Johnson + + * condvar7.c: New. Test broadcast after waiting thread is canceled. + * condvar8.c: New. Test multiple broadcasts. + * condvar9.c: New. Test multiple broadcasts with thread + cancelation. + +Sep 16 1999 Ross Johnson + + * rwlock6.c: New test. + +Sep 15 1999 Ross Johnson + + * rwlock1.c: New test. + * rwlock2.c: New test. + * rwlock3.c: New test. + * rwlock4.c: New test. + * rwlock5.c: New test. + +Aug 22 1999 Ross Johnson + + * runall.bat (join2): Add test. + +Aug 19 1999 Ross Johnson + + * join2.c: New test. + +Wed Aug 12 1999 Ross Johnson + + * Makefile (LIBS): Add -L. + +Mon May 31 10:25:01 1999 Ross Johnson + + * Makefile (GLANG): Add GCC language option. + +Sat May 29 23:29:04 1999 Ross Johnson + + * runall.bat (condvar5): Add new test. + + * runall.bat (condvar6): Add new test. + + * Makefile (condvar5) : Add new test. + + * Makefile (condvar6) : Add new test. + + * condvar5.c: New test for pthread_cond_broadcast(). + + * condvar6.c: New test for pthread_cond_broadcast(). + +Sun Apr 4 12:04:28 1999 Ross Johnson + + * tsd1.c (mythread): Change Sleep(0) to sched_yield(). + (sched.h): Include. + + * condvar3.c (mythread): Remove redundant Sleep(). + + * runtest.bat: Re-organised to make more informative. + +Fri Mar 19 1999 Ross Johnson + + * *.bat: redirect unwanted output to nul: + + * runall.bat: new. + + * cancel1.c: new. Not part of suite yet. + +Mon Mar 15 00:17:55 1999 Ross Johnson + + * mutex1.c: only test mutex init and destroy; add assertions. + + * count1.c: raise number of spawned threads to 60 (appears to + be the limit under Win98). + +Sun Mar 14 21:31:02 1999 Ross Johnson + + * test.h (assert): add assertion trace option. + Use: + "#define ASSERT_TRACE 1" to turn it on, + "#define ASSERT_TRACE 0" to turn it off (default). + + * condvar3.c (main): add more assertions. + + * condvar4.c (main): add more assertions. + + * condvar1.c (main): add more assertions. + +Fri Mar 12 08:34:15 1999 Ross Johnson + + * condvar4.c (cvthing): switch the order of the INITIALIZERs. + + * eyal1.c (main): Fix trylock loop; was not waiting for thread to lock + the "started" mutex. + +Wed Mar 10 10:41:52 1999 Ross Johnson + + * tryentercs.c: Apply typo patch from bje. + + * tryentercs2.c: Ditto. + +Sun Mar 7 10:41:52 1999 Ross Johnson + + * Makefile (condvar3, condvar4): Add tests. + + * condvar4.c (General): Reduce to simple test case; prerequisite + is condvar3.c; add description. + + * condvar3.c (General): Reduce to simple test case; prerequisite + is condvar2.c; add description. + + * condvar2.c (General): Reduce to simple test case; prerequisite + is condvar1.c; add description. + + * condvar1.c (General): Reduce to simple test case; add + description. + + * Template.c (Comments): Add generic test detail. + +1999-02-23 Ross Johnson + + * Template.c: Revamp. + + * condvar1.c: Add. + + * condvar2.c: Add. + + * Makefile: Add condvar1 condvar2 tests. + + * exit1.c, exit2.c, exit3.c: Cosmetic changes. + +1999-02-23 Ross Johnson + + * Makefile: Some refinement. + + * *.c: More exhaustive checking through assertions; clean up; + add some more tests. + + * Makefile: Now actually runs the tests. + + * tests.h: Define our own assert macro. The Mingw32 + version pops up a dialog but we want to run non-interactively. + + * equal1.c: use assert a little more directly so that it + prints the actual call statement. + + * exit1.c: Modify to return 0 on success, 1 on failure. + +1999-02-22 Ross Johnson + + * self2.c: Bring up to date. + + * self3.c: Ditto. + +1999-02-21 Ben Elliston + + * README: Update. + + * Makefile: New file. Run all tests automatically. Primitive tests + are run first; more complex tests are run last. + + * count1.c: New test. Validate the thread count. + + * exit2.c: Perform a simpler test. + + * exit3.c: New test. Replaces exit2.c, since exit2.c needs to + perform simpler checking first. + + * create1.c: Update to use the new testsuite exiting convention. + + * equal1.c: Likewise. + + * mutex1.c: Likewise. + + * mutex2.c: Likewise. + + * once1.c: Likewise. + + * self2.c: Likewise. + + * self3.c: Likewise. + + * tsd1.c: Likewise. + +1999-02-20 Ross Johnson + + * mutex2.c: Test static mutex initialisation. + + * test.h: New. Declares a table mapping error numbers to + error names. + +1999-01-17 Ross Johnson + + * runtest: New script to build and run a test in the tests directory. + +Wed Dec 30 11:22:44 1998 Ross Johnson + + * tsd1.c: Re-written. See comments at start of file. + * Template.c: New. Contains skeleton code and comment template + intended to fully document the test. + +Fri Oct 16 17:59:49 1998 Ross Johnson + + * tsd1.c (destroy_key): Add function. Change diagnostics. + +Thu Oct 15 17:42:37 1998 Ross Johnson + + * tsd1.c (mythread): Fix some casts and add some message + output. Fix inverted conditional. + +Mon Oct 12 02:12:29 1998 Ross Johnson + + * tsd1.c: New. Test TSD using 1 key and 2 threads. + +1998-09-13 Ben Elliston + + * eyal1.c: New file; contributed by Eyal Lebedinsky + . + +1998-09-12 Ben Elliston + + * exit2.c (func): Return a value. + (main): Call the right thread entry function. + +1998-07-22 Ben Elliston + + * exit2.c (main): Fix size of pthread_t array. + +1998-07-10 Ben Elliston + + * exit2.c: New file; test pthread_exit() harder. + + * exit1.c: New file; test pthread_exit(). diff --git a/src/pthread/tests/barrier1.c b/src/pthread/tests/barrier1.c new file mode 100644 index 000000000..0538d06df --- /dev/null +++ b/src/pthread/tests/barrier1.c @@ -0,0 +1,63 @@ +/* + * barrier1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a barrier object and then destroy it. + * + */ + +#include "test.h" + +static pthread_barrier_t barrier = NULL; + +int pthread_test_barrier1() +{ + assert(barrier == NULL); + + assert(pthread_barrier_init(&barrier, NULL, 1) == 0); + + assert(barrier != NULL); + + assert(pthread_barrier_destroy(&barrier) == 0); + + assert(barrier == NULL); + + return 0; +} diff --git a/src/pthread/tests/barrier2.c b/src/pthread/tests/barrier2.c new file mode 100644 index 000000000..86e7346b7 --- /dev/null +++ b/src/pthread/tests/barrier2.c @@ -0,0 +1,60 @@ +/* + * barrier2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +static pthread_barrier_t barrier = NULL; + +int pthread_test_barrier2() +{ + assert(pthread_barrier_init(&barrier, NULL, 1) == 0); + + assert(pthread_barrier_wait(&barrier) == PTHREAD_BARRIER_SERIAL_THREAD); + + assert(pthread_barrier_destroy(&barrier) == 0); + + return 0; +} diff --git a/src/pthread/tests/barrier3.c b/src/pthread/tests/barrier3.c new file mode 100644 index 000000000..1f16a7964 --- /dev/null +++ b/src/pthread/tests/barrier3.c @@ -0,0 +1,77 @@ +/* + * barrier3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object with barrier attribute, wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +static pthread_barrier_t barrier = NULL; +static int result = 1; + +static void * func(void * arg) +{ + return (void *) pthread_barrier_wait(&barrier); +} + + +int pthread_test_barrier3() +{ + pthread_t t; + pthread_barrierattr_t ba; + + assert(pthread_barrierattr_init(&ba) == 0); + assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0); + assert(pthread_barrier_init(&barrier, &ba, 1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + + assert(result == PTHREAD_BARRIER_SERIAL_THREAD); + + assert(pthread_barrier_destroy(&barrier) == 0); + assert(pthread_barrierattr_destroy(&ba) == 0); + + return 0; +} diff --git a/src/pthread/tests/barrier4.c b/src/pthread/tests/barrier4.c new file mode 100644 index 000000000..43fc98336 --- /dev/null +++ b/src/pthread/tests/barrier4.c @@ -0,0 +1,119 @@ +/* + * barrier4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, multiple wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +enum +{ + NUMTHREADS = 16 +}; + +static pthread_barrier_t barrier = NULL; +static pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; +static int serialThreadCount = 0; +static int otherThreadCount = 0; + +static void * +func(void * arg) +{ + int result = pthread_barrier_wait(&barrier); + + assert(pthread_mutex_lock(&mx) == 0); + + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + serialThreadCount++; + } + else if (0 == result) + { + otherThreadCount++; + } + else + { + return NULL; + } + assert(pthread_mutex_unlock(&mx) == 0); + + return NULL; +} + +int pthread_test_barrier4() +{ + int i, j; + pthread_t t[NUMTHREADS + 1]; + +// pthread_barrier_t barrier = NULL; +// serialThreadCount = 0; +// otherThreadCount = 0; + + mx = PTHREAD_MUTEX_INITIALIZER; + + for (j = 1; j <= NUMTHREADS; j++) + { + + serialThreadCount = 0; + + assert(pthread_barrier_init(&barrier, NULL, j) == 0); + + for (i = 1; i <= j; i++) + { + assert(pthread_create(&t[i], NULL, func, NULL) == 0); + } + + for (i = 1; i <= j; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + assert(serialThreadCount == 1); + + assert(pthread_barrier_destroy(&barrier) == 0); + } + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} diff --git a/src/pthread/tests/barrier5.c b/src/pthread/tests/barrier5.c new file mode 100644 index 000000000..17e0fd51e --- /dev/null +++ b/src/pthread/tests/barrier5.c @@ -0,0 +1,133 @@ +/* + * barrier5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, set up a sequence of + * barrier points to prove lockstepness, and then destroy it. + * + */ + +#include "test.h" + +enum +{ + NUMTHREADS = 16, + BARRIERS = 1000 +}; + +static pthread_barrier_t barrier = NULL; +static pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; + +static int barrierReleases[BARRIERS + 1]; + +static void * +func(void * barrierHeight) +{ + int i; + int result; + int serialThreads = 0; + + for (i = 1; i < BARRIERS; i++) + { + result = pthread_barrier_wait(&barrier); + + assert(pthread_mutex_lock(&mx) == 0); + barrierReleases[i]++; + assert(pthread_mutex_unlock(&mx) == 0); + /* + * Confirm the correct number of releases from the previous + * barrier. We can't do the current barrier yet because there may + * still be threads waking up. + */ + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + serialThreads++; + assert(barrierReleases[i - 1] == (int) barrierHeight); + barrierReleases[i + 1] = 0; + } + else if (result != 0) + { + return NULL; + } + } + + return (void *) serialThreads; +} + +int pthread_test_barrier5() +{ + int i, j; + int result; + int serialThreadsTotal; + pthread_t t[NUMTHREADS + 1]; + + mx = PTHREAD_MUTEX_INITIALIZER; + + for (j = 1; j <= NUMTHREADS; j++) + { + + barrierReleases[0] = j; + barrierReleases[1] = 0; + + assert(pthread_barrier_init(&barrier, NULL, j) == 0); + + for (i = 1; i <= j; i++) + { + assert(pthread_create(&t[i], NULL, func, (void *) j) == 0); + } + + serialThreadsTotal = 0; + for (i = 1; i <= j; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + serialThreadsTotal += result; + } + + assert(serialThreadsTotal == BARRIERS - 1); + assert(barrierReleases[BARRIERS - 1] == j); + assert(barrierReleases[BARRIERS] == 0); + + assert(pthread_barrier_destroy(&barrier) == 0); + } + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} diff --git a/src/pthread/tests/benchlib.c b/src/pthread/tests/benchlib.c new file mode 100644 index 000000000..469a8b55d --- /dev/null +++ b/src/pthread/tests/benchlib.c @@ -0,0 +1,75 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +#include +#include +#include "pthread.h" +#include "sched.h" +#include "semaphore.h" +#include "benchtest.h" +#include "implement.h" + +void +dummy_call(int * a) +{ +} + +void +interlocked_inc_with_conditionals(int * a) +{ + if (a != NULL) + if (PTE_ATOMIC_INCREMENT(a) == -1) + { + *a = 0; + } +} + +void +interlocked_dec_with_conditionals(int * a) +{ + if (a != NULL) + if (PTE_ATOMIC_DECREMENT(a) == -1) + { + *a = 0; + } +} + + +/****************************************************************************************/ diff --git a/src/pthread/tests/benchtest.h b/src/pthread/tests/benchtest.h new file mode 100644 index 000000000..3e258c906 --- /dev/null +++ b/src/pthread/tests/benchtest.h @@ -0,0 +1,52 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +//#include "../config.h" + +//extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION); +//extern HINSTANCE ptw32_h_kernel32; + +#define PTW32_OBJECT_AUTO_INIT ((void *) -1) + +void dummy_call(int * a); +void interlocked_inc_with_conditionals(int *a); +void interlocked_dec_with_conditionals(int *a); + +/****************************************************************************************/ diff --git a/src/pthread/tests/benchtest1.c b/src/pthread/tests/benchtest1.c new file mode 100644 index 000000000..cc89b55b3 --- /dev/null +++ b/src/pthread/tests/benchtest1.c @@ -0,0 +1,226 @@ +/* + * benchtest1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over lock/unlock for each mutex type. + */ + +#include "test.h" +#include "implement.h" + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 100000L + +static pthread_mutex_t mx; +static pthread_mutexattr_t ma; +static struct _timeb currSysTimeStart; +static struct _timeb currSysTimeStop; +static long durationMilliSecs; +static long overHeadMilliSecs = 0; +static int one = 1; +static int zero = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +static void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + assert(pthread_mutexattr_settype(&ma, mType) == 0); +#endif + assert(pthread_mutex_init(&mx, &ma) == 0); + + TESTSTART + assert(pthread_mutex_lock(&mx) == zero); + assert(pthread_mutex_unlock(&mx) == zero); + TESTSTOP + + assert(pthread_mutex_destroy(&mx) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int pthread_test_bench1() +{ + int i = 0; + pte_osMutexHandle cs; + + overHeadMilliSecs = 0; + one = 1; + zero = 0; + + pthread_mutexattr_init(&ma); + + printf( "=============================================================================\n"); + printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n", + ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == one); + assert(1 == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + TESTSTART + assert((dummy_call(&i), 1) == one); + assert((dummy_call(&i), 1) == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Dummy call x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + TESTSTART + assert((interlocked_inc_with_conditionals(&i), 1) == one); + assert((interlocked_dec_with_conditionals(&i), 1) == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Dummy call -> Interlocked with cond x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + TESTSTART + assert((PTE_ATOMIC_INCREMENT(&i), 1) == one); + assert((PTE_ATOMIC_INCREMENT(&i), 1) == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "InterlockedOp x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + pte_osMutexCreate(&cs); + + TESTSTART + { + + pte_osMutexLock(cs); + pte_osMutexUnlock(cs); + } + TESTSTOP + + pte_osMutexDelete(cs); + + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Simple Critical Section", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + one = i; /* Dummy assignment to avoid 'variable unused' warning */ + return 0; +} diff --git a/src/pthread/tests/benchtest2.c b/src/pthread/tests/benchtest2.c new file mode 100644 index 000000000..73520299f --- /dev/null +++ b/src/pthread/tests/benchtest2.c @@ -0,0 +1,200 @@ +/* + * benchtest1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Two threads iterate over lock/unlock for each mutex type. + * The two threads are forced into lock-step using two mutexes, + * forcing the threads to block on each lock operation. The + * time measured is therefore the worst case senario. + */ + +#include "test.h" + + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 10000L + +static pthread_mutex_t gate1, gate2; +static pthread_mutexattr_t ma; +static long durationMilliSecs; +static long overHeadMilliSecs = 0; +static struct _timeb currSysTimeStart; +static struct _timeb currSysTimeStop; +static pthread_t worker; +static int running = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +static void * +overheadThread(void * arg) +{ + do + { + sched_yield(); + } + while (running); + + return NULL; +} + + +static void * +workerThread(void * arg) +{ + do + { + (void) pthread_mutex_lock(&gate1); + (void) pthread_mutex_lock(&gate2); + (void) pthread_mutex_unlock(&gate1); + sched_yield(); + (void) pthread_mutex_unlock(&gate2); + } + while (running); + + return NULL; +} + +static void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + assert(pthread_mutexattr_settype(&ma, mType) == 0); +#endif + assert(pthread_mutex_init(&gate1, &ma) == 0); + assert(pthread_mutex_init(&gate2, &ma) == 0); + assert(pthread_mutex_lock(&gate1) == 0); + assert(pthread_mutex_lock(&gate2) == 0); + running = 1; + assert(pthread_create(&worker, NULL, workerThread, NULL) == 0); + TESTSTART + (void) pthread_mutex_unlock(&gate1); + sched_yield(); + (void) pthread_mutex_unlock(&gate2); + (void) pthread_mutex_lock(&gate1); + (void) pthread_mutex_lock(&gate2); + TESTSTOP + running = 0; + assert(pthread_mutex_unlock(&gate2) == 0); + assert(pthread_mutex_unlock(&gate1) == 0); + assert(pthread_join(worker, NULL) == 0); + assert(pthread_mutex_destroy(&gate2) == 0); + assert(pthread_mutex_destroy(&gate1) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS / 4 /* Four locks/unlocks per iteration */); +} + + +int pthread_test_bench2() +{ + assert(pthread_mutexattr_init(&ma) == 0); + + printf( "=============================================================================\n"); + printf( "\nLock plus unlock on a locked mutex.\n"); + printf("%ld iterations, four locks/unlocks per iteration.\n\n", ITERATIONS); + + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + running = 1; + assert(pthread_create(&worker, NULL, overheadThread, NULL) == 0); + TESTSTART + sched_yield(); + sched_yield(); + TESTSTOP + running = 0; + assert(pthread_join(worker, NULL) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Blocking locks", 0); +#endif + + printf( "=============================================================================\n"); + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/src/pthread/tests/benchtest3.c b/src/pthread/tests/benchtest3.c new file mode 100644 index 000000000..79509f94c --- /dev/null +++ b/src/pthread/tests/benchtest3.c @@ -0,0 +1,164 @@ +/* + * benchtest3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over a trylock on a locked mutex for each mutex type. + */ + +#include "test.h" + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 100000L + +static pthread_mutex_t mx; +static pthread_mutexattr_t ma; +static struct _timeb currSysTimeStart; +static struct _timeb currSysTimeStop; +static long durationMilliSecs; +static long overHeadMilliSecs = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +static void * +trylockThread (void * arg) +{ + TESTSTART + (void) pthread_mutex_trylock(&mx); + TESTSTOP + + return NULL; +} + + +static void +runTest (char * testNameString, int mType) +{ + pthread_t t; + +#ifdef PTW32_MUTEX_TYPES + (void) pthread_mutexattr_settype(&ma, mType); +#endif + assert(pthread_mutex_init(&mx, &ma) == 0); + assert(pthread_mutex_lock(&mx) == 0); + assert(pthread_create(&t, NULL, trylockThread, 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mx) == 0); + assert(pthread_mutex_destroy(&mx) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int pthread_test_bench3() +{ + assert(pthread_mutexattr_init(&ma) == 0); + + printf( "=============================================================================\n"); + printf( "\nTrylock on a locked mutex.\n"); + printf( "%ld iterations.\n\n", ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/src/pthread/tests/benchtest4.c b/src/pthread/tests/benchtest4.c new file mode 100644 index 000000000..c7113783d --- /dev/null +++ b/src/pthread/tests/benchtest4.c @@ -0,0 +1,150 @@ +/* + * benchtest4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over trylock/unlock for each mutex type. + */ + +#include "test.h" + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 100000L + +static pthread_mutex_t mx; +static pthread_mutexattr_t ma; +static struct _timeb currSysTimeStart; +static struct _timeb currSysTimeStop; +static long durationMilliSecs; +static long overHeadMilliSecs = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +static void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + pthread_mutexattr_settype(&ma, mType); +#endif + pthread_mutex_init(&mx, &ma); + + TESTSTART + (void) pthread_mutex_trylock(&mx); + (void) pthread_mutex_unlock(&mx); + TESTSTOP + + pthread_mutex_destroy(&mx); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int pthread_test_bench4() +{ + pthread_mutexattr_init(&ma); + + printf( "=============================================================================\n"); + printf( "Trylock plus unlock on an unlocked mutex.\n"); + printf( "%ld iterations.\n\n", ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/src/pthread/tests/benchtest5.c b/src/pthread/tests/benchtest5.c new file mode 100644 index 000000000..639667cf2 --- /dev/null +++ b/src/pthread/tests/benchtest5.c @@ -0,0 +1,179 @@ +/* + * benchtest5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Semaphore + * Single thread iteration over post/wait for a semaphore. + */ + +#include "test.h" + + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define ITERATIONS 1000000L + +sem_t sema; +//HANDLE w32sema; + +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; +int one = 1; +int zero = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void +reportTest (char * testNameString) +{ + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + printf( "=============================================================================\n"); + printf( "\nOperations on a semaphore.\n%ld iterations\n\n", + ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); +<<<<<<< .mine +<<<<<<< .mine + * -------------------------------------------------------------------------- +======= + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * +======= + * -------------------------------------------------------------------------- +>>>>>>> .r47 +>>>>>>> .r51 + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + /* + * Now we can start the actual tests + */ + assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0); + TESTSTART + assert(ReleaseSemaphore(w32sema, 1, NULL) != zero); + TESTSTOP + assert(CloseHandle(w32sema) != 0); + + reportTest("W32 Post with no waiters"); + + + assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0); + TESTSTART + assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0); + TESTSTOP + assert(CloseHandle(w32sema) != 0); + + reportTest("W32 Wait without blocking"); + + + assert(sem_init(&sema, 0, 0) == 0); + TESTSTART + assert(sem_post(&sema) == zero); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("POSIX Post with no waiters"); + + + assert(sem_init(&sema, 0, ITERATIONS) == 0); + TESTSTART + assert(sem_wait(&sema) == zero); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("POSIX Wait without blocking"); + + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + return 0; +} diff --git a/src/pthread/tests/cancel1.c b/src/pthread/tests/cancel1.c new file mode 100644 index 000000000..311904b92 --- /dev/null +++ b/src/pthread/tests/cancel1.c @@ -0,0 +1,188 @@ +/* + * File: cancel1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test setting cancel state and cancel type. + * - + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - pthread_setcancelstate function + * - pthread_setcanceltype function + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - pthread_create, pthread_self work. + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 2 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* ... */ + { + int oldstate; + + assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0); + assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */ + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0); + assert(pthread_setcancelstate(oldstate, &oldstate) == 0); + assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */ + + /* We don't support async cancellation so all of these tests would fail... */ +#if 0 + int oldtype; + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0); + assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */ + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + assert(pthread_setcanceltype(oldtype, &oldtype) == 0); + assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */ +#endif //0 + + } + + return 0; +} + +int pthread_test_cancel1() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i],NULL) == 0); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/cancel2.c b/src/pthread/tests/cancel2.c new file mode 100644 index 000000000..0c2b14392 --- /dev/null +++ b/src/pthread/tests/cancel2.c @@ -0,0 +1,235 @@ +/* + * File: cancel2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test SEH or C++ cancel exception handling within + * application exception blocks. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 1 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER; + +static void * +mythread(void * arg) +{ +// int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + switch (bag->threadnum % 2) + { + case 0: + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); +// result = 0; + break; + case 1: + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); +// result = 1; + break; + } + +#if defined(__cplusplus) + try +#endif + { + /* Wait for go from main */ + assert(pthread_mutex_lock(&waitLock) == 0); + assert(pthread_mutex_unlock(&waitLock) == 0); + sched_yield(); + + for (;;) + { + pthread_testcancel(); + sched_yield(); + } + + } +#if defined(__cplusplus) + catch (...) + { + /* + * Should not get into here. + */ +// result += 100; + } +#endif + + /* + * Should not get to here either. + */ + return 0; +} + +int pthread_test_cancel2() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + waitLock = PTHREAD_MUTEX_INITIALIZER; + + assert((t[0] = pthread_self()).p != NULL); + assert(pthread_mutex_lock(&waitLock) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + assert(pthread_mutex_unlock(&waitLock) == 0); + + pte_osThreadSleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + fail = (result != (int) PTHREAD_CANCELED); + failed |= fail; + } + + assert(!failed); + + assert(pthread_mutex_destroy(&waitLock) == 0); + + /* + * Success. + */ + return 0; +} + + diff --git a/src/pthread/tests/cancel3.c b/src/pthread/tests/cancel3.c new file mode 100644 index 000000000..c59ff58d4 --- /dev/null +++ b/src/pthread/tests/cancel3.c @@ -0,0 +1,219 @@ +/* + * File: cancel3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test asynchronous cancelation (alertable or non-alertable). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - Async cancel if thread is not blocked (i.e. voluntarily resumes if blocked). + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join. + * - quserex.dll and alertdrv.sys are not available. + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread (void *arg) +{ + int result = ((int) PTHREAD_CANCELED + 1); + bag_t *bag = (bag_t *) arg; + + assert (bag == &threadbag[bag->threadnum]); + assert (bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + pte_osThreadSleep (100); + + return (void *) result; +} + +int pthread_test_cancel3() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert ((t[0] = pthread_self ()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) + == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep (500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert (pthread_cancel (t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep (NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf (stderr, "Thread %d: started %d\n", i, + threadbag[i].started); + } + } + + assert (!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert (pthread_join (t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf (stderr, "Thread %d: started %d: count %d\n", + i, threadbag[i].started, threadbag[i].count); + } + failed = (failed || fail); + } + + assert (!failed); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cancel3() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ diff --git a/src/pthread/tests/cancel4.c b/src/pthread/tests/cancel4.c new file mode 100644 index 000000000..cc0e5b19b --- /dev/null +++ b/src/pthread/tests/cancel4.c @@ -0,0 +1,202 @@ +/* + * File: cancel4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cancelation does not occur in deferred + * cancelation threads with no cancelation points. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - pthread_create + * pthread_self + * pthread_cancel + * pthread_join + * pthread_setcancelstate + * pthread_setcanceltype + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + + /* + * We wait up to 2 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 20; bag->count++) + pte_osThreadSleep(100); + + return (void *) result; +} + +int pthread_test_cancel4() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED indicates that async + * cancelation occurred. + */ + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result == (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/cancel5.c b/src/pthread/tests/cancel5.c new file mode 100644 index 000000000..7ed0eb75d --- /dev/null +++ b/src/pthread/tests/cancel5.c @@ -0,0 +1,210 @@ +/* + * File: cancel5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_cancel from the main thread + * without calling pthread_self() in main. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread (void *arg) +{ + int result = ((int) PTHREAD_CANCELED + 1); + bag_t *bag = (bag_t *) arg; + + assert (bag == &threadbag[bag->threadnum]); + assert (bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + pte_osThreadSleep (100); + + return (void *) result; +} + +int pthread_test_cancel5() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) + == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep (500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert (pthread_cancel (t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep (NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert (!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert (pthread_join (t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert (!failed); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cancel5() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ diff --git a/src/pthread/tests/cancel6a.c b/src/pthread/tests/cancel6a.c new file mode 100644 index 000000000..309c7a541 --- /dev/null +++ b/src/pthread/tests/cancel6a.c @@ -0,0 +1,203 @@ +/* + * File: cancel6a.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Test Synopsis: Test double cancelation - asynchronous. + * Second attempt should fail (ESRCH). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + pte_osThreadSleep(100); + + return (void *) result; +} + +int pthread_test_cancel6a() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + assert(pthread_cancel(t[i]) == ESRCH); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cancel6a() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ diff --git a/src/pthread/tests/cancel6d.c b/src/pthread/tests/cancel6d.c new file mode 100644 index 000000000..e4489152f --- /dev/null +++ b/src/pthread/tests/cancel6d.c @@ -0,0 +1,189 @@ +/* + * File: cancel6d.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Test Synopsis: Test double cancelation - deferred. + * Second attempt should succeed (unless the canceled thread has started + * cancelation already - not tested here). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + { + pte_osThreadSleep(100); + pthread_testcancel(); + } + + return (void *) result; +} + +int pthread_test_cancel6d() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/cleanup0.c b/src/pthread/tests/cleanup0.c new file mode 100644 index 000000000..069f98d59 --- /dev/null +++ b/src/pthread/tests/cleanup0.c @@ -0,0 +1,225 @@ +/* + * File: cleanup1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t pop_count = {0, 0}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + pte_osMutexLock(sI->cs); + sI->i++; + pte_osMutexUnlock(sI->cs); +} + +static void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + pte_osThreadSleep(100); + + pthread_cleanup_pop(1); + + return (void *) result; +} + +int pthread_test_cleanup0() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pte_osMutexCreate(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result == (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + pte_osMutexDelete(pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cleanup0() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ + diff --git a/src/pthread/tests/cleanup1.c b/src/pthread/tests/cleanup1.c new file mode 100644 index 000000000..8653fd4b9 --- /dev/null +++ b/src/pthread/tests/cleanup1.c @@ -0,0 +1,240 @@ +/* + * File: cleanup1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t pop_count = {0, 0}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + pte_osMutexLock(sI->cs); + + sI->i++; + + pte_osMutexUnlock(sI->cs); + +} + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + /* + * We don't have true async cancelation - it relies on the thread + * at least re-entering the run state at some point. + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + pte_osThreadSleep(100); + + pthread_cleanup_pop(0); + + return (void *) result; +} + +int pthread_test_cleanup1() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pte_osMutexCreate(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + pte_osMutexDelete(pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cleanup1() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ + diff --git a/src/pthread/tests/cleanup2.c b/src/pthread/tests/cleanup2.c new file mode 100644 index 000000000..b4a251371 --- /dev/null +++ b/src/pthread/tests/cleanup2.c @@ -0,0 +1,215 @@ +/* + * File: cleanup2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t pop_count = {0, 0}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + pte_osMutexLock(sI->cs); + sI->i++; + pte_osMutexUnlock(sI->cs); +} + +static void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + sched_yield(); + + pthread_cleanup_pop(1); + + return (void *) result; +} + +int pthread_test_cleanup2() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pte_osMutexCreate(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != 0); + + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + pte_osMutexDelete(pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cleanup2() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ + diff --git a/src/pthread/tests/cleanup3.c b/src/pthread/tests/cleanup3.c new file mode 100644 index 000000000..045b848af --- /dev/null +++ b/src/pthread/tests/cleanup3.c @@ -0,0 +1,226 @@ +/* + * File: cleanup3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler does not execute (when thread is + * not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#include "test.h" + +#ifdef PTE_SUPPORT_ASYNC_CANCEL + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t pop_count = {0, 0}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + pte_osMutexLock(sI->cs); + + sI->i++; + + pte_osMutexUnlock(sI->cs); + +} + +static void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + sched_yield(); + + pte_osMutexLock(pop_count.cs); + + pop_count.i--; + + pte_osMutexUnlock(pop_count.cs); + + + pthread_cleanup_pop(0); + + return (void *) result; +} + +int pthread_test_cleanup3() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pte_osMutexCreate(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != 0); + + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == -(NUMTHREADS)); + + pte_osMutexDelete(pop_count.cs); + + /* + * Success. + */ + return 0; +} + + +#else /* PTE_SUPPORT_ASYNC_CANCEL */ + +int pthread_test_cleanup3() +{ + printf("Test not run - async cancellation not supported\n"); + + return 0; +} + +#endif /* !PTE_SUPPORT_ASYNC_CANCEL */ diff --git a/src/pthread/tests/condvar1.c b/src/pthread/tests/condvar1.c new file mode 100644 index 000000000..37eb37579 --- /dev/null +++ b/src/pthread/tests/condvar1.c @@ -0,0 +1,104 @@ +/* + * File: condvar1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test initialisation and destruction of a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_init returns 0, and + * - pthread_cond_destroy returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_init returns non-zero, or + * - pthread_cond_destroy returns non-zero. + * - Process returns non-zero exit status. + */ + +#include "test.h" + +static pthread_cond_t cv = NULL; + +int pthread_test_condvar1() +{ + cv = NULL; + + assert(cv == NULL); + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(cv != NULL); + + assert(pthread_cond_destroy(&cv) == 0); + + assert(cv == NULL); + + return 0; +} diff --git a/src/pthread/tests/condvar1_1.c b/src/pthread/tests/condvar1_1.c new file mode 100644 index 000000000..11eace66d --- /dev/null +++ b/src/pthread/tests/condvar1_1.c @@ -0,0 +1,122 @@ +/* + * File: condvar1_1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test CV linked list management. + * + * Test Method (Validation or Falsification): + * - Validation: + * Initiate and destroy several CVs in random order. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - All initialised CVs destroyed without segfault. + * - Successfully broadcasts all remaining CVs after + * each CV is removed. + * + * Fail Criteria: + */ + +#include +#include "test.h" + +enum +{ + NUM_CV = 10 +}; + +static pthread_cond_t cv[NUM_CV]; + +int pthread_test_condvar1_1() +{ + int i, j; + + for (i = 0; i < NUM_CV; i++) + { + /* Traverse the list before every init of a CV. */ + assert(pthread_timechange_handler_np(NULL) == (void *) 0); + assert(pthread_cond_init(&cv[i], NULL) == 0); + } + + j = NUM_CV; + (void) srand((unsigned)time(NULL)); + + do + { + i = rand() % NUM_CV; + + if (cv[i] != NULL) + { + j--; + assert(pthread_cond_destroy(&cv[i]) == 0); + /* Traverse the list every time we remove a CV. */ + assert(pthread_timechange_handler_np(NULL) == (void *) 0); + } + } + while (j > 0); + + return 0; +} diff --git a/src/pthread/tests/condvar1_2.c b/src/pthread/tests/condvar1_2.c new file mode 100644 index 000000000..670478d82 --- /dev/null +++ b/src/pthread/tests/condvar1_2.c @@ -0,0 +1,130 @@ +/* + * File: condvar1_2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test CV linked list management and serialisation. + * + * Test Method (Validation or Falsification): + * - Validation: + * Initiate and destroy several CVs in random order. + * Asynchronously traverse the CV list and broadcast. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - All initialised CVs destroyed without segfault. + * - Successfully broadcasts all remaining CVs after + * each CV is removed. + * + * Fail Criteria: + */ + +#include +#include "test.h" + +enum +{ + NUM_CV = 5, + NUM_LOOPS = 5 +}; + +static pthread_cond_t cv[NUM_CV]; + +int pthread_test_condvar1_2() +{ + int i, j, k; + int result = -1; + pthread_t t; + + for (k = 0; k < NUM_LOOPS; k++) + { + for (i = 0; i < NUM_CV; i++) + { + assert(pthread_cond_init(&cv[i], NULL) == 0); + } + + j = NUM_CV; + (void) srand((unsigned)time(NULL)); + + /* Traverse the list asynchronously. */ + assert(pthread_create(&t, NULL, pthread_timechange_handler_np, NULL) == 0); + + do + { + i = rand() % NUM_CV; + if (cv[i] != NULL) + { + j--; + assert(pthread_cond_destroy(&cv[i]) == 0); + } + } + while (j > 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert (result == 0); + } + + return 0; +} diff --git a/src/pthread/tests/condvar2.c b/src/pthread/tests/condvar2.c new file mode 100644 index 000000000..15c0bf556 --- /dev/null +++ b/src/pthread/tests/condvar2.c @@ -0,0 +1,129 @@ +/* + * File: condvar2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timed wait on a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because the CV is never signaled, we expect the wait to time out. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" + + +static pthread_cond_t cv; +static pthread_mutex_t mutex; + +#include "../implement.h" + +int pthread_test_condvar2() +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mutex) == 0); + + { + int result = pthread_cond_destroy(&cv); + + assert(result == 0); + } + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar2_1.c b/src/pthread/tests/condvar2_1.c new file mode 100644 index 000000000..39f6787ec --- /dev/null +++ b/src/pthread/tests/condvar2_1.c @@ -0,0 +1,154 @@ +/* + * File: condvar2_1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with no signal/broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because the CV is never signaled, we expect the waits to time out. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" + + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static struct timespec abstime = + { + 0, 0 + }; + +enum +{ + NUMTHREADS = OS_MAX_SIMUL_THREADS +}; + +static void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return arg; +} + +#include "../implement.h" + +int pthread_test_condvar2_1() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_mutex_lock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + assert(pthread_mutex_unlock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + + assert(result == i); + } + + assert(pthread_cond_destroy(&cv) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar3.c b/src/pthread/tests/condvar3.c new file mode 100644 index 000000000..ca3f4e421 --- /dev/null +++ b/src/pthread/tests/condvar3.c @@ -0,0 +1,152 @@ +/* + * File: condvar3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test basic function of a CV + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - The primary thread takes the lock before creating any threads. + * The secondary thread blocks on the lock allowing the primary + * thread to enter the cv wait state which releases the lock. + * The secondary thread then takes the lock and signals the waiting + * primary thread. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static int shared = 0; + +enum +{ + NUMTHREADS = 2 /* Including the primary thread. */ +}; + +static void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + shared++; + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_cond_signal(&cv) == 0); + + return (void *) 0; +} + +int pthread_test_condvar3() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert((t[0] = pthread_self()).p != NULL); + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + abstime.tv_sec += 5; + + while (! (shared > 0)) + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0); + + assert(shared > 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_cond_destroy(&cv) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar3_1.c b/src/pthread/tests/condvar3_1.c new file mode 100644 index 000000000..8725aec7c --- /dev/null +++ b/src/pthread/tests/condvar3_1.c @@ -0,0 +1,206 @@ +/* + * File: condvar3_1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with some signaled. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + * Some are signaled, the rest time out. Pthread_cond_destroy() will fail + * unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" + + +static pthread_cond_t cv; +static pthread_cond_t cv1; +static pthread_mutex_t mutex; +static pthread_mutex_t mutex1; +static struct timespec abstime = + { + 0, 0 + }; +static int timedout = 0; +static int signaled = 0; +static int awoken = 0; +static int waiting = 0; + +enum +{ + NUMTHREADS = 30 +}; + +static void * +mythread(void * arg) +{ + int result; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_mutex_lock(&mutex1) == 0); + ++waiting; + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(pthread_cond_signal(&cv1) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + result = pthread_cond_timedwait(&cv, &mutex, &abstime); + if (result == ETIMEDOUT) + { + timedout++; + } + else + { + awoken++; + } + assert(pthread_mutex_unlock(&mutex) == 0); + + return arg; +} + +#include "../implement.h" + +int pthread_test_condvar3_1() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + + timedout = 0; + signaled = 0; + awoken = 0; + waiting = 0; + + + assert(pthread_cond_init(&cv, NULL) == 0); + assert(pthread_cond_init(&cv1, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + assert(pthread_mutex_init(&mutex1, NULL) == 0); + + assert(pthread_mutex_lock(&mutex1) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + do + { + assert(pthread_cond_wait(&cv1,&mutex1) == 0); + } + while ( NUMTHREADS > waiting ); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++) + { +// assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_cond_signal(&cv) == 0); +// assert(pthread_mutex_unlock(&mutex) == 0); + + signaled++; + } + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + assert(result == i); + } + + assert(signaled == awoken); + assert(timedout == NUMTHREADS - signaled); + + assert(pthread_cond_destroy(&cv1) == 0); + + { + assert(pthread_cond_destroy(&cv) == 0); + } + + assert(pthread_mutex_destroy(&mutex1) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar3_2.c b/src/pthread/tests/condvar3_2.c new file mode 100644 index 000000000..91ade4052 --- /dev/null +++ b/src/pthread/tests/condvar3_2.c @@ -0,0 +1,201 @@ +/* + * File: condvar3_2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with remainder broadcast awoken. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + * Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail + * unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include "implement.h" + + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static struct timespec abstime = + { + 0, 0 + }; +static struct timespec abstime2 = + { + 0, 0 + }; +static int timedout = 0; +static int awoken = 0; + +enum +{ + NUMTHREADS = OS_MAX_SIMUL_THREADS +}; + +static void * +mythread(void * arg) +{ + int result; + + assert(pthread_mutex_lock(&mutex) == 0); + + abstime2.tv_sec = abstime.tv_sec; + + if ((int) arg % 3 == 0) + { + abstime2.tv_sec += 2; + } + + result = pthread_cond_timedwait(&cv, &mutex, &abstime2); + assert(pthread_mutex_unlock(&mutex) == 0); + if (result == ETIMEDOUT) + { + PTE_ATOMIC_INCREMENT(&timedout); + } + else + { + PTE_ATOMIC_INCREMENT(&awoken); + } + + + return arg; +} + +#include "../implement.h" + +int pthread_test_condvar3_2() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + timedout = 0; + awoken = 0; + + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; + abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + assert(pthread_mutex_lock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + assert(pthread_mutex_unlock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + assert(result == i); + /* + * Approximately 2/3rds of the threads are expected to time out. + * Signal the remainder after some threads have woken up and exited + * and while some are still waking up after timeout. + * Also tests that redundant broadcasts don't return errors. + */ + +// assert(pthread_mutex_lock(&mutex) == 0); + + if (PTE_ATOMIC_EXCHANGE_ADD(&awoken, 0L) > NUMTHREADS/3) + { + assert(pthread_cond_broadcast(&cv) == 0); + } + +// assert(pthread_mutex_unlock(&mutex) == 0); + + } + + assert(awoken == NUMTHREADS - timedout); + + { + assert(pthread_cond_destroy(&cv) == 0); + } + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar3_3.c b/src/pthread/tests/condvar3_3.c new file mode 100644 index 000000000..bd67c8a27 --- /dev/null +++ b/src/pthread/tests/condvar3_3.c @@ -0,0 +1,145 @@ +/* + * File: condvar3_3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeouts and lost signals on a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +/* Timur Aydin (taydin@snet.net) */ + +#include "test.h" + + +static pthread_cond_t cnd; +static pthread_mutex_t mtx; + +int pthread_test_condvar3_3() +{ + int rc; + + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cnd, 0) == 0); + assert(pthread_mutex_init(&mtx, 0) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + abstime.tv_sec += 1; + + /* Here pthread_cond_timedwait should time out after one second. */ + + assert(pthread_mutex_lock(&mtx) == 0); + + assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + + // Stop some compilers from reporting that rc is not used + rc = rc; + + assert(pthread_mutex_unlock(&mtx) == 0); + + /* Here, the condition variable is signaled, but there are no + threads waiting on it. The signal should be lost and + the next pthread_cond_timedwait should time out too. */ + +// assert(pthread_mutex_lock(&mtx) == 0); + + assert((rc = pthread_cond_signal(&cnd)) == 0); +// assert(pthread_mutex_unlock(&mtx) == 0); + + assert(pthread_mutex_lock(&mtx) == 0); + + _ftime(&currSysTime); + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + abstime.tv_sec += 1; + + assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + assert(pthread_mutex_unlock(&mtx) == 0); + + assert(pthread_cond_destroy(&cnd) == 0); + assert(pthread_mutex_destroy(&mtx) == 0); + + return 0; +} diff --git a/src/pthread/tests/condvar4.c b/src/pthread/tests/condvar4.c new file mode 100644 index 000000000..da56a1784 --- /dev/null +++ b/src/pthread/tests/condvar4.c @@ -0,0 +1,181 @@ +/* + * File: condvar4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test PTHREAD_COND_INITIALIZER. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test basic CV function but starting with a static initialised + * CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +enum +{ + NUMTHREADS = 2 +}; + +static void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_signal(&cvthing.notbusy) == 0); + + return (void *) 0; +} + +int pthread_test_condvar4() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + cvthing.shared = 0; + + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); + assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + assert(cvthing.shared > 0); + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_join(t[1], NULL) == 0); + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + return 0; +} diff --git a/src/pthread/tests/condvar5.c b/src/pthread/tests/condvar5.c new file mode 100644 index 000000000..5545d09e4 --- /dev/null +++ b/src/pthread/tests/condvar5.c @@ -0,0 +1,182 @@ +/* + * File: condvar5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with one waiting CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +enum +{ + NUMTHREADS = 2 +}; + +static void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + return (void *) 0; +} + +int pthread_test_condvar5() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); + + assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + assert(cvthing.shared > 0); + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + return 0; +} diff --git a/src/pthread/tests/condvar6.c b/src/pthread/tests/condvar6.c new file mode 100644 index 000000000..4f102e197 --- /dev/null +++ b/src/pthread/tests/condvar6.c @@ -0,0 +1,260 @@ + +/* + * File: condvar6.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = + { + 0, 0 + }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + while (! (cvthing.shared > 0)) + { + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + } + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int pthread_test_condvar6() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + + start_flag = PTHREAD_MUTEX_INITIALIZER; + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&start_flag) == 0); + + + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + pte_osThreadSleep(1000); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Give threads time to complete. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + } + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS); + + assert(pthread_mutex_destroy(&start_flag) == 0); + + /* + * Success. + */ + return 0; +} + + diff --git a/src/pthread/tests/condvar7.c b/src/pthread/tests/condvar7.c new file mode 100644 index 000000000..157e58476 --- /dev/null +++ b/src/pthread/tests/condvar7.c @@ -0,0 +1,263 @@ +/* + * File: condvar7.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = + { + 0, 0 + }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + { + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + } + + pthread_cleanup_pop(0); + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int pthread_test_condvar7() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&start_flag) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 10; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + pte_osThreadSleep(1000); + + /* + * Cancel one of the threads. + */ + assert(pthread_cancel(t[1]) == 0); + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + /* + * Signal all remaining waiting threads. + */ + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Wait for all threads to complete. + */ + for (i = 2; i <= NUMTHREADS; i++) + assert(pthread_join(t[i], NULL) == 0); + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + } + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == (NUMTHREADS - 1)); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/condvar8.c b/src/pthread/tests/condvar8.c new file mode 100644 index 000000000..2f242ca76 --- /dev/null +++ b/src/pthread/tests/condvar8.c @@ -0,0 +1,265 @@ +/* + * File: condvar8.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = + { + 0, 0 + }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + pthread_cleanup_pop(0); + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int pthread_test_condvar8() +{ + int failed = 0; + int i; + int first, last; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + start_flag = PTHREAD_MUTEX_INITIALIZER; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 10; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (first = 1, last = NUMTHREADS / 2; + first < NUMTHREADS; + first = last + 1, last = NUMTHREADS) + { + assert(pthread_mutex_lock(&start_flag) == 0); + + for (i = first; i <= last; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + cvthing.shared = 0; + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + pte_osThreadSleep(100); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Give threads time to complete. + */ + for (i = first; i <= last; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + assert(awoken == (i - 1)); + } + + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS); + + assert(pthread_mutex_destroy(&start_flag) == 0); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/condvar9.c b/src/pthread/tests/condvar9.c new file mode 100644 index 000000000..f2334106a --- /dev/null +++ b/src/pthread/tests/condvar9.c @@ -0,0 +1,271 @@ +/* + * File: condvar9.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them, + * and then repeat. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 9 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + int finished; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ + { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; + }; + +static cvthing_t cvthing = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = + { + 0, 0 + }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + /* + * pthread_cond_timedwait is a cancelation point and we're + * going to cancel some threads deliberately. + */ + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + pthread_cleanup_pop(0); + + assert(cvthing.shared > 0); + + awoken++; + bag->finished = 1; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int pthread_test_condvar9() +{ + int failed = 0; + int i; + int first, last; + int canceledThreads = 0; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + cvthing.notbusy = PTHREAD_COND_INITIALIZER; + cvthing.lock = PTHREAD_MUTEX_INITIALIZER; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (first = 1, last = NUMTHREADS / 2; + first < NUMTHREADS; + first = last + 1, last = NUMTHREADS) + { + int ct; + + assert(pthread_mutex_lock(&start_flag) == 0); + + for (i = first; i <= last; i++) + { + threadbag[i].started = threadbag[i].finished = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + cvthing.shared = 0; + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + pte_osThreadSleep(1000); + + ct = (first + last) / 2; + assert(pthread_cancel(t[ct]) == 0); + canceledThreads++; + assert(pthread_join(t[ct], NULL) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Standard check that all threads started - and wait for them to finish. + */ + for (i = first; i <= last; i++) + { + failed = !threadbag[i].started; + + if (!failed) + { + assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0); + } + } + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS - canceledThreads); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/count1.c b/src/pthread/tests/count1.c new file mode 100644 index 000000000..aa88d50c7 --- /dev/null +++ b/src/pthread/tests/count1.c @@ -0,0 +1,105 @@ +/* + * count1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Description: + * Test some basic assertions about the number of threads at runtime. + */ + +#include +#include + +#include "test.h" + +#define NUMTHREADS OS_MAX_SIMUL_THREADS + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_t threads[NUMTHREADS]; +static unsigned numThreads = 0; + +static void * +myfunc(void *arg) +{ + pthread_mutex_lock(&lock); + numThreads++; + pthread_mutex_unlock(&lock); + + pte_osThreadSleep(1000); + return 0; +} + +int pthread_test_count1() +{ + int i; + int maxThreads = sizeof(threads) / sizeof(pthread_t); + + numThreads = 0; + + lock = PTHREAD_MUTEX_INITIALIZER; + + /* + * Spawn NUMTHREADS threads. Each thread should increment the + * numThreads variable, sleep for one second. + */ + for (i = 0; i < maxThreads; i++) + { + assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0); + } + + /* + * Wait for all the threads to exit. + */ + for (i = 0; i < maxThreads; i++) + { + assert(pthread_join(threads[i], NULL) == 0); + } + + /* + * Check the number of threads created. + */ + assert((int) numThreads == maxThreads); + + assert(pthread_mutex_destroy(&lock) == 0); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/create1.c b/src/pthread/tests/create1.c new file mode 100644 index 000000000..382570f79 --- /dev/null +++ b/src/pthread/tests/create1.c @@ -0,0 +1,77 @@ +/* + * create1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Description: + * Create a thread and check that it ran. + * + * Depends on API functions: None. + */ + +#include + +#include "test.h" + +static int washere = 0; + +static void * func(void * arg) +{ + washere = 1; + return 0; +} + +int pthread_test_create1() +{ + pthread_t t; + + washere = 0; + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + /* A dirty hack, but we cannot rely on pthread_join in this + primitive test. */ + pte_osThreadSleep(2000); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + return 0; +} diff --git a/src/pthread/tests/create2.c b/src/pthread/tests/create2.c new file mode 100644 index 000000000..03342a0b4 --- /dev/null +++ b/src/pthread/tests/create2.c @@ -0,0 +1,117 @@ +/* + * File: create2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that threads have a Win32 handle when started. + * + * Test Method (Validation or Falsification): + * - Statistical, not absolute (depends on sample size). + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + NUMTHREADS = 100 +}; + +static volatile int washere = 0; + +static void * func(void * arg) +{ +// washere = 1; + washere++; + return (void *) 0; +} + +int pthread_test_create2() +{ + pthread_t t; + pthread_attr_t attr; + void * result = NULL; + int i; + + washere = 0; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + for (i = 0; i < NUMTHREADS; i++) + { + washere = 0; + assert(pthread_create(&t, &attr, func, NULL) == 0); + pthread_join(t, &result); + assert(washere == 1); + } + + return 0; +} diff --git a/src/pthread/tests/create3.c b/src/pthread/tests/create3.c new file mode 100644 index 000000000..39c2eca6c --- /dev/null +++ b/src/pthread/tests/create3.c @@ -0,0 +1,127 @@ +/* + * File: create3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2003 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing NULL as thread id arg to pthread_create. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#ifdef __GNUC__ +#include +#endif + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 10 +}; + + +static void * +threadFunc(void * arg) +{ + return (void *) 0; +} + +int pthread_test_create3() +{ + int i; + pthread_t mt; + pthread_t t[NUMTHREADS]; + + assert((mt = pthread_self()).p != NULL); + + /* Avoid compiler warning */ + mt = mt; + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, threadFunc, NULL) == 0); + } + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_join(t[i],NULL) == 0); + } + + /* + * Success. + */ + return 0; +} + diff --git a/src/pthread/tests/delay1.c b/src/pthread/tests/delay1.c new file mode 100644 index 000000000..f5e3b04fe --- /dev/null +++ b/src/pthread/tests/delay1.c @@ -0,0 +1,61 @@ +/* + * delay1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_delay_np + */ + +#include "test.h" + +int pthread_test_delay1() +{ + struct timespec interval = + { + 1L, 500000000L + }; + + pthread_delay_np(&interval); + + assert(pthread_delay_np(&interval) == 0); + + return 0; +} + diff --git a/src/pthread/tests/delay2.c b/src/pthread/tests/delay2.c new file mode 100644 index 000000000..5eebb4155 --- /dev/null +++ b/src/pthread/tests/delay2.c @@ -0,0 +1,88 @@ +/* + * delay1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_delay_np + */ + +#include "test.h" + +pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; + +static void * +func(void * arg) +{ + struct timespec interval = + { + 5, 500000000L + }; + + assert(pthread_mutex_lock(&mx) == 0); + + pthread_cleanup_push(pthread_mutex_unlock, &mx); + assert(pthread_delay_np(&interval) == 0); + pthread_cleanup_pop(1); + + return (void *) 1; +} + +int pthread_test_delay2() +{ + pthread_t t; + int result = 0; + + mx = PTHREAD_MUTEX_INITIALIZER; + + assert(pthread_mutex_lock(&mx) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_cancel(t) == 0); + + assert(pthread_mutex_unlock(&mx) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == (int) PTHREAD_CANCELED); + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} + diff --git a/src/pthread/tests/detach1.c b/src/pthread/tests/detach1.c new file mode 100644 index 000000000..89d3d9ffb --- /dev/null +++ b/src/pthread/tests/detach1.c @@ -0,0 +1,103 @@ +/* + * Test for pthread_detach(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_detach(), pthread_exit(). + */ + +#include "test.h" + + +enum +{ + NUMTHREADS = 20 +}; + +static void * +func(void * arg) +{ + int i = (int) arg; + + pte_osThreadSleep(i * 10); + + pthread_exit(arg); + + /* Never reached. */ + exit(1); + + /* Just to avoid compiler warnings */ + return NULL; +} + +int pthread_test_detach1() +{ + pthread_t id[NUMTHREADS]; + int i; + + /* Create a few threads and then exit. */ + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + + /* Some threads will finish before they are detached, some after. */ + pte_osThreadSleep(NUMTHREADS/2 * 10 + 50); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_detach(id[i]) == 0); + } + + pte_osThreadSleep(NUMTHREADS * 10 + 1000); + + /* + * Check that all threads are now invalid. + * This relies on unique thread IDs - e.g. works with + * pthreads-w32 or Solaris, but may not work for Linux, BSD etc. + */ + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_kill(id[i], 0) == ESRCH); + } + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/equal1.c b/src/pthread/tests/equal1.c new file mode 100644 index 000000000..f8211d0f2 --- /dev/null +++ b/src/pthread/tests/equal1.c @@ -0,0 +1,70 @@ +/* + * Test for pthread_equal. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on functions: pthread_create(). + */ + +#include "test.h" + +static void * func(void * arg) +{ + pte_osThreadSleep(2000); + return 0; +} + +int pthread_test_equal1() +{ + pthread_t t1, t2; + + assert(pthread_create(&t1, NULL, func, (void *) 1) == 0); + + assert(pthread_create(&t2, NULL, func, (void *) 2) == 0); + + assert(pthread_equal(t1, t2) == 0); + + assert(pthread_equal(t1,t1) != 0); + + assert(pthread_join(t1,NULL) == 0); + assert(pthread_join(t2,NULL) == 0); + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/errno1.c b/src/pthread/tests/errno1.c new file mode 100644 index 000000000..f9dc94826 --- /dev/null +++ b/src/pthread/tests/errno1.c @@ -0,0 +1,179 @@ +/* + * File: errno1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test thread-safety of errno + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 3 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static pthread_mutex_t stop_here = PTHREAD_MUTEX_INITIALIZER; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + errno = bag->threadnum; + + pte_osThreadSleep(1000); + + pthread_mutex_lock(&stop_here); + + assert(errno == bag->threadnum); + + pthread_mutex_unlock(&stop_here); + + pte_osThreadSleep(1000); + + return 0; +} + +int pthread_test_errno1() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pthread_mutex_lock(&stop_here); + errno = 0; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(2000); + pthread_mutex_unlock(&stop_here); + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print ouput on failure. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + /* ... */ + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/src/pthread/tests/exception1.c b/src/pthread/tests/exception1.c new file mode 100644 index 000000000..a73ccd415 --- /dev/null +++ b/src/pthread/tests/exception1.c @@ -0,0 +1,221 @@ +/* + * File: exception1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing of exceptions back to the application. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + + +#include "test.h" + +#if defined(__cplusplus) && defined(PTE_SUPPORT_ASYNC_CANCEL) + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +static void * +exceptionedThread(void * arg) +{ + int dummy = 0; + int result = ((int)PTHREAD_CANCELED + 1); + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + pte_osThreadSleep(100); + + try + { + /* + * I had a zero divide exception here but it + * wasn't being caught by the catch(...) + * below under Mingw32. That could be a problem. + */ + throw dummy; + } + catch (...) + { + /* Should get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } + + return (void *) result; +} + +static void * +canceledThread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + int count; + + + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + try + { + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (count = 0; count < 100; count++) + pte_osThreadSleep(100); + } + catch (...) + { + /* Should NOT get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } + + return (void *) result; +} + + +int +pthread_test_exception1() +{ + int failed = 0; + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + pthread_t ct[NUMTHREADS]; + + assert((mt = pthread_self()).p != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, (void *) 0) == 0); + assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(1000); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_cancel(ct[i]) == 0); + } + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 1000); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 0; i < NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* Canceled thread */ + assert(pthread_join(ct[i], (void **) &result) == 0); + assert(!(fail = (result != (int) PTHREAD_CANCELED))); + + failed = (failed || fail); + + /* Exceptioned thread */ + assert(pthread_join(et[i], (void **) &result) == 0); + assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2)))); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + +#else + +int +pthread_test_exception1() +{ + printf("Test N/A for this compiler environment.\n"); + return 0; +} + +#endif diff --git a/src/pthread/tests/exception2.c b/src/pthread/tests/exception2.c new file mode 100644 index 000000000..cb4557b26 --- /dev/null +++ b/src/pthread/tests/exception2.c @@ -0,0 +1,150 @@ +/* + * File: exception2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing of exceptions out of thread scope. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#if defined(__cplusplus) + +#include +#include + +#ifdef __GNUC__ +#include +#endif + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + +static void * +exceptionedThread(void * arg) +{ + int dummy = 0x1; + + throw dummy; + + return (void *) 100; +} + + +int +pthread_test_exception2() +{ + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + + std::set_terminate(0); + + /* + if (argc <= 1) + { + int result; + + printf("You should see an \"abnormal termination\" message\n"); + fflush(stdout); + result = system("exception2.exe die"); + exit(0); + } + */ + assert((mt = pthread_self()).p != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); + } + + pte_osThreadSleep(1000); + + /* + * Success. + */ + return 0; +} + +#else /* defined(__cplusplus) */ + +#include + +int +pthread_test_exception2() +{ + printf("Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(__cplusplus) */ diff --git a/src/pthread/tests/exception3.c b/src/pthread/tests/exception3.c new file mode 100644 index 000000000..785190fab --- /dev/null +++ b/src/pthread/tests/exception3.c @@ -0,0 +1,161 @@ +/* + * File: exception3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test running of user supplied terminate() function. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#if defined(__cplusplus) + +# if defined(__GNUC__) && __GNUC__ < 3 +# include +# else +# include + using std::set_terminate; +# endif + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + +int caught = 0; +pthread_mutex_t caughtLock; + + + +static void +terminateFunction () +{ + assert(pthread_mutex_lock(&caughtLock) == 0); + caught++; + assert(pthread_mutex_unlock(&caughtLock) == 0); + + pthread_exit((void *) 0); +} + +static void * +exceptionedThread(void * arg) +{ + int dummy = 0x1; + + (void) set_terminate(&terminateFunction); + + throw dummy; + + return (void *) 0; +} + +int +pthread_test_exception3() +{ + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + pthread_mutexattr_t ma; + + assert((mt = pthread_self()).p != NULL); + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&caughtLock, &ma) == 0); + assert(pthread_mutexattr_destroy(&ma) == 0); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); + } + + pte_osThreadSleep(1000); + + assert(caught == NUMTHREADS); + + /* + * Success. + */ + return 0; +} + +#else /* defined(__cplusplus) */ + +#include + +int +pthread_test_exception3() +{ + printf("Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(__cplusplus) */ diff --git a/src/pthread/tests/exit1.c b/src/pthread/tests/exit1.c new file mode 100644 index 000000000..80c04b37f --- /dev/null +++ b/src/pthread/tests/exit1.c @@ -0,0 +1,69 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: None. + */ + +#include "test.h" + +static void * func(void * param) +{ + pthread_exit((void *) 0); + + /* Not reached */ + assert(0); + +} + +int pthread_test_exit1() +{ + pthread_t id; + /* A simple test first. */ + + assert(pthread_create(&id, NULL, func, 0) == 0); + + // Don't want to depend on join. + pte_osThreadSleep(1000); + + assert(pthread_join(id,NULL) == 0); + + return 0; +} diff --git a/src/pthread/tests/exit2.c b/src/pthread/tests/exit2.c new file mode 100644 index 000000000..3119c826c --- /dev/null +++ b/src/pthread/tests/exit2.c @@ -0,0 +1,71 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_create() + * pthread_exit() + */ + +#include "test.h" + +static void * +func(void * arg) +{ + pthread_exit(arg); + + /* Never reached. */ + assert(0); + + return NULL; +} + +int pthread_test_exit2() +{ + pthread_t t; + + assert(pthread_create(&t, NULL, func, (void *) NULL) == 0); + + pte_osThreadSleep(1000); + + assert(pthread_join(t,NULL) == 0); + + return 0; +} diff --git a/src/pthread/tests/exit3.c b/src/pthread/tests/exit3.c new file mode 100644 index 000000000..bdf281500 --- /dev/null +++ b/src/pthread/tests/exit3.c @@ -0,0 +1,80 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +static void * +func(void * arg) +{ + pthread_exit(arg); + + /* Never reached. */ + assert(0); + + return NULL; +} + +int pthread_test_exit3() +{ + pthread_t id[4]; + int i; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + pte_osThreadSleep(1000); + + for (i = 0; i < 4; i++) + { + void * retValue; + assert(pthread_join(id[i],&retValue) == 0); + assert((int)retValue == i); + } + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/exit4.c b/src/pthread/tests/exit4.c new file mode 100644 index 000000000..6d3e9ad44 --- /dev/null +++ b/src/pthread/tests/exit4.c @@ -0,0 +1,201 @@ +/* + * File: exit4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_exit from a Win32 thread + * without having created an implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + + +static int osThread(void * arg) +{ + int result = 1; + bag_t * bag = *((bag_t **) arg); + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* + * Doesn't return and doesn't create an implicit POSIX handle. + */ + pthread_exit((void *) result); + + return 0; +} + + + +int pthread_test_exit4() +{ + int failed = 0; + int i; + pte_osThreadHandle h[NUMTHREADS + 1]; + + for (i = 1; i <= NUMTHREADS; i++) + { + void *ptr; + + /* + char threadName[32]; + snprintf(threadName, sizeof(threadName), "test_th%d", i); + */ + + threadbag[i].started = 0; + threadbag[i].threadnum = i; + + ptr = &(threadbag[i]); + + pte_osThreadCreate(osThread, 4096, 10, + &ptr, + &h[i]); + + pte_osThreadStart(h[i]); + + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * Can't get a result code. + */ + result = 1; + + fail = (result != 1); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/src/pthread/tests/exit5.c b/src/pthread/tests/exit5.c new file mode 100644 index 000000000..5e09c0fc2 --- /dev/null +++ b/src/pthread/tests/exit5.c @@ -0,0 +1,207 @@ +/* + * File: exit5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_exit from a Win32 thread + * having created an implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - Validate return value and that POSIX handle is created and destroyed. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ + { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + pthread_t self; + }; + +static bag_t threadbag[NUMTHREADS + 1]; + +static int osThread(void * arg) +{ + int result = 1; + bag_t * bag = *((bag_t **) arg); + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + assert((bag->self = pthread_self()).p != NULL); + assert(pthread_kill(bag->self, 0) == 0); + + /* + * Doesn't return. + */ + pthread_exit((void *) result); + + return 0; +} + + + +int pthread_test_exit5() +{ + int failed = 0; + int i; + pte_osThreadHandle h[NUMTHREADS + 1]; + + for (i = 1; i <= NUMTHREADS; i++) + { + void *ptr; + + threadbag[i].started = 0; + threadbag[i].threadnum = i; + + ptr = &(threadbag[i]); + + pte_osThreadCreate(osThread, 4096, 10, + &ptr, + &h[i]); + + pte_osThreadStart(h[i]); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + pte_osThreadSleep(500); + + + /* + * Give threads time to run. + */ + pte_osThreadSleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * Can't get a result code. + */ + result = 1; + + assert(threadbag[i].self.p != NULL && pthread_kill(threadbag[i].self, 0) == ESRCH); + + fail = (result != 1); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/src/pthread/tests/inherit1.c b/src/pthread/tests/inherit1.c new file mode 100644 index 000000000..d7c10008d --- /dev/null +++ b/src/pthread/tests/inherit1.c @@ -0,0 +1,145 @@ +/* + * File: inherit1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority inheritance. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +static void * func(void * arg) +{ + int policy; + struct sched_param param; + + assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); + + return (void *) param.sched_priority; +} + +int pthread_test_inherit1() +{ + pthread_t t; + pthread_t mainThread = pthread_self(); + pthread_attr_t attr; + int result = 0; + struct sched_param param; + struct sched_param mainParam; + int prio; + int policy; + int inheritsched = -1; + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0); + assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0); + assert(inheritsched == PTHREAD_INHERIT_SCHED); + + for (prio = pte_osThreadGetMinPriority(); + prio <= pte_osThreadGetMaxPriority(); + prio++) + { + mainParam.sched_priority = prio; + + /* Change the main thread priority */ + assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0); + assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0); + assert(policy == SCHED_OTHER); + /* Priority returned below should be the level set by pthread_setschedparam(). */ + assert(mainParam.sched_priority == prio); + + pte_osThreadSetPriority(pte_osThreadGetHandle(), prio); + + assert(pte_osThreadGetPriority(pte_osThreadGetHandle()) == prio); + + for (param.sched_priority = prio; + param.sched_priority <= pte_osThreadGetMaxPriority(); + param.sched_priority++) + { + /* The new thread create should ignore this new priority */ + assert(pthread_attr_setschedparam(&attr, ¶m) == 0); + assert(pthread_create(&t, &attr, func, NULL) == 0); + pthread_join(t, (void **)&result); + assert((int) result == mainParam.sched_priority); + } + } + + return 0; +} diff --git a/src/pthread/tests/join0.c b/src/pthread/tests/join0.c new file mode 100644 index 000000000..0a0633760 --- /dev/null +++ b/src/pthread/tests/join0.c @@ -0,0 +1,75 @@ +/* + * Test for pthread_join(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_exit(). + */ + +#include "test.h" + +static void * +func(void * arg) +{ + pte_osThreadSleep(2000); + + pthread_exit(arg); + + /* Never reached. */ + exit(1); + + return 0; +} + + +int pthread_test_join0() +{ + pthread_t id; + int result; + + /* Create a single thread and wait for it to exit. */ + assert(pthread_create(&id, NULL, func, (void *) 123) == 0); + + assert(pthread_join(id, (void **) &result) == 0); + + assert(result == 123); + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/join1.c b/src/pthread/tests/join1.c new file mode 100644 index 000000000..4b55d6bef --- /dev/null +++ b/src/pthread/tests/join1.c @@ -0,0 +1,83 @@ +/* + * Test for pthread_join(). + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_join(), pthread_exit(). + */ + +#include "test.h" + +static void * +func(void * arg) +{ + int i = (int) arg; + + pte_osThreadSleep(i * 100); + + pthread_exit(arg); + + /* Never reached. */ + return 0; +} + +int pthread_test_join1() +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + /* Some threads will finish before they are joined, some after. */ + pte_osThreadSleep(20 * 100 + 50); + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/join2.c b/src/pthread/tests/join2.c new file mode 100644 index 000000000..a2e1dc367 --- /dev/null +++ b/src/pthread/tests/join2.c @@ -0,0 +1,74 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +static void * +func(void * arg) +{ + pte_osThreadSleep(2000); + return arg; +} + +int pthread_test_join2() +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/join3.c b/src/pthread/tests/join3.c new file mode 100644 index 000000000..7f0d22611 --- /dev/null +++ b/src/pthread/tests/join3.c @@ -0,0 +1,80 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +static void * +func(void * arg) +{ + sched_yield(); + return arg; +} + +int pthread_test_join3() +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + /* + * Let threads exit before we join them. + * We should still retrieve the exit code for the threads. + */ + pte_osThreadSleep(1000); + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/join4.c b/src/pthread/tests/join4.c new file mode 100644 index 000000000..add465c17 --- /dev/null +++ b/src/pthread/tests/join4.c @@ -0,0 +1,83 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Verifies that pthread_join can be cancelled. + */ + +#include "test.h" + +static pthread_t handle1; +static pthread_t handle2; + +static int thread2_status; + +static void * +thr1(void * arg) +{ + pte_osThreadSleep(5000); + + return NULL; +} + +static void * +thr2(void * arg) +{ + int result; + + assert(pthread_join(handle1,NULL) == 0); + + thread2_status = 1; + + return NULL; +} + +int pthread_test_join4() +{ + thread2_status = 0; + + assert(pthread_create(&handle1, NULL, thr1, NULL) == 0); + assert(pthread_create(&handle2, NULL, thr2, NULL) == 0); + + /* Give some time for thread #1 to start sleeping and thread #2 to wait on thread #1 */ + pte_osThreadSleep(500); + + /* Cancel thread #2 (who is waiting on thread #1) */ + assert(pthread_cancel(handle2) == 0); + + /* Wait a short amount of time for cancellation to take effect */ + pte_osThreadSleep(500); + + /* Make sure that pthread_join exited after cancellation */ + assert(thread2_status == 1); + + assert(pthread_join(handle1, NULL) == 0); + assert(pthread_join(handle2, NULL) == 0); + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/kill1.c b/src/pthread/tests/kill1.c new file mode 100644 index 000000000..7abf564ee --- /dev/null +++ b/src/pthread/tests/kill1.c @@ -0,0 +1,88 @@ +/* + * File: kill1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - pthread_kill() does not support non zero signals.. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +int pthread_test_kill1() +{ + assert(pthread_kill(pthread_self(), 1) == EINVAL); + + return 0; +} diff --git a/src/pthread/tests/mutex1.c b/src/pthread/tests/mutex1.c new file mode 100644 index 000000000..1cf4e9448 --- /dev/null +++ b/src/pthread/tests/mutex1.c @@ -0,0 +1,79 @@ +/* + * mutex1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a simple mutex object, lock it, and then unlock it again. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + */ + +#include +#include + +#include "test.h" + + + +static pthread_mutex_t mutex = NULL; + +int +pthread_test_mutex1() +{ + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex1e.c b/src/pthread/tests/mutex1e.c new file mode 100644 index 000000000..af46561c7 --- /dev/null +++ b/src/pthread/tests/mutex1e.c @@ -0,0 +1,83 @@ +/* + * mutex1e.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_ERRORCHECK. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex = NULL; +static pthread_mutexattr_t mxAttr; + +int +pthread_test_mutex1e() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex1n.c b/src/pthread/tests/mutex1n.c new file mode 100644 index 000000000..b0eb5de9f --- /dev/null +++ b/src/pthread/tests/mutex1n.c @@ -0,0 +1,82 @@ +/* + * mutex1n.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_NORMAL. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include +#include +#include "test.h" + +static pthread_mutex_t mutex = NULL; +static pthread_mutexattr_t mxAttr; + +int +pthread_test_mutex1n() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex1r.c b/src/pthread/tests/mutex1r.c new file mode 100644 index 000000000..fb1ae426b --- /dev/null +++ b/src/pthread/tests/mutex1r.c @@ -0,0 +1,83 @@ +/* + * mutex1r.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_RECURSIVE. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex = NULL; +static pthread_mutexattr_t mxAttr; + +int +pthread_test_mutex1r() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex2.c b/src/pthread/tests/mutex2.c new file mode 100644 index 000000000..1ff85ae79 --- /dev/null +++ b/src/pthread/tests/mutex2.c @@ -0,0 +1,77 @@ +/* + * mutex2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +int +pthread_test_mutex2() +{ + mutex = PTHREAD_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex2e.c b/src/pthread/tests/mutex2e.c new file mode 100644 index 000000000..b8087d77b --- /dev/null +++ b/src/pthread/tests/mutex2e.c @@ -0,0 +1,77 @@ +/* + * mutex2e.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +int +pthread_test_mutex2e() +{ + mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex2r.c b/src/pthread/tests/mutex2r.c new file mode 100644 index 000000000..262e0297b --- /dev/null +++ b/src/pthread/tests/mutex2r.c @@ -0,0 +1,77 @@ +/* + * mutex2r.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +int +pthread_test_mutex2r() +{ + mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/src/pthread/tests/mutex3.c b/src/pthread/tests/mutex3.c new file mode 100644 index 000000000..57fc5a8dc --- /dev/null +++ b/src/pthread/tests/mutex3.c @@ -0,0 +1,88 @@ +/* + * mutex3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +pthread_test_mutex3() +{ + pthread_t t; + + mutex1 = PTHREAD_MUTEX_INITIALIZER; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(washere == 1); + + assert(pthread_mutex_destroy(&mutex1) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex3e.c b/src/pthread/tests/mutex3e.c new file mode 100644 index 000000000..9b1bce0f2 --- /dev/null +++ b/src/pthread/tests/mutex3e.c @@ -0,0 +1,89 @@ +/* + * mutex3e.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +pthread_test_mutex3e() +{ + pthread_t t; + + mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(pthread_mutex_destroy(&mutex1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/src/pthread/tests/mutex3r.c b/src/pthread/tests/mutex3r.c new file mode 100644 index 000000000..8610fc4df --- /dev/null +++ b/src/pthread/tests/mutex3r.c @@ -0,0 +1,88 @@ +/* + * mutex3r.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static pthread_mutex_t mutex1 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +pthread_test_mutex3r() +{ + pthread_t t; + + mutex1 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(washere == 1); + + assert(pthread_mutex_destroy(&mutex1) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex4.c b/src/pthread/tests/mutex4.c new file mode 100644 index 000000000..9a723ff84 --- /dev/null +++ b/src/pthread/tests/mutex4.c @@ -0,0 +1,125 @@ +/* + * mutex4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Thread A locks mutex - thread B tries to unlock. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int wasHere = 0; + +static pthread_mutex_t mutex1; + +void * unlocker(void * arg) +{ + int expectedResult = (int) arg; + + wasHere++; + assert(pthread_mutex_unlock(&mutex1) == expectedResult); + wasHere++; + return NULL; +} + +int +pthread_test_mutex4() +{ + pthread_t t; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + /* + * NORMAL (fast) mutexes don't check ownership. + */ + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(wasHere == 2); + assert(pthread_mutex_destroy(&mutex1) == 0); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + /* + * NORMAL (fast) mutexes don't check ownership. + */ + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(wasHere == 2); + assert(pthread_mutex_destroy(&mutex1) == 0); + + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(wasHere == 2); + assert(pthread_mutex_destroy(&mutex1) == 0); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(wasHere == 2); + assert(pthread_mutex_destroy(&mutex1) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex5.c b/src/pthread/tests/mutex5.c new file mode 100644 index 000000000..00dc2a70e --- /dev/null +++ b/src/pthread/tests/mutex5.c @@ -0,0 +1,76 @@ +/* + * mutex5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Confirm the equality/inequality of the various mutex types, + * and the default not-set value. + */ + +#include +#include + +#include "test.h" + +static pthread_mutexattr_t mxAttr; + +/* Prevent optimiser from removing dead or obvious asserts. */ +int _optimiseFoil; +#define FOIL(x) (_optimiseFoil = x) + +int +pthread_test_mutex5() +{ + int mxType = -1; + + assert(FOIL(PTHREAD_MUTEX_DEFAULT) == PTHREAD_MUTEX_NORMAL); + assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_ERRORCHECK); + assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_RECURSIVE); + assert(FOIL(PTHREAD_MUTEX_RECURSIVE) != PTHREAD_MUTEX_ERRORCHECK); + + assert(FOIL(PTHREAD_MUTEX_NORMAL) == PTHREAD_MUTEX_FAST_NP); + assert(FOIL(PTHREAD_MUTEX_RECURSIVE) == PTHREAD_MUTEX_RECURSIVE_NP); + assert(FOIL(PTHREAD_MUTEX_ERRORCHECK) == PTHREAD_MUTEX_ERRORCHECK_NP); + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + return 0; +} diff --git a/src/pthread/tests/mutex6.c b/src/pthread/tests/mutex6.c new file mode 100644 index 000000000..6efc5a9a5 --- /dev/null +++ b/src/pthread/tests/mutex6.c @@ -0,0 +1,108 @@ +/* + * mutex6.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks mutex twice (recursive lock). + * Locking thread should deadlock on second attempt. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "pte_osal.h" + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +pthread_test_mutex6() +{ + pthread_t t; + + lockCount = 0; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + pte_osThreadSleep (1000); + + assert(lockCount == 2); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex6e.c b/src/pthread/tests/mutex6e.c new file mode 100644 index 000000000..5a74a5ed7 --- /dev/null +++ b/src/pthread/tests/mutex6e.c @@ -0,0 +1,109 @@ +/* + * mutex6e.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type. + * Thread locks mutex twice (recursive lock). + * This should fail with an EDEADLK error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == EDEADLK); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +pthread_test_mutex6e() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + lockCount = 0; + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + return 0; +} + diff --git a/src/pthread/tests/mutex6es.c b/src/pthread/tests/mutex6es.c new file mode 100644 index 000000000..a4f98afe2 --- /dev/null +++ b/src/pthread/tests/mutex6es.c @@ -0,0 +1,104 @@ +/* + * mutex6es.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK static mutex type. + * Thread locks mutex twice (recursive lock). + * This should fail with an EDEADLK error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == EDEADLK); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +pthread_test_mutex6es() +{ + pthread_t t; + int result = 0; + + lockCount = 0; + + mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} + diff --git a/src/pthread/tests/mutex6n.c b/src/pthread/tests/mutex6n.c new file mode 100644 index 000000000..289b2c41a --- /dev/null +++ b/src/pthread/tests/mutex6n.c @@ -0,0 +1,121 @@ +/* + * mutex6n.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_NORMAL mutex type. + * Thread locks mutex twice (recursive lock). + * The thread should deadlock. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + +// JNS: Why is this done? The mutex should already +// be unlocked by the main thread, so this call +// will always return EPERM... +// assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +pthread_test_mutex6n() +{ + pthread_t t; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + pte_osThreadSleep (1000); + + assert(lockCount == 2); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} + diff --git a/src/pthread/tests/mutex6r.c b/src/pthread/tests/mutex6r.c new file mode 100644 index 000000000..9733471ef --- /dev/null +++ b/src/pthread/tests/mutex6r.c @@ -0,0 +1,108 @@ +/* + * mutex6r.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type. + * Thread locks mutex twice (recursive lock). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +pthread_test_mutex6r() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex6rs.c b/src/pthread/tests/mutex6rs.c new file mode 100644 index 000000000..3b5639e35 --- /dev/null +++ b/src/pthread/tests/mutex6rs.c @@ -0,0 +1,101 @@ +/* + * mutex6rs.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE static mutex type. + * Thread locks mutex twice (recursive lock). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +pthread_test_mutex6rs() +{ + pthread_t t; + int result = 0; + + lockCount = 0; + mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex6s.c b/src/pthread/tests/mutex6s.c new file mode 100644 index 000000000..84d71774d --- /dev/null +++ b/src/pthread/tests/mutex6s.c @@ -0,0 +1,108 @@ +/* + * mutex6s.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) static mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks mutex twice (recursive lock). + * Locking thread should deadlock on second attempt. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + + return 0; +} + +int +pthread_test_mutex6s() +{ + pthread_t t; + + lockCount = 0; + mutex = PTHREAD_MUTEX_INITIALIZER; + + assert(mutex == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + pte_osThreadSleep (1000); + + assert(lockCount == 2); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex7.c b/src/pthread/tests/mutex7.c new file mode 100644 index 000000000..ceaa4e424 --- /dev/null +++ b/src/pthread/tests/mutex7.c @@ -0,0 +1,95 @@ +/* + * mutex7.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks then trylocks mutex (attempted recursive lock). + * The thread should lock first time and EBUSY second time. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return 0; +} + +int +pthread_test_mutex7() +{ + pthread_t t; + + lockCount = 0; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(1000); + + assert(lockCount == 2); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + /* Never reached */ + return 0; +} diff --git a/src/pthread/tests/mutex7e.c b/src/pthread/tests/mutex7e.c new file mode 100644 index 000000000..572841e7f --- /dev/null +++ b/src/pthread/tests/mutex7e.c @@ -0,0 +1,111 @@ +/* + * mutex7e.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type. + * Thread locks and then trylocks mutex (attempted recursive lock). + * Trylock should fail with an EBUSY error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +pthread_test_mutex7e() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + /* Never reached */ + return 0; +} + diff --git a/src/pthread/tests/mutex7n.c b/src/pthread/tests/mutex7n.c new file mode 100644 index 000000000..ae1a963bd --- /dev/null +++ b/src/pthread/tests/mutex7n.c @@ -0,0 +1,105 @@ +/* + * mutex7n.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_NORMAL mutex type. + * Thread locks then trylocks mutex (attempted recursive lock). + * The thread should lock first time and EBUSY second time. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +pthread_test_mutex7n() +{ + pthread_t t; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(1000); + + assert(lockCount == 2); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + /* Never reached */ + return 0; +} + diff --git a/src/pthread/tests/mutex7r.c b/src/pthread/tests/mutex7r.c new file mode 100644 index 000000000..ab2a070be --- /dev/null +++ b/src/pthread/tests/mutex7r.c @@ -0,0 +1,108 @@ +/* + * mutex7r.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type. + * Thread locks mutex then trylocks mutex (recursive lock twice). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +pthread_test_mutex7r() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex8.c b/src/pthread/tests/mutex8.c new file mode 100644 index 000000000..19e2bab51 --- /dev/null +++ b/src/pthread/tests/mutex8.c @@ -0,0 +1,100 @@ +/* + * mutex8.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Test the default (type not set) mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +static void * locker(void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct timeb currSysTime; + const unsigned long NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + currSysTime.time += 1; // wait for one seconds + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +pthread_test_mutex8() +{ + pthread_t t; + + lockCount = 0; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/src/pthread/tests/mutex8e.c b/src/pthread/tests/mutex8e.c new file mode 100644 index 000000000..7ebd1b6d5 --- /dev/null +++ b/src/pthread/tests/mutex8e.c @@ -0,0 +1,114 @@ +/* + * mutex8e.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned long NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +pthread_test_mutex8e() +{ + pthread_t t; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} + diff --git a/src/pthread/tests/mutex8n.c b/src/pthread/tests/mutex8n.c new file mode 100644 index 000000000..d9aa9bab8 --- /dev/null +++ b/src/pthread/tests/mutex8n.c @@ -0,0 +1,114 @@ +/* + * mutex8n.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Tests PTHREAD_MUTEX_NORMAL mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +pthread_test_mutex8n() +{ + pthread_t t; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} + diff --git a/src/pthread/tests/mutex8r.c b/src/pthread/tests/mutex8r.c new file mode 100644 index 000000000..a1c5968e0 --- /dev/null +++ b/src/pthread/tests/mutex8r.c @@ -0,0 +1,114 @@ +/* + * mutex8r.c + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include +#include + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +static void * locker(void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const unsigned int NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +pthread_test_mutex8r() +{ + pthread_t t; + int mxType = -1; + + lockCount = 0; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} + diff --git a/src/pthread/tests/once1.c b/src/pthread/tests/once1.c new file mode 100644 index 000000000..46aa3d4e0 --- /dev/null +++ b/src/pthread/tests/once1.c @@ -0,0 +1,90 @@ +/* + * once1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a static pthread_once and test that it calls myfunc once. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + */ + +#include "test.h" + +static pthread_once_t once = PTHREAD_ONCE_INIT; + +static int washere = 0; + +static void +myfunc(void) +{ + washere++; +} + +static void * +mythread(void * arg) +{ + assert(pthread_once(&once, myfunc) == 0); + + return 0; +} + +int pthread_test_once1() +{ + pthread_t t1, t2; + pthread_once_t onceinit = PTHREAD_ONCE_INIT; + + washere = 0; + + once = onceinit; + + assert(pthread_create(&t1, NULL, mythread, NULL) == 0); + + assert(pthread_create(&t2, NULL, mythread, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(washere == 1); + + assert(pthread_join(t1,NULL) == 0); + assert(pthread_join(t2,NULL) == 0); + + return 0; +} diff --git a/src/pthread/tests/once2.c b/src/pthread/tests/once2.c new file mode 100644 index 000000000..2ff1a0b74 --- /dev/null +++ b/src/pthread/tests/once2.c @@ -0,0 +1,134 @@ +/* + * once2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create several static pthread_once objects and channel several threads + * through each. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + */ + +#include "test.h" + +#define NUM_THREADS OS_MAX_SIMUL_THREADS / 5 /* Targeting each once control */ +#define NUM_ONCE 5 + + +static pthread_once_t o = PTHREAD_ONCE_INIT; +static pthread_once_t once[NUM_ONCE]; + +typedef struct + { + int i; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t numOnce = {0, 0}; +static sharedInt_t numThreads = {0, 0}; + +static void +myfunc(void) +{ + + pte_osMutexLock(numOnce.cs); + + numOnce.i++; + + pte_osMutexUnlock(numOnce.cs); + + /* Simulate slow once routine so that following threads pile up behind it */ + pte_osThreadSleep(100); +} + +static void * +mythread(void * arg) +{ + + assert(pthread_once(&once[(int) arg], myfunc) == 0); + + pte_osMutexLock(numThreads.cs); + numThreads.i++; + pte_osMutexUnlock(numThreads.cs); + + return 0; +} + +int pthread_test_once2() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + int result; + + numOnce.i = 0; + numThreads.i = 0; + + pte_osMutexCreate(&numThreads.cs); + pte_osMutexCreate(&numOnce.cs); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 0); + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if ((result = pthread_join(t[i][j], NULL)) != 0) + { + assert(0); //Join failed for [thread,once] + } + + /* Stop some compilers from generating warning */ + result = result; + + pte_osThreadSleep(1000); + + assert(numOnce.i == NUM_ONCE); + assert(numThreads.i == NUM_THREADS * NUM_ONCE); + + pte_osMutexDelete(numOnce.cs); + pte_osMutexDelete(numThreads.cs); + + return 0; +} diff --git a/src/pthread/tests/once3.c b/src/pthread/tests/once3.c new file mode 100644 index 000000000..505374c73 --- /dev/null +++ b/src/pthread/tests/once3.c @@ -0,0 +1,151 @@ +/* + * once3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create several pthread_once objects and channel several threads + * through each. Make the init_routine cancelable and cancel them with + * waiters waiting. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + * pthread_testcancel() + * pthread_cancel() + * pthread_once() + */ + +//#define ASSERT_TRACE + +#include "test.h" + +#define NUM_THREADS OS_MAX_SIMUL_THREADS / 5 /* Targeting each once control */ +#define NUM_ONCE 5 + + +static pthread_once_t o = PTHREAD_ONCE_INIT; +static pthread_once_t once[NUM_ONCE]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t numOnce = {0, 0, 0}; +static sharedInt_t numThreads = {0, 0, 0}; + +static void +myfunc(void) +{ + + pte_osMutexLock(numOnce.cs); + numOnce.i++; + assert(numOnce.i > 0); + pte_osMutexUnlock(numOnce.cs); + + /* Simulate slow once routine so that following threads pile up behind it */ + pte_osThreadSleep(10); + /* test for cancelation late so we're sure to have waiters. */ + pthread_testcancel(); +} + +static void * +mythread(void * arg) +{ + + /* + * Cancel every thread. These threads are deferred cancelable only, so + * only the thread performing the once routine (my_func) will see it (there are + * no other cancelation points here). The result will be that every thread + * eventually cancels only when it becomes the new once thread. + */ + assert(pthread_cancel(pthread_self()) == 0); + assert(pthread_once(&once[(int) arg], myfunc) == 0); + pte_osMutexLock(numThreads.cs); + numThreads.i++; + pte_osMutexUnlock(numThreads.cs); + + return 0; +} + +int pthread_test_once3() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + pthread_once_t onceinit = PTHREAD_ONCE_INIT; + + numOnce.i = 0; + numThreads.i = 0; + + o = onceinit; + + pte_osMutexCreate(&numThreads.cs); + pte_osMutexCreate(&numOnce.cs); + + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + { + assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 0); + } + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if (pthread_join(t[i][j], NULL) != 0) + assert(0); // Join failed for [thread,once] + + /* + * All threads will cancel, none will return normally from + * pthread_once and so numThreads should never be incremented. However, + * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE). + */ + assert(numOnce.i == NUM_ONCE * NUM_THREADS); + assert(numThreads.i == 0); + + pte_osMutexDelete(numOnce.cs); + pte_osMutexDelete(numThreads.cs); + + return 0; +} diff --git a/src/pthread/tests/once4.c b/src/pthread/tests/once4.c new file mode 100644 index 000000000..027bdaa2b --- /dev/null +++ b/src/pthread/tests/once4.c @@ -0,0 +1,188 @@ +/* + * once4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create several pthread_once objects and channel several threads + * through each. Make the init_routine cancelable and cancel them + * waiters waiting. Vary the priorities. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + * pthread_testcancel() + * pthread_cancel() + * pthread_once() + */ + +#include "test.h" + +#define NUM_THREADS OS_MAX_SIMUL_THREADS / 5 /* Targeting each once control */ +#define NUM_ONCE 5 + +static pthread_once_t o = PTHREAD_ONCE_INIT; +static pthread_once_t once[NUM_ONCE]; + +typedef struct + { + int i; + int null; + pte_osMutexHandle cs; + } sharedInt_t; + +static sharedInt_t numOnce = {0, 0}; +static sharedInt_t numThreads = {0, 0}; + +typedef struct + { + int threadnum; + int oncenum; + int myPrio; +// HANDLE w32Thread; + } bag_t; + +static bag_t threadbag[NUM_THREADS][NUM_ONCE]; + +//static CRITICAL_SECTION print_lock; + +static void +mycleanupfunc(void * arg) +{ + +} + +static void +myinitfunc(void) +{ + + pte_osMutexLock(numOnce.cs); + numOnce.i++; + pte_osMutexUnlock(numOnce.cs); + + /* Simulate slow once routine so that following threads pile up behind it */ + pte_osThreadSleep(10); + /* test for cancelation late so we're sure to have waiters. */ + pthread_testcancel(); +} + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + struct sched_param param; + + /* + * Cancel every thread. These threads are deferred cancelable only, so + * only the thread performing the init_routine will see it (there are + * no other cancelation points here). The result will be that every thread + * eventually cancels only when it becomes the new initter. + */ + pthread_t self = pthread_self(); +// bag->w32Thread = pthread_getw32threadhandle_np(self); + /* + * Set priority between -2 and 2 inclusive. + */ + bag->myPrio = (bag->threadnum % 5) - 2; + param.sched_priority = bag->myPrio; + pthread_setschedparam(self, SCHED_OTHER, ¶m); + + /* Trigger a cancellation at the next cancellation point in this thread */ + pthread_cancel(self); + pthread_cleanup_push(mycleanupfunc, arg); + assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0); + pthread_cleanup_pop(1); + + pte_osMutexLock(numThreads.cs); + numThreads.i++; + pte_osMutexUnlock(numThreads.cs); + return 0; +} + +int pthread_test_once4() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + + numOnce.i = 0; + numThreads.i = 0; + +// pte_osMutexCreate(&print_lock); +// pte_osMutexCreate(&numThreads.cs); +// pte_osMutexCreate(&numOnce.cs); + + /* + * Set the priority class to realtime - otherwise normal + * Windows random priority boosting will obscure any problems. + */ + //SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + /* Set main thread to lower prio than threads */ + //SetThreadPriority(GetCurrentThread(), -2); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + { + bag_t * bag = &threadbag[i][j]; + bag->threadnum = i; + bag->oncenum = j; + assert(pthread_create(&t[i][j], NULL, mythread, (void *) bag) == 0); + } + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if (pthread_join(t[i][j], NULL) != 0) + assert(0); //Join failed for [thread,once] + + /* + * All threads will cancel, none will return normally from + * pthread_once and so numThreads should never be incremented. However, + * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE). + */ + assert(numOnce.i == NUM_ONCE * NUM_THREADS); + assert(numThreads.i == 0); + +// pte_osMutexDelete(&numOnce.cs); +// pte_osMutexDelete(&numThreads.cs); +// pte_osMutexDelete(&print_lock); + + return 0; +} diff --git a/src/pthread/tests/priority1.c b/src/pthread/tests/priority1.c new file mode 100644 index 000000000..6360f656e --- /dev/null +++ b/src/pthread/tests/priority1.c @@ -0,0 +1,131 @@ +/* + * File: priority1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority explicit setting using thread attribute. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +/* +static int minPrio; +static int maxPrio; +static int validPriorities[PTW32TEST_MAXPRIORITIES]; +*/ + +static int pthreadPrio; + +static void * +func(void * arg) +{ + int policy; + struct sched_param param; + pthread_t threadID = pthread_self(); + + assert(pthread_getschedparam(threadID, &policy, ¶m) == 0); + assert(policy == SCHED_OTHER); + assert(param.sched_priority == (int) pthreadPrio); + + assert(pte_osThreadGetPriority(pte_osThreadGetHandle()) == param.sched_priority); + + + return (void *) 0; +} + +int pthread_test_priority1() +{ + pthread_t t; + pthread_attr_t attr; + void * result = NULL; + struct sched_param param; + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0); + + param.sched_priority = sched_get_priority_min(SCHED_OTHER) + 1; + pthreadPrio = sched_get_priority_min(SCHED_OTHER) + 1; + assert(pthread_attr_setschedparam(&attr, ¶m) == 0); + + assert(pthread_create(&t, &attr, func, (void *) &attr) == 0); + assert(pthread_join(t, &result) == 0); + + return 0; +} diff --git a/src/pthread/tests/priority2.c b/src/pthread/tests/priority2.c new file mode 100644 index 000000000..805cf55b4 --- /dev/null +++ b/src/pthread/tests/priority2.c @@ -0,0 +1,156 @@ +/* + * File: priority2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority setting after creation. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +static pthread_barrier_t startBarrier, endBarrier; + +static void * func(void * arg) +{ + int policy; + int result; + struct sched_param param; + + result = pthread_barrier_wait(&startBarrier); + assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD); + assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); + assert(policy == SCHED_OTHER); + result = pthread_barrier_wait(&endBarrier); + assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD); + + assert(pte_osThreadGetPriority(pte_osThreadGetHandle()) == param.sched_priority); + + return (void *) param.sched_priority; +} + + + +int pthread_test_priority2() +{ + pthread_t t; + void * result = NULL; + int result2; + struct sched_param param; + + + /* + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + */ + + assert(pthread_barrier_init(&startBarrier, NULL, 2) == 0); + assert(pthread_barrier_init(&endBarrier, NULL, 2) == 0); + + /* Set the thread's priority to a known initial value. + * If the new priority is invalid then the threads priority + * is unchanged from the previous value. + */ + /* + SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()), + PTW32TEST_THREAD_INIT_PRIO); + */ + for (param.sched_priority = pte_osThreadGetMinPriority(); + param.sched_priority <= pte_osThreadGetMaxPriority(); + param.sched_priority++) + { + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_setschedparam(t, SCHED_OTHER, ¶m) == 0); + result2 = pthread_barrier_wait(&startBarrier); + assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD); + result2 = pthread_barrier_wait(&endBarrier); + assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD); + +// assert(GetThreadPriority(pthread_getw32threadhandle_np(t)) == +// validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); + + pthread_join(t, &result); + assert(param.sched_priority == (int)result); + } + + assert(pthread_barrier_destroy(&startBarrier) == 0); + assert(pthread_barrier_destroy(&endBarrier) == 0); + + return 0; +} diff --git a/src/pthread/tests/reuse1.c b/src/pthread/tests/reuse1.c new file mode 100644 index 000000000..ee977a688 --- /dev/null +++ b/src/pthread/tests/reuse1.c @@ -0,0 +1,130 @@ +/* + * File: reuse1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Confirm that thread reuse works for joined threads. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + NUMTHREADS = 50 +}; + +static int washere = 0; + +static void * func(void * arg) +{ + washere = 1; + return arg; +} + +int pthread_test_reuse1() +{ + pthread_t t, + last_t; + pthread_attr_t attr; + void * result = NULL; + int i; + + assert(pthread_attr_init(&attr) == 0);; + assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0); + + washere = 0; + assert(pthread_create(&t, &attr, func, NULL) == 0); + assert(pthread_join(t, &result) == 0);; + assert(result == 0); + assert(washere == 1); + last_t = t; + + for (i = 1; i < NUMTHREADS; i++) + { + washere = 0; + assert(pthread_create(&t, &attr, func, (void *) i) == 0); + pthread_join(t, &result); + assert((int) result == i); + assert(washere == 1); + /* thread IDs should be unique */ + assert(!pthread_equal(t, last_t)); + /* thread struct pointers should be the same */ + assert(t.p == last_t.p); + /* thread handle reuse counter should be different by one */ + assert(t.x == last_t.x+1); + last_t = t; + } + + return 0; +} diff --git a/src/pthread/tests/reuse2.c b/src/pthread/tests/reuse2.c new file mode 100644 index 000000000..340b632b5 --- /dev/null +++ b/src/pthread/tests/reuse2.c @@ -0,0 +1,170 @@ +/* + * File: reuse2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that thread reuse works for detached threads. + * - Analyse thread struct reuse. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - This test is implementation specific + * because it uses knowledge of internals that should be + * opaque to an application. + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#include "implement.h" + +/* + */ + +enum +{ + NUMTHREADS = 100 +}; + + +static int done = 0; + +static void * func(void * arg) +{ + sched_yield(); + + PTE_ATOMIC_INCREMENT(&done); + + return (void *) 0; +} + +int pthread_test_reuse2() +{ + pthread_t t[NUMTHREADS]; + pthread_attr_t attr; + int i; + unsigned int notUnique = 0, + totalHandles = 0, + reuseMax = 0, + reuseMin = NUMTHREADS; + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&t[i], &attr, func, NULL) == 0); + } + + while (NUMTHREADS > PTE_ATOMIC_EXCHANGE_ADD(&done, 0L)) + pte_osThreadSleep(100); + + pte_osThreadSleep(100); + + /* + * Analyse reuse by computing min and max number of times pthread_create() + * returned the same pthread_t value. + */ + for (i = 0; i < NUMTHREADS; i++) + { + if (t[i].p != NULL) + { + unsigned int j, thisMax; + + thisMax = t[i].x; + + for (j = i+1; j < NUMTHREADS; j++) + if (t[i].p == t[j].p) + { + if (t[i].x == t[j].x) + notUnique++; + if (thisMax < t[j].x) + thisMax = t[j].x; + t[j].p = NULL; + } + + if (reuseMin > thisMax) + reuseMin = thisMax; + + if (reuseMax < thisMax) + reuseMax = thisMax; + } + } + + for (i = 0; i < NUMTHREADS; i++) + if (t[i].p != NULL) + totalHandles++; + + /* + * pthread_t reuse counts start at 0, so we need to add 1 + * to the max and min values derived above. + */ + + return 0; +} diff --git a/src/pthread/tests/rwlock1.c b/src/pthread/tests/rwlock1.c new file mode 100644 index 000000000..f8739cc18 --- /dev/null +++ b/src/pthread/tests/rwlock1.c @@ -0,0 +1,68 @@ +/* + * rwlock1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a simple rwlock object and then destroy it. + * + * Depends on API functions: + * pthread_rwlock_init() + * pthread_rwlock_destroy() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock = NULL; + +int pthread_test_rwlock1() +{ + rwlock = NULL; + + assert(rwlock == NULL); + + assert(pthread_rwlock_init(&rwlock, NULL) == 0); + + assert(rwlock != NULL); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/src/pthread/tests/rwlock2.c b/src/pthread/tests/rwlock2.c new file mode 100644 index 000000000..7f9c829a9 --- /dev/null +++ b/src/pthread/tests/rwlock2.c @@ -0,0 +1,73 @@ +/* + * rwlock2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + +int pthread_test_rwlock2() +{ + rwlock = PTHREAD_RWLOCK_INITIALIZER; + + assert(rwlock == PTHREAD_RWLOCK_INITIALIZER); + + assert(pthread_rwlock_rdlock(&rwlock) == 0); + + assert(rwlock != PTHREAD_RWLOCK_INITIALIZER); + + assert(rwlock != NULL); + + assert(pthread_rwlock_unlock(&rwlock) == 0); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/src/pthread/tests/rwlock2_t.c b/src/pthread/tests/rwlock2_t.c new file mode 100644 index 000000000..2ed6edce6 --- /dev/null +++ b/src/pthread/tests/rwlock2_t.c @@ -0,0 +1,87 @@ +/* + * rwlock2_t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + +int pthread_test_rwlock2t() +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + rwlock = PTHREAD_RWLOCK_INITIALIZER; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(rwlock == PTHREAD_RWLOCK_INITIALIZER); + + assert(pthread_rwlock_timedrdlock(&rwlock, &abstime) == 0); + + assert(rwlock != PTHREAD_RWLOCK_INITIALIZER); + + assert(rwlock != NULL); + + assert(pthread_rwlock_unlock(&rwlock) == 0); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/src/pthread/tests/rwlock3.c b/src/pthread/tests/rwlock3.c new file mode 100644 index 000000000..ae793210c --- /dev/null +++ b/src/pthread/tests/rwlock3.c @@ -0,0 +1,87 @@ +/* + * rwlock3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, wrlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_wrlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock3() +{ + pthread_t t; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t, NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock3_t.c b/src/pthread/tests/rwlock3_t.c new file mode 100644 index 000000000..4c94d2bff --- /dev/null +++ b/src/pthread/tests/rwlock3_t.c @@ -0,0 +1,100 @@ +/* + * rwlock3_t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-wrlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedwrlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock3t() +{ + pthread_t t; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedwrlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock4.c b/src/pthread/tests/rwlock4.c new file mode 100644 index 000000000..b9c39051f --- /dev/null +++ b/src/pthread/tests/rwlock4.c @@ -0,0 +1,87 @@ +/* + * rwlock4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock4() +{ + pthread_t t; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock4_t.c b/src/pthread/tests/rwlock4_t.c new file mode 100644 index 000000000..ace7f5b01 --- /dev/null +++ b/src/pthread/tests/rwlock4_t.c @@ -0,0 +1,100 @@ +/* + * rwlock4_t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-rdlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock4t() +{ + pthread_t t; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock5.c b/src/pthread/tests/rwlock5.c new file mode 100644 index 000000000..b19142df9 --- /dev/null +++ b/src/pthread/tests/rwlock5.c @@ -0,0 +1,89 @@ +/* + * rwlock5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, tryrdlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_tryrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_tryrdlock(&rwlock1) == 0); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock5() +{ + pthread_t t; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock5_t.c b/src/pthread/tests/rwlock5_t.c new file mode 100644 index 000000000..53c7a84d7 --- /dev/null +++ b/src/pthread/tests/rwlock5_t.c @@ -0,0 +1,105 @@ +/* + * rwlock5_t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-rdlock it, tryrdlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_tryrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_rwlock_tryrdlock(&rwlock1) == 0); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + washere = 1; + + return 0; +} + +int pthread_test_rwlock5t() +{ + pthread_t t; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + washere = 0; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + pte_osThreadSleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + assert(pthread_join(t,NULL) == 0); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock6.c b/src/pthread/tests/rwlock6.c new file mode 100644 index 000000000..2ab1595d5 --- /dev/null +++ b/src/pthread/tests/rwlock6.c @@ -0,0 +1,110 @@ +/* + * rwlock6.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Check writer and reader locking + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_wrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; + +static void * wrfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + pte_osThreadSleep(2000); + bankAccount += 10; + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +static void * rdfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +int pthread_test_rwlock6() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt; + int wr1Result = 0; + int wr2Result = 0; + int rdResult = 0; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); + pte_osThreadSleep(500); + assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); + pte_osThreadSleep(500); + assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt, (void **) &rdResult) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + + assert(wr1Result == 10); + assert(rdResult == 10); + assert(wr2Result == 20); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock6_t.c b/src/pthread/tests/rwlock6_t.c new file mode 100644 index 000000000..cf928280c --- /dev/null +++ b/src/pthread/tests/rwlock6_t.c @@ -0,0 +1,137 @@ +/* + * rwlock6_t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Check writer and reader locking with reader timeouts + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_wrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; + +static void * wrfunc(void * arg) +{ + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + pte_osThreadSleep(2000); + bankAccount += 10; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) bankAccount); +} + +static void * rdfunc(void * arg) +{ + int ba = -1; + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + + if ((int) arg == 1) + { + abstime.tv_sec += 1; + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); + ba = 0; + } + else if ((int) arg == 2) + { + abstime.tv_sec += 3; + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + } + + return ((void *) ba); +} + +int pthread_test_rwlock6t() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt1; + pthread_t rdt2; + int wr1Result = 0; + int wr2Result = 0; + int rd1Result = 0; + int rd2Result = 0; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); + pte_osThreadSleep(500); + assert(pthread_create(&rdt1, NULL, rdfunc, (void *) 1) == 0); + pte_osThreadSleep(500); + assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); + pte_osThreadSleep(500); + assert(pthread_create(&rdt2, NULL, rdfunc, (void *) 2) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt1, (void **) &rd1Result) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + assert(pthread_join(rdt2, (void **) &rd2Result) == 0); + + assert(wr1Result == 10); + assert(rd1Result == 0); + assert(wr2Result == 20); + assert(rd2Result == 20); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} + + diff --git a/src/pthread/tests/rwlock6_t2.c b/src/pthread/tests/rwlock6_t2.c new file mode 100644 index 000000000..916c4c54a --- /dev/null +++ b/src/pthread/tests/rwlock6_t2.c @@ -0,0 +1,131 @@ +/* + * rwlock6_t2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Check writer and reader timeouts. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_timedwrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; +struct timespec abstime = + { + 0, 0 + }; + +static void * wrfunc(void * arg) +{ + int result; + + result = pthread_rwlock_timedwrlock(&rwlock1, &abstime); + if ((int) arg == 1) + { + assert(result == 0); + pte_osThreadSleep(2000); + bankAccount += 10; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + return ((void *) bankAccount); + } + else if ((int) arg == 2) + { + assert(result == ETIMEDOUT); + return ((void *) 100); + } + + return ((void *) -1); +} + +static void * rdfunc(void * arg) +{ + int ba = 0; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); + + return ((void *) ba); +} + +int pthread_test_rwlock6t2() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt; + int wr1Result = 0; + int wr2Result = 0; + int rdResult = 0; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, (void *) 1) == 0); + pte_osThreadSleep(100); + assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); + pte_osThreadSleep(100); + assert(pthread_create(&wrt2, NULL, wrfunc, (void *) 2) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt, (void **) &rdResult) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + + assert(wr1Result == 10); + assert(rdResult == 0); + assert(wr2Result == 100); + + assert(pthread_rwlock_destroy(&rwlock1) == 0); + + return 0; +} diff --git a/src/pthread/tests/rwlock7.c b/src/pthread/tests/rwlock7.c new file mode 100644 index 000000000..473883639 --- /dev/null +++ b/src/pthread/tests/rwlock7.c @@ -0,0 +1,188 @@ +/* + * rwlock7.c + * + * Hammer on a bunch of rwlocks to test robustness and fairness. + * Printed stats should be roughly even for each thread. + */ + +#include "test.h" + +#ifdef __GNUC__ +#include +#endif + +#define THREADS 5 +#define DATASIZE 7 +#define ITERATIONS 100000 + +/* + * Keep statistics for each thread. + */ +typedef struct thread_tag + { + int thread_num; + pthread_t thread_id; + int updates; + int reads; + int changed; + unsigned int seed; + } thread_t; + +/* + * Read-write lock and shared data + */ +typedef struct data_tag + { + pthread_rwlock_t lock; + int data; + int updates; + } data_t; + +static thread_t threads[THREADS]; +static data_t data[DATASIZE]; + +/* + * Thread start routine that uses read-write locks + */ +static void *thread_routine (void *arg) +{ + thread_t *self = (thread_t*)arg; + int iteration; + int element = 0; + int interval = 1 + rand() % 71; + + self->changed = 0; + + for (iteration = 0; iteration < ITERATIONS; iteration++) + { + /* + if (iteration % (ITERATIONS / 10) == 0) + { + putchar('.'); + fflush(stdout); + } + */ + /* + * Each "self->interval" iterations, perform an + * update operation (write lock instead of read + * lock). + */ + if ((iteration % interval) == 0) + { + assert(pthread_rwlock_wrlock (&data[element].lock) == 0); + data[element].data = self->thread_num; + data[element].updates++; + self->updates++; + interval = 1 + rand () % 71; + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + else + { + /* + * Look at the current data element to see whether + * the current thread last updated it. Count the + * times, to report later. + */ + assert(pthread_rwlock_rdlock (&data[element].lock) == 0); + + self->reads++; + + if (data[element].data != self->thread_num) + { + self->changed++; + interval = 1 + self->changed % 71; + } + + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + + element = (element + 1) % DATASIZE; + + } + + return NULL; +} + +int pthread_test_rwlock7() +{ + int count; + int data_count; + int thread_updates = 0; + int data_updates = 0; + + struct _timeb currSysTime1; + struct _timeb currSysTime2; + + /* + * Initialize the shared data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data[data_count].data = 0; + data[data_count].updates = 0; + + assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); + } + + _ftime(&currSysTime1); + + /* + * Create THREADS threads to access shared data. + */ + for (count = 0; count < THREADS; count++) + { + threads[count].thread_num = count; + threads[count].updates = 0; + threads[count].reads = 0; + threads[count].seed = 1 + rand() % 71; + + assert(pthread_create (&threads[count].thread_id, + NULL, thread_routine, (void*)&threads[count]) == 0); + } + + /* + * Wait for all threads to complete, and collect + * statistics. + */ + for (count = 0; count < THREADS; count++) + { + assert(pthread_join (threads[count].thread_id, NULL) == 0); + } + + /* + putchar('\n'); + fflush(stdout); + */ + + for (count = 0; count < THREADS; count++) + { + } + + /* + putchar('\n'); + fflush(stdout); + */ + + for (count = 0; count < THREADS; count++) + { + thread_updates += threads[count].updates; + } + + /* + putchar('\n'); + fflush(stdout); + */ + + /* + * Collect statistics for the data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data_updates += data[data_count].updates; + assert(pthread_rwlock_destroy (&data[data_count].lock) == 0); + } + + _ftime(&currSysTime2); + + return 0; +} diff --git a/src/pthread/tests/rwlock8.c b/src/pthread/tests/rwlock8.c new file mode 100644 index 000000000..d2990b0fe --- /dev/null +++ b/src/pthread/tests/rwlock8.c @@ -0,0 +1,178 @@ +/* + * rwlock8.c + * + * Hammer on a bunch of rwlocks to test robustness and fairness. + * Printed stats should be roughly even for each thread. + * + * Yield during each access to exercise lock contention code paths + * more than rwlock7.c does (particularly on uni-processor systems). + */ + +#include "test.h" + +#ifdef __GNUC__ +#include +#endif + +#define THREADS 5 +#define DATASIZE 7 +#define ITERATIONS 10000 + +/* + * Keep statistics for each thread. + */ +typedef struct thread_tag + { + int thread_num; + pthread_t thread_id; + int updates; + int reads; + int changed; + unsigned int seed; + } thread_t; + +/* + * Read-write lock and shared data + */ +typedef struct data_tag + { + pthread_rwlock_t lock; + int data; + int updates; + } data_t; + +static thread_t threads[THREADS]; +static data_t data[DATASIZE]; + +/* + * Thread start routine that uses read-write locks + */ +static void *thread_routine (void *arg) +{ + thread_t *self = (thread_t*)arg; + int iteration; + int element = 0; + int interval = 1 + rand() % 71; + + self->changed = 0; + + for (iteration = 0; iteration < ITERATIONS; iteration++) + { + /* + if (iteration % (ITERATIONS / 10) == 0) + { + putchar('.'); + fflush(stdout); + } + */ + /* + * Each "self->interval" iterations, perform an + * update operation (write lock instead of read + * lock). + */ + if ((iteration % interval) == 0) + { + assert(pthread_rwlock_wrlock (&data[element].lock) == 0); + data[element].data = self->thread_num; + data[element].updates++; + self->updates++; + interval = 1 + rand() % 71; + sched_yield(); + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + else + { + /* + * Look at the current data element to see whether + * the current thread last updated it. Count the + * times, to report later. + */ + assert(pthread_rwlock_rdlock (&data[element].lock) == 0); + + self->reads++; + + if (data[element].data != self->thread_num) + { + self->changed++; + interval = 1 + self->changed % 71; + } + + sched_yield(); + + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + + element = (element + 1) % DATASIZE; + + } + + return NULL; +} + +int pthread_test_rwlock8() +{ + int count; + int data_count; + int thread_updates = 0; + int data_updates = 0; + + struct _timeb currSysTime1; + struct _timeb currSysTime2; + + /* + * Initialize the shared data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data[data_count].data = 0; + data[data_count].updates = 0; + + assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); + } + + _ftime(&currSysTime1); + + /* + * Create THREADS threads to access shared data. + */ + for (count = 0; count < THREADS; count++) + { + threads[count].thread_num = count; + threads[count].updates = 0; + threads[count].reads = 0; + threads[count].seed = 1 + rand() % 71; + + assert(pthread_create (&threads[count].thread_id, + NULL, thread_routine, (void*)&threads[count]) == 0); + } + + /* + * Wait for all threads to complete, and collect + * statistics. + */ + for (count = 0; count < THREADS; count++) + { + assert(pthread_join (threads[count].thread_id, NULL) == 0); + } + for (count = 0; count < THREADS; count++) + { + thread_updates += threads[count].updates; + } + /* + putchar('\n'); + fflush(stdout); + */ + + /* + * Collect statistics for the data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data_updates += data[data_count].updates; + assert(pthread_rwlock_destroy (&data[data_count].lock) == 0); + } + + _ftime(&currSysTime2); + + return 0; +} diff --git a/src/pthread/tests/self1.c b/src/pthread/tests/self1.c new file mode 100644 index 000000000..624260271 --- /dev/null +++ b/src/pthread/tests/self1.c @@ -0,0 +1,76 @@ +/* + * self1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test for pthread_self(). + * + * Depends on API functions: + * pthread_self() + * + * Implicitly depends on: + * pthread_getspecific() + * pthread_setspecific() + */ + +#include + +#include "test.h" + +int pthread_test_self1() +{ + /* + * This should always succeed unless the system has no + * resources (memory) left. + */ + pthread_t self; + +#ifdef PTW32_STATIC_LIB +// pthread_win32_process_attach_np(); +#endif + + self = pthread_self(); + + assert(self.p != NULL); + +#ifdef PTW32_STATIC_LIB +// pthread_win32_process_detach_np(); +#endif + return 0; +} diff --git a/src/pthread/tests/self2.c b/src/pthread/tests/self2.c new file mode 100644 index 000000000..cff41175b --- /dev/null +++ b/src/pthread/tests/self2.c @@ -0,0 +1,83 @@ +/* + * self2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test for pthread_self(). + * + * Depends on API functions: + * pthread_create() + * pthread_self() + * + * Implicitly depends on: + * pthread_getspecific() + * pthread_setspecific() + */ + +#include +#include + +#include "test.h" +//#include + +static pthread_t me; + +static void * +entry(void * arg) +{ + me = pthread_self(); + + return arg; +} + +int pthread_test_self2() +{ + pthread_t t; + + assert(pthread_create(&t, NULL, entry, NULL) == 0); + + pte_osThreadSleep(100); + + assert(pthread_equal(t, me) != 0); + + assert(pthread_join(t,NULL) == 0); + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/semaphore1.c b/src/pthread/tests/semaphore1.c new file mode 100644 index 000000000..3dd85ee45 --- /dev/null +++ b/src/pthread/tests/semaphore1.c @@ -0,0 +1,139 @@ +/* + * File: semaphore1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +static void * +thr(void * arg) +{ + sem_t s; + int result; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + + assert((result = sem_trywait(&s)) == -1); + + if ( result == -1 ) + { + int err = errno; + assert(err == EAGAIN); + } + + assert((result = sem_post(&s)) == 0); + + assert((result = sem_trywait(&s)) == 0); + + assert(sem_post(&s) == 0); + + assert(sem_destroy(&s) == 0); + + return 0; +} + + +int pthread_test_semaphore1(void) +{ + pthread_t t; + sem_t s; + int result; + + assert(pthread_create(&t, NULL, thr, NULL) == 0); + assert(pthread_join(t, (void **)&result) == 0); + assert(result == 0); + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + + assert((result = sem_trywait(&s)) == -1); + + if ( result == -1 ) + { + int err = errno; + assert(err == EAGAIN); + } + + assert((result = sem_post(&s)) == 0); + + assert((result = sem_trywait(&s)) == 0); + + assert(sem_post(&s) == 0); + + assert(sem_destroy(&s) == 0); + return 0; +} + diff --git a/src/pthread/tests/semaphore2.c b/src/pthread/tests/semaphore2.c new file mode 100644 index 000000000..a9c622ee8 --- /dev/null +++ b/src/pthread/tests/semaphore2.c @@ -0,0 +1,112 @@ +/* + * File: semaphore2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct value. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 100 + +int pthread_test_semaphore2(void) +{ + sem_t s; + int value = 0; + int i; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, MAX_COUNT) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == MAX_COUNT); + + for (i = MAX_COUNT - 1; i >= 0; i--) + { + assert(sem_wait(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == i); + } + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == i); + } + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/semaphore3.c b/src/pthread/tests/semaphore3.c new file mode 100644 index 000000000..3b5e619f4 --- /dev/null +++ b/src/pthread/tests/semaphore3.c @@ -0,0 +1,129 @@ +/* + * File: semaphore3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 5 + +static sem_t s; + +static void * +thr (void * arg) +{ + assert(sem_wait(&s) == 0); + assert(pthread_detach(pthread_self()) == 0); + return NULL; +} + +int pthread_test_semaphore3(void) +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, NULL) == 0); + do + { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } + while (value != -i); + assert(-value == i); + } + + for (i = MAX_COUNT - 1; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(-value == i); + } + + pte_osThreadSleep(1000); + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/semaphore4.c b/src/pthread/tests/semaphore4.c new file mode 100644 index 000000000..753042432 --- /dev/null +++ b/src/pthread/tests/semaphore4.c @@ -0,0 +1,162 @@ +/* + * File: semaphore4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters + * after threads are cancelled. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include +#include + +#define MAX_COUNT OS_MAX_SIMUL_THREADS + +static sem_t s; + +static void * +thr (void * arg) +{ + + if ((int) arg == 5) + { + // We expect this thread to be cancelled, + // so sem_wait should return EINTR. + assert(sem_wait(&s) == -1); + assert(errno == EINTR); + } + else + { + // Should exit normally + assert(sem_wait(&s) == 0); + } + + return NULL; +} + +int pthread_test_semaphore4(void) +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, (void *)i) == 0); + do + { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } + while (value != -i); + + assert(-value == i); + } + + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT); + + assert(pthread_cancel(t[5]) == 0); + { + int result; + assert(pthread_join(t[5], (void **) &result) == 0); + } + assert(sem_getvalue(&s, &value) == 0); + + assert(-value == (MAX_COUNT - 1)); + + for (i = MAX_COUNT - 2; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(-value == i); + } + + + for (i = 1; i <= MAX_COUNT; i++) + { + if (i != 5) + assert(pthread_join(t[i], NULL) == 0); + } + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/semaphore4t.c b/src/pthread/tests/semaphore4t.c new file mode 100644 index 000000000..9f44ebbd2 --- /dev/null +++ b/src/pthread/tests/semaphore4t.c @@ -0,0 +1,151 @@ +/* + * File: semaphore4t.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters + * after threads are cancelled. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - sem_timedwait cancellation. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT OS_MAX_SIMUL_THREADS + +static sem_t s; + +static void * +thr (void * arg) +{ + if ((int) arg == 5) + { + // We expect this thread to be cancelled, + // so sem_wait should return EINTR. + assert(sem_timedwait(&s,NULL) == -1); + assert(errno == EINTR); + } + else + { + assert(sem_timedwait(&s,NULL) == 0); + } + + return NULL; +} + +int pthread_test_semaphore4t(void) +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, (void *) i) == 0); + do + { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } + while (value != -i); + assert(-value == i); + } + + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT); + assert(pthread_cancel(t[5]) == 0); + assert(pthread_join(t[5], NULL) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT - 1); + + for (i = MAX_COUNT - 2; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(-value == i); + } + + for (i = 1; i <= MAX_COUNT; i++) + { + if (i != 5) + assert(pthread_join(t[i], NULL) == 0); + } + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/semaphore5.c b/src/pthread/tests/semaphore5.c new file mode 100644 index 000000000..e7348b37e --- /dev/null +++ b/src/pthread/tests/semaphore5.c @@ -0,0 +1,111 @@ +/* + * File: semaphore5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verifies that sem_timedwait returns after timeout. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +static sem_t s; + +static void * +thr (void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + assert(sem_timedwait(&s, &abstime) == -1); + assert(errno == ETIMEDOUT); + + return NULL; +} + +int pthread_test_semaphore5(void) +{ + int value = 0; + pthread_t handle; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == 0); + + + assert(pthread_create(&handle, NULL, thr, NULL) == 0); + + assert(pthread_join(handle, NULL) == 0); + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/semaphore6.c b/src/pthread/tests/semaphore6.c new file mode 100644 index 000000000..75a7982c0 --- /dev/null +++ b/src/pthread/tests/semaphore6.c @@ -0,0 +1,121 @@ +/* + * File: semaphore5.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verifies that sem_timedwait doesn't return before timeout + * expires + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +static sem_t s; +static int semStatus; + +static void * +thr (void * arg) +{ + struct timespec abstime = + { + 0, 0 + }; + struct _timeb currSysTime; + const long long NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + assert(sem_timedwait(&s, &abstime) == -1); + assert(errno == ETIMEDOUT); + + semStatus = 1; + // assert(pthread_detach(pthread_self()) == 0); + return NULL; +} + +int pthread_test_semaphore6(void) +{ + int value = 0; + pthread_t handle; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == 0); + + semStatus = 0; + + assert(pthread_create(&handle, NULL, thr, NULL) == 0); + + pte_osThreadSleep(3000); + + /* Make sure that sem_timedwait doesn't return too early */ + assert(semStatus == 0); + + assert(pthread_join(handle, NULL) == 0); + + assert(sem_destroy(&s) == 0); + + return 0; +} + diff --git a/src/pthread/tests/spin1.c b/src/pthread/tests/spin1.c new file mode 100644 index 000000000..c400147e6 --- /dev/null +++ b/src/pthread/tests/spin1.c @@ -0,0 +1,64 @@ +/* + * spin1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a simple spinlock object, lock it, and then unlock it again. + * This is the simplest test of the pthread mutex family that we can do. + * + */ + +#include "test.h" + +static pthread_spinlock_t lock; + +int pthread_test_spin1() +{ + assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0); + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(pthread_spin_lock(&lock) == EINVAL); + + return 0; +} diff --git a/src/pthread/tests/spin2.c b/src/pthread/tests/spin2.c new file mode 100644 index 000000000..e412a386b --- /dev/null +++ b/src/pthread/tests/spin2.c @@ -0,0 +1,80 @@ +/* + * spin2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a spinlock object, lock it, trylock it, + * and then unlock it again. + * + */ + +#include "test.h" + +static pthread_spinlock_t lock = NULL; + +static int washere = 0; + +static void * func(void * arg) +{ + assert(pthread_spin_trylock(&lock) == EBUSY); + + washere = 1; + + return 0; +} + +int pthread_test_spin2() +{ + pthread_t t; + + assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0); + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/src/pthread/tests/spin3.c b/src/pthread/tests/spin3.c new file mode 100644 index 000000000..4acf1a06a --- /dev/null +++ b/src/pthread/tests/spin3.c @@ -0,0 +1,77 @@ +/* + * spin3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Thread A locks spin - thread B tries to unlock. + * This should succeed, but it's undefined behaviour. + * + */ + +#include "test.h" + +static int wasHere = 0; + +static pthread_spinlock_t spin; + +static void * unlocker(void * arg) +{ + int expectedResult = (int) arg; + + wasHere++; + assert(pthread_spin_unlock(&spin) == expectedResult); + wasHere++; + return NULL; +} + +int pthread_test_spin3() +{ + pthread_t t; + + wasHere = 0; + assert(pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE) == 0); + assert(pthread_spin_lock(&spin) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_spin_unlock(&spin) == EPERM); + assert(pthread_spin_destroy(&spin) == 0); + assert(wasHere == 2); + + return 0; +} diff --git a/src/pthread/tests/spin4.c b/src/pthread/tests/spin4.c new file mode 100644 index 000000000..607621ba6 --- /dev/null +++ b/src/pthread/tests/spin4.c @@ -0,0 +1,106 @@ +/* + * spin4.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static spinlock object, lock it, spin on it, + * and then unlock it again. + */ + +#include "test.h" + +static pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER; +static struct _timeb currSysTimeStart; +static struct _timeb currSysTimeStop; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +static int washere = 0; + +static void * func(void * arg) +{ + _ftime(&currSysTimeStart); + washere = 1; + assert(pthread_spin_lock(&lock) == 0); + assert(pthread_spin_unlock(&lock) == 0); + _ftime(&currSysTimeStop); + + return (void *) GetDurationMilliSecs(currSysTimeStart, currSysTimeStop); +} + +int pthread_test_spin4() +{ + long result = 0; + pthread_t t; + struct _timeb sysTime; + + if (pthread_num_processors_np() == 1) + { + printf("spin test #4 not run - it requires multiple CPUs.\n"); + return 0; + } + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + while (washere == 0) + { + sched_yield(); + } + + do + { + sched_yield(); + _ftime(&sysTime); + } + while (GetDurationMilliSecs(currSysTimeStart, sysTime) <= 1000); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result > 1000); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/src/pthread/tests/stress1.c b/src/pthread/tests/stress1.c new file mode 100644 index 000000000..905d0f74c --- /dev/null +++ b/src/pthread/tests/stress1.c @@ -0,0 +1,288 @@ +/* + * stress1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Stress test condition variables, mutexes, semaphores. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - Correct accounting of semaphore and condition variable waiters. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * Attempting to expose race conditions in cond vars, semaphores etc. + * - Master attempts to signal slave close to when timeout is due. + * - Master and slave do battle continuously until main tells them to stop. + * - Afterwards, the CV must be successfully destroyed (will return an + * error if there are waiters (including any internal semaphore waiters, + * which, if there are, cannot not be real waiters). + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - CV is successfully destroyed. + * + * Fail Criteria: + * - CV destroy fails. + */ + +#include +#include "test.h" + +typedef long long int64_t; + +const unsigned int ITERATIONS = 1000; + +static pthread_t master, slave; +typedef struct + { + int value; + pthread_cond_t cv; + pthread_mutex_t mx; + } mysig_t; + +static int allExit; +static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; +static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; +static int timeoutCount = 0; +static int signalsTakenCount = 0; +static int signalsSent = 0; +static int bias = 0; +static int timeout = 10; +// Must be > 0 + +enum +{ + CTL_STOP = -1 +}; + +/* + * Returns abstime 'milliseconds' from 'now'. + * + * Works for: -INT_MAX <= millisecs <= INT_MAX + */ +static struct timespec * + millisecondsFromNow (struct timespec * time, int millisecs) + { + struct _timeb currSysTime; + int64_t nanosecs, secs; + const int64_t NANOSEC_PER_MILLISEC = 1000000; + const int64_t NANOSEC_PER_SEC = 1000000000; + + /* get current system time and add millisecs */ + _ftime(&currSysTime); + + secs = (int64_t)(currSysTime.time) + (millisecs / 1000); + nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; + if (nanosecs >= NANOSEC_PER_SEC) + { + secs++; + nanosecs -= NANOSEC_PER_SEC; + } + else if (nanosecs < 0) + { + secs--; + nanosecs += NANOSEC_PER_SEC; + } + + time->tv_nsec = (long)nanosecs; + time->tv_sec = (long)secs; + + return time; + } + +static void * +masterThread (void * arg) +{ + int dither = (int) arg; + + timeout = (int) arg; + + pthread_barrier_wait(&startBarrier); + + do + { + int sleepTime; + + assert(pthread_mutex_lock(&control.mx) == 0); + control.value = timeout; + assert(pthread_mutex_unlock(&control.mx) == 0); + + /* + * We are attempting to send the signal close to when the slave + * is due to timeout. We feel around by adding some [non-random] dither. + * + * dither is in the range 2*timeout peak-to-peak + * sleep time is the average of timeout plus dither. + * e.g. + * if timeout = 10 then dither = 20 and + * sleep millisecs is: 5 <= ms <= 15 + * + * The bias value attempts to apply some negative feedback to keep + * the ratio of timeouts to signals taken close to 1:1. + * bias changes more slowly than dither so as to average more. + * + * Finally, if abs(bias) exceeds timeout then timeout is incremented. + */ + if (signalsSent % timeout == 0) + { + if (timeoutCount > signalsTakenCount) + { + bias++; + } + else if (timeoutCount < signalsTakenCount) + { + bias--; + } + if (bias < -timeout || bias > timeout) + { + timeout++; + } + } + dither = (dither + 1 ) % (timeout * 2); + sleepTime = (timeout - bias + dither) / 2; + pte_osThreadSleep(sleepTime); + assert(pthread_cond_signal(&control.cv) == 0); + signalsSent++; + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +static void * +slaveThread (void * arg) +{ + struct timespec time; + + pthread_barrier_wait(&startBarrier); + + do + { + assert(pthread_mutex_lock(&control.mx) == 0); + if (pthread_cond_timedwait(&control.cv, + &control.mx, + millisecondsFromNow(&time, control.value)) == ETIMEDOUT) + { + timeoutCount++; + } + else + { + signalsTakenCount++; + } + assert(pthread_mutex_unlock(&control.mx) == 0); + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +int pthread_test_stress1() +{ + unsigned int i; + + control.value = 0; + control.cv = PTHREAD_COND_INITIALIZER; + control.mx = PTHREAD_MUTEX_INITIALIZER; + + timeoutCount = 0; + signalsTakenCount = 0; + signalsSent = 0; + bias = 0; + timeout = 10; + assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); + + assert(pthread_create(&master, NULL, masterThread, (void *) timeout) == 0); + assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); + + allExit = 0; + + pthread_barrier_wait(&startBarrier); + + for (i = 1; !allExit; i++) + { + pthread_barrier_wait(&holdBarrier); + if (i >= ITERATIONS) + { + allExit = 1; + } + pthread_barrier_wait(&readyBarrier); + } + + assert(pthread_join(slave, NULL) == 0); + assert(pthread_join(master, NULL) == 0); + + /* Cleanup */ + assert(pthread_barrier_destroy(&holdBarrier) == 0); + assert(pthread_barrier_destroy(&readyBarrier) == 0); + assert(pthread_barrier_destroy(&startBarrier) == 0); + assert(pthread_cond_destroy(&control.cv) == 0); + assert(pthread_mutex_destroy(&control.mx) == 0); + + /* Success. */ + return 0; +} diff --git a/src/pthread/tests/test.h b/src/pthread/tests/test.h new file mode 100644 index 000000000..94045c321 --- /dev/null +++ b/src/pthread/tests/test.h @@ -0,0 +1,283 @@ +/* + * test.h + * + * Useful definitions and declarations for tests. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +#ifndef _PTHREAD_TEST_H_ +#define _PTHREAD_TEST_H_ + +#include +#include + +#include "pte_osal.h" + +#include "pthread.h" +#include "sched.h" +#include "semaphore.h" + +//#include + + +#define PTW32_THREAD_NULL_ID {NULL,0} + +#if defined(__MINGW32__) +#include +#elif defined(__BORLANDC__) +#define int64_t ULONGLONG +#else +#define int64_t _int64 +#endif + +extern const char * error_string; + + +/* + * The Mingw32 assert macro calls the CRTDLL _assert function + * which pops up a dialog. We want to run in batch mode so + * we define our own assert macro. + */ +#ifdef assert +# undef assert +#endif + +#ifndef ASSERT_TRACE +# define ASSERT_TRACE 0 +#else +# undef ASSERT_TRACE +# define ASSERT_TRACE 1 +#endif + +# define assert(e) \ + ((e) ? ((ASSERT_TRACE) ? fprintf(stdout, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stdout) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), exit(1), 0)) + +extern int assertE; +# define assert_e(e, o, r) \ + (((assertE = e) o (r)) ? ((ASSERT_TRACE) ? fprintf(stdout, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stdout) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s %s %s), file %s, line %d, error %s\n", \ + #e,#o,#r, __FILE__, (int) __LINE__, error_string[assertE]), exit(1), 0)) + +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +int pthread_test_mutex1(); +int pthread_test_mutex1e(); +int pthread_test_mutex1n(); +int pthread_test_mutex1r(); + +int pthread_test_mutex2(); +int pthread_test_mutex2e(); +int pthread_test_mutex2r(); + +int pthread_test_mutex3(); +int pthread_test_mutex3e(); +int pthread_test_mutex3r(); + +int pthread_test_mutex4(); + +int pthread_test_mutex5(); + +int pthread_test_mutex6(); +int pthread_test_mutex6e(); +int pthread_test_mutex6es(); +int pthread_test_mutex6n(); +int pthread_test_mutex6r(); +int pthread_test_mutex6rs(); +int pthread_test_mutex6s(); + +int pthread_test_mutex7(); +int pthread_test_mutex7e(); +int pthread_test_mutex7n(); +int pthread_test_mutex7r(); + +int pthread_test_mutex8(); +int pthread_test_mutex8e(); +int pthread_test_mutex8n(); +int pthread_test_mutex8r(); + +int pthread_test_valid1(); +int pthread_test_valid2(); + +int pthread_test_self1(); +int pthread_test_self2(); + +int pthread_test_equal1(); + +int pthread_test_create1(); +int pthread_test_create2(); +int pthread_test_create3(); + +int pthread_test_semaphore1(); +int pthread_test_semaphore2(); +int pthread_test_semaphore3(); +int pthread_test_semaphore4(); +int pthread_test_semaphore4t(); +int pthread_test_semaphore5(); +int pthread_test_semaphore6(); + +int pthread_test_barrier1(); +int pthread_test_barrier2(); +int pthread_test_barrier3(); +int pthread_test_barrier4(); +int pthread_test_barrier5(); + +int pthread_test_count1(); + +int pthread_test_create1(); +int pthread_test_create2(); +int pthread_test_create3(); + +int pthread_test_delay1(); +int pthread_test_delay2(); + +int pthread_test_errno1(); + +int pthread_test_join0(); +int pthread_test_join1(); +int pthread_test_join2(); +int pthread_test_join3(); +int pthread_test_join4(); + +int pthread_test_kill1(); + +int pthread_test_once1(); +int pthread_test_once2(); +int pthread_test_once3(); +int pthread_test_once4(); + +int pthread_test_spin1(); +int pthread_test_spin2(); +int pthread_test_spin3(); +int pthread_test_spin4(); + +int pthread_test_tsd1(); +int pthread_test_tsd2(); + +int pthread_test_condvar1_1(); +int pthread_test_condvar1_2(); +int pthread_test_condvar1(); +int pthread_test_condvar2_1(); +int pthread_test_condvar2(); +int pthread_test_condvar3(); +int pthread_test_condvar3_1(); +int pthread_test_condvar3_2(); +int pthread_test_condvar3_3(); +int pthread_test_condvar4(); +int pthread_test_condvar5(); +int pthread_test_condvar6(); +int pthread_test_condvar7(); +int pthread_test_condvar8(); +int pthread_test_condvar9(); + +int pthread_test_stress1(); + +int pthread_test_detach1(); + +int pthread_test_exit1(); +int pthread_test_exit2(); +int pthread_test_exit3(); +int pthread_test_exit4(); +int pthread_test_exit5(); + +int pthread_test_reuse1(); +int pthread_test_reuse2(); + +int pthread_test_rwlock1(); +int pthread_test_rwlock2(); +int pthread_test_rwlock2t(); +int pthread_test_rwlock3(); +int pthread_test_rwlock3t(); +int pthread_test_rwlock4(); +int pthread_test_rwlock4t(); +int pthread_test_rwlock5(); +int pthread_test_rwlock5t(); +int pthread_test_rwlock6(); +int pthread_test_rwlock6t(); +int pthread_test_rwlock6t2(); +int pthread_test_rwlock7(); +int pthread_test_rwlock8(); + +int pthread_test_priority1(); +int pthread_test_priority2(); + +int pthread_test_inherit1(); + +int pthread_test_cancel1(); +int pthread_test_cancel2(); +int pthread_test_cancel3(); +int pthread_test_cancel4(); +int pthread_test_cancel5(); +int pthread_test_cancel6a(); +int pthread_test_cancel6d(); +int pthread_test_cancel7(); +int pthread_test_cancel8(); +int pthread_test_cancel9(); + +int pthread_test_cleanup0(); +int pthread_test_cleanup1(); +int pthread_test_cleanup2(); +int pthread_test_cleanup3(); + +int pthread_test_bench1(); +int pthread_test_bench2(); +int pthread_test_bench3(); +int pthread_test_bench4(); + +int pthread_test_exception1(); +int pthread_test_exception2(); +int pthread_test_exception3(); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/src/pthread/tests/test_main.c b/src/pthread/tests/test_main.c new file mode 100644 index 000000000..d4bea4894 --- /dev/null +++ b/src/pthread/tests/test_main.c @@ -0,0 +1,488 @@ +#include "pte_osal.h" +#include "test.h" + +const char * error_string; + +int assertE; + +///@todo: add cancellable wait for thread end for DSP/BIOS +///@todo: look at removing/changing ftime + +static void runBarrierTests(void) +{ + printf("Barrier test #1\n"); + pthread_test_barrier1(); + + printf("Barrier test #2\n"); + pthread_test_barrier2(); + + printf("Barrier test #3\n"); + pthread_test_barrier3(); + + printf("Barrier test #4\n"); + pthread_test_barrier4(); + + printf("Barrier test #5\n"); + pthread_test_barrier5(); +} + +static void runSemTests(void) +{ + + printf("Semaphore test #1\n"); + pthread_test_semaphore1(); + + printf("Semaphore test #2\n"); + pthread_test_semaphore2(); + + printf("Semaphore test #3\n"); + pthread_test_semaphore3(); + + + printf("Semaphore test #4\n"); + pthread_test_semaphore4(); + + printf("Semaphore test #4t\n"); + pthread_test_semaphore4t(); + + printf("Semaphore test #5\n"); + pthread_test_semaphore5(); + + printf("Semaphore test #6\n"); + pthread_test_semaphore6(); + +} + +static void runThreadTests(void) +{ + + printf("Create test #1\n"); + pthread_test_create1(); + + printf("Create test #2\n"); + pthread_test_create2(); + + printf("Create test #3\n"); + pthread_test_create3(); + + printf("Join test #0\n"); + pthread_test_join0(); + + printf("Join test #1\n"); + pthread_test_join1(); + + printf("Join test #2\n"); + pthread_test_join2(); + + printf("Join test #3\n"); + pthread_test_join3(); + + printf("Join test #4\n"); + pthread_test_join4(); + + printf("Kill test #1\n"); + pthread_test_kill1(); + + printf("Exit test #1\n"); + pthread_test_exit1(); + + printf("Exit test #2\n"); + pthread_test_exit2(); + + printf("Exit test #3\n"); + pthread_test_exit3(); + + printf("Exit test #4\n"); + pthread_test_exit4(); + + printf("Exit test #5\n"); + pthread_test_exit5(); + + /* These tests can not be run in series with other tests, + * as they rely on knowing what is on the reuse queue. + */ + /* + printf("Reuse test #1\n"); + pthread_test_reuse1(); + + printf("Reuse test #2\n"); + pthread_test_reuse2(); + */ + + printf("Priority test #1\n"); + pthread_test_priority1(); + + printf("Priority test #2\n"); + pthread_test_priority2(); + +// printf("Inherit test #1\n"); +// pthread_test_inherit1(); ///@todo + +} + +static void runMiscTests(void) +{ + + printf("Valid test #1\n"); + pthread_test_valid1(); + + printf("Valid test #2\n"); + pthread_test_valid2(); + + printf("Self test #1\n"); + pthread_test_self1(); + + printf("Self test #2\n"); + pthread_test_self2(); + + printf("Equal test #1\n"); + pthread_test_equal1(); + + printf("Count test #1\n"); + pthread_test_count1(); + + printf("Delay test #1\n"); + pthread_test_delay1(); + + printf("Delay test #2\n"); + pthread_test_delay2(); + + printf("Once test #1\n"); + pthread_test_once1(); + + printf("Once test #2\n"); + pthread_test_once2(); + + printf("Once test #3\n"); + pthread_test_once3(); + + printf("Once test #4\n"); + pthread_test_once4(); + + printf("TSD test #1\n"); + pthread_test_tsd1(); + + printf("TSD test #2\n"); + pthread_test_tsd2(); + +#ifdef THREAD_SAFE_ERRNO + printf("Errno test #1\n"); + pthread_test_errno1(); +#endif // THREAD_SAFE_ERRNO + + printf("Detach test #1\n"); + pthread_test_detach1(); + +} + +static void runMutexTests(void) +{ + + printf("Mutex test #1\n"); + pthread_test_mutex1(); + + printf("Mutex test #1(e)\n"); + pthread_test_mutex1e(); + + printf("Mutex test #1(n)\n"); + pthread_test_mutex1n(); + + printf("Mutex test #1(r)\n"); + pthread_test_mutex1e(); + + printf("Mutex test #2\n"); + pthread_test_mutex2(); + + printf("Mutex test #2(e)\n"); + pthread_test_mutex2e(); + + printf("Mutex test #2(r)\n"); + pthread_test_mutex2r(); + + printf("Mutex test #3\n"); + pthread_test_mutex3(); + + printf("Mutex test #3(e)\n"); + pthread_test_mutex3e(); + + printf("Mutex test #3(r)\n"); + pthread_test_mutex3r(); + + printf("Mutex test #4\n"); + pthread_test_mutex4(); + + printf("Mutex test #5\n"); + pthread_test_mutex5(); + + printf("Mutex test #6\n"); + pthread_test_mutex6(); + + printf("Mutex test #6e\n"); + pthread_test_mutex6e(); + + printf("Mutex test #6es\n"); + pthread_test_mutex6es(); + + printf("Mutex test #6n\n"); + pthread_test_mutex6n(); + + printf("Mutex test #6r\n"); + pthread_test_mutex6r(); + + printf("Mutex test #6rs\n"); + pthread_test_mutex6rs(); + + printf("Mutex test #6s\n"); + pthread_test_mutex6s(); + + printf("Mutex test #7\n"); + pthread_test_mutex7(); + + printf("Mutex test #7e\n"); + pthread_test_mutex7e(); + + printf("Mutex test #7n\n"); + pthread_test_mutex7n(); + + printf("Mutex test #7r\n"); + pthread_test_mutex7r(); + + printf("Mutex test #8\n"); + pthread_test_mutex8(); + + printf("Mutex test #8e\n"); + pthread_test_mutex8e(); + + printf("Mutex test #8n\n"); + pthread_test_mutex8n(); + + printf("Mutex test #8r\n"); + pthread_test_mutex8r(); + +} + +static void runSpinTests() +{ + printf("Spin test #1\n"); + pthread_test_spin1(); + + printf("Spin test #2\n"); + pthread_test_spin2(); + + printf("Spin test #3\n"); + pthread_test_spin3(); + + printf("Spin test #4\n"); + pthread_test_spin4(); + +} + +static void runCondvarTests() +{ + + printf("Condvar test #1\n"); + pthread_test_condvar1(); + + printf("Condvar test #1-1\n"); + pthread_test_condvar1_1(); + + printf("Condvar test #1-2\n"); + pthread_test_condvar1_2(); + + printf("Condvar test #2\n"); + pthread_test_condvar2(); + + printf("Condvar test #2-1\n"); + pthread_test_condvar2_1(); + + printf("Condvar test #3\n"); + pthread_test_condvar3(); + + printf("Condvar test #3-1\n"); + pthread_test_condvar3_1(); + + printf("Condvar test #3-2\n"); + pthread_test_condvar3_2(); + + printf("Condvar test #3-3\n"); + pthread_test_condvar3_3(); + + printf("Condvar test #4\n"); + pthread_test_condvar4(); + + printf("Condvar test #5\n"); + pthread_test_condvar5(); + + printf("Condvar test #6\n"); + pthread_test_condvar6(); + + printf("Condvar test #7\n"); + pthread_test_condvar7(); + + printf("Condvar test #8\n"); + pthread_test_condvar8(); + + printf("Condvar test #9\n"); + pthread_test_condvar9(); + +} + +static void runStressTests() +{ + printf("Stress test #1\n"); + pthread_test_stress1(); +} + +static void runRwlockTests() +{ + printf("Rwlock test #1\n"); + pthread_test_rwlock1(); + + printf("Rwlock test #2\n"); + pthread_test_rwlock2(); + + printf("Rwlock test #2t\n"); + pthread_test_rwlock2t(); + + printf("Rwlock test #3\n"); + pthread_test_rwlock3(); + + printf("Rwlock test #3t\n"); + pthread_test_rwlock3t(); + + printf("Rwlock test #4\n"); + pthread_test_rwlock4(); + + printf("Rwlock test #4t\n"); + pthread_test_rwlock4t(); + + printf("Rwlock test #5\n"); + pthread_test_rwlock5(); + + printf("Rwlock test #5t\n"); + pthread_test_rwlock5t(); + + printf("Rwlock test #6\n"); + pthread_test_rwlock6(); + + printf("Rwlock test #6t\n"); + pthread_test_rwlock6t(); + + printf("Rwlock test #6t2\n"); + pthread_test_rwlock6t2(); + + printf("Rwlock test #7\n"); + pthread_test_rwlock7(); + + printf("Rwlock test #8\n"); + pthread_test_rwlock8(); + +} + +static void runCancelTests() +{ + + printf("Cancel test #1\n"); + pthread_test_cancel1(); + + printf("Cancel test #2\n"); + pthread_test_cancel2(); + + printf("Cancel test #3\n"); + pthread_test_cancel3(); + + printf("Cancel test #4\n"); + pthread_test_cancel4(); + + printf("Cancel test #5\n"); + pthread_test_cancel5(); + + printf("Cancel test #6a\n"); + pthread_test_cancel6a(); + + printf("Cancel test #6d\n"); + pthread_test_cancel6d(); + + /* Cleanup only occurs for async cancellation. + * If we don't support this, can't test it... + */ + printf("Cleanup test #0\n"); + pthread_test_cleanup0(); + + printf("Cleanup test #1\n"); + pthread_test_cleanup1(); + + printf("Cleanup test #2\n"); + pthread_test_cleanup2(); + + printf("Cleanup test #3\n"); + pthread_test_cleanup3(); +} + +static void runBenchTests() +{ + + printf("Benchmark test #1\n"); + pthread_test_bench1(); + + printf("Benchmark test #2\n"); + pthread_test_bench2(); + + printf("Benchmark test #3\n"); + pthread_test_bench3(); + + printf("Benchmark test #4\n"); + pthread_test_bench4(); +} + +static void runExceptionTests() +{ + printf("Exception test #1\n"); + pthread_test_exception1(); + +/* This test intentially crashes the app + (unhandled exception) + printf("Exception test #2\n"); + pthread_test_exception2(); +*/ + + printf("Exception test #3\n"); + pthread_test_exception3(); +} + +void pte_test_main() +{ + int i; + + if (!pthread_init()) + { + printf("Failed to initialize pthreads library.\n"); + return; + } + + printf("Running tests...\n"); + for (i=0;i<2;i++) + { + printf("=========================\n"); + printf(" Test iteration #%d\n\n",i); + printf("=========================\n"); + + runThreadTests(); + runMiscTests(); + runMutexTests(); + runSemTests(); + runCondvarTests(); + runBarrierTests(); + runSpinTests(); + runRwlockTests(); + runCancelTests(); + runExceptionTests(); + runBenchTests(); + runStressTests(); + + } + + printf("Tests complete!\n"); + +} + diff --git a/src/pthread/tests/tsd1.c b/src/pthread/tests/tsd1.c new file mode 100644 index 000000000..4c5308b7d --- /dev/null +++ b/src/pthread/tests/tsd1.c @@ -0,0 +1,227 @@ +/* + * tsd1.c + * + * Test Thread Specific Data (TSD) key creation and destruction. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * + * -------------------------------------------------------------------------- + * + * Description: + * - + * + * Test Method (validation or falsification): + * - validation + * + * Requirements Tested: + * - keys are created for each existing thread including the main thread + * - keys are created for newly created threads + * - keys are thread specific + * - destroy routine is called on each thread exit including the main thread + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Environment: + * - + * + * Input: + * - none + * + * Output: + * - text to stdout + * + * Assumptions: + * - already validated: pthread_create() + * pthread_once() + * - main thread also has a POSIX thread identity + * + * Pass Criteria: + * - stdout matches file reference/tsd1.out + * + * Fail Criteria: + * - fails to match file reference/tsd1.out + * - output identifies failed component + */ + +#include "test.h" +#include "implement.h" +#include + + +enum +{ + NUM_THREADS = OS_MAX_SIMUL_THREADS +}; + +static pthread_key_t key = NULL; +static int accesscount[NUM_THREADS]; +static int thread_set[NUM_THREADS]; +static int thread_destroyed[NUM_THREADS]; +static pthread_barrier_t startBarrier; + +static void +destroy_key(void * arg) +{ + int * j = (int *) arg; + + (*j)++; + + assert(*j == 2); + + thread_destroyed[j - accesscount] = 1; +} + +static void +setkey(void * arg) +{ + int * j = (int *) arg; + + thread_set[j - accesscount] = 1; + + assert(*j == 0); + + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + + assert(pthread_getspecific(key) == arg); + + (*j)++; + + assert(*j == 1); +} + +static void * +mythread(void * arg) +{ + (void) pthread_barrier_wait(&startBarrier); + + // Note that this test must go here, rather than + // in setkey() above, as setkey() is called by the main + // (non-pthread) thread, which has already been running + // and thus may have a non-zero value for the TLS for + // this key. + assert(pthread_getspecific(key) == NULL); + + setkey(arg); + + return 0; + + /* Exiting the thread will call the key destructor. */ +} + +int pthread_test_tsd1() +{ + int i; + int fail = 0; + pthread_t thread[NUM_THREADS]; + + /* Just to avoid compiler warnings */ + thread_set[0] = thread_set[0]; + thread_destroyed[0] = thread_destroyed[0]; + + assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0); + + for (i = 1; i < NUM_THREADS/2; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Here we test that existing threads will get a key created + * for them. + */ + assert(pthread_key_create(&key, destroy_key) == 0); + + (void) pthread_barrier_wait(&startBarrier); + + /* + * Test main thread key. + */ + accesscount[0] = 0; + setkey((void *) &accesscount[0]); + + /* + * Here we test that new threads will get a key created + * for them. + */ + for (i = NUM_THREADS/2; i < NUM_THREADS; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Wait for all threads to complete. + */ + for (i = 1; i < NUM_THREADS; i++) + { + int result = 0; + + assert(pthread_join(thread[i], (void **) &result) == 0); + } + +// assert(pthread_key_delete(key) == 0); + + assert(pthread_barrier_destroy(&startBarrier) == 0); + + for (i = 1; i < NUM_THREADS; i++) + { + /* + * The counter is incremented once when the key is set to + * a value, and again when the key is destroyed. If the key + * doesn't get set for some reason then it will still be + * NULL and the destroy function will not be called, and + * hence accesscount will not equal 2. + */ + if (accesscount[i] != 2) + { + fail++; + } + } + + assert(fail == 0); + + return (fail); +} diff --git a/src/pthread/tests/tsd2.c b/src/pthread/tests/tsd2.c new file mode 100644 index 000000000..a9558abf5 --- /dev/null +++ b/src/pthread/tests/tsd2.c @@ -0,0 +1,225 @@ +/* + * tsd2.c + * + * Test Thread Specific Data (TSD) key creation and destruction. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * + * -------------------------------------------------------------------------- + * + * Description: + * - + * + * Test Method (validation or falsification): + * - validation + * + * Requirements Tested: + * - keys are created for each existing thread including the main thread + * - keys are created for newly created threads + * - keys are thread specific + * - destroy routine is called on each thread exit including the main thread + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Environment: + * - + * + * Input: + * - none + * + * Output: + * - text to stdout + * + * Assumptions: + * - already validated: pthread_create() + * pthread_once() + * - main thread also has a POSIX thread identity + * + * Pass Criteria: + * - stdout matches file reference/tsd1.out + * + * Fail Criteria: + * - fails to match file reference/tsd1.out + * - output identifies failed component + */ + +#include "test.h" +#include "implement.h" +#include + + +enum +{ + NUM_THREADS = 20 +}; + +static pthread_key_t key = NULL; +static int accesscount[NUM_THREADS]; +static int thread_set[NUM_THREADS]; +static int thread_destroyed[NUM_THREADS]; +static pthread_barrier_t startBarrier; + +static void +destroy_key(void * arg) +{ + int * j = (int *) arg; + + (*j)++; + + /* Set TSD key from the destructor to test destructor iteration */ + if (*j == 2) + assert(pthread_setspecific(key, arg) == 0); + else + assert(*j == 3); + + thread_destroyed[j - accesscount] = 1; +} + +static void +setkey(void * arg) +{ + int * j = (int *) arg; + + thread_set[j - accesscount] = 1; + + assert(*j == 0); + + assert(pthread_getspecific(key) == NULL); + + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + + assert(pthread_getspecific(key) == arg); + + (*j)++; + + assert(*j == 1); +} + +static void * +mythread(void * arg) +{ + (void) pthread_barrier_wait(&startBarrier); + + setkey(arg); + + return 0; + + /* Exiting the thread will call the key destructor. */ +} + +int pthread_test_tsd2() +{ + int i; + int fail = 0; + pthread_t thread[NUM_THREADS]; + + /* Just to avoid compiler warnings */ + thread_set[0] = thread_set[0]; + thread_destroyed[0] = thread_destroyed[0]; + + assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0); + + for (i = 1; i < NUM_THREADS/2; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Here we test that existing threads will get a key created + * for them. + */ + assert(pthread_key_create(&key, destroy_key) == 0); + + (void) pthread_barrier_wait(&startBarrier); + + /* + * Test main thread key. + */ + accesscount[0] = 0; + setkey((void *) &accesscount[0]); + + /* + * Here we test that new threads will get a key created + * for them. + */ + for (i = NUM_THREADS/2; i < NUM_THREADS; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Wait for all threads to complete. + */ + for (i = 1; i < NUM_THREADS; i++) + { + int result = 0; + + assert(pthread_join(thread[i], (void **) &result) == 0); + } + + assert(pthread_key_delete(key) == 0); + + assert(pthread_barrier_destroy(&startBarrier) == 0); + + for (i = 1; i < NUM_THREADS; i++) + { + /* + * The counter is incremented once when the key is set to + * a value, and again when the key is destroyed. If the key + * doesn't get set for some reason then it will still be + * NULL and the destroy function will not be called, and + * hence accesscount will not equal 2. + */ + if (accesscount[i] != 3) + { + fail++; + } + } + + fflush(stderr); + + return (fail); +} diff --git a/src/pthread/tests/valid1.c b/src/pthread/tests/valid1.c new file mode 100644 index 000000000..ff3b25eb5 --- /dev/null +++ b/src/pthread/tests/valid1.c @@ -0,0 +1,109 @@ +/* + * File: valid1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that thread validation works. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum +{ + NUMTHREADS = 1 +}; + +static int washere = 0; + +static void * func(void * arg) +{ + washere = 1; + return (void *) 0; +} + +int pthread_test_valid1(void) +{ + pthread_t t; + void * result = NULL; + + washere = 0; + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, &result) == 0); + assert(result == 0); + assert(washere == 1); + sched_yield(); + assert(pthread_kill(t, 0) == ESRCH); + + return 0; +} diff --git a/src/pthread/tests/valid2.c b/src/pthread/tests/valid2.c new file mode 100644 index 000000000..244a25d7e --- /dev/null +++ b/src/pthread/tests/valid2.c @@ -0,0 +1,89 @@ +/* + * File: valid2.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Confirm that thread validation fails for garbage thread ID. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +int pthread_test_valid2(void) +{ + pthread_t NullThread = PTW32_THREAD_NULL_ID; + + assert(pthread_kill(NullThread, 0) == ESRCH); + + return 0; +} diff --git a/src/pthread/tls-helper.c b/src/pthread/tls-helper.c new file mode 100644 index 000000000..5a3b1d502 --- /dev/null +++ b/src/pthread/tls-helper.c @@ -0,0 +1,185 @@ +/* + * tls-helper.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "tls-helper.h" + +static int *keysUsed; + +/* We don't protect this - it's only written on startup */ +static int maxTlsValues; + +pte_osMutexHandle globalTlsLock; + +pte_osResult pteTlsGlobalInit(int maxEntries) +{ + int i; + pte_osResult result; + + pte_osMutexCreate(&globalTlsLock); + + keysUsed = (int *) malloc(maxEntries * sizeof(int)); + + if (keysUsed != NULL) + { + for (i=0;i Date: Sun, 19 Jul 2020 15:00:42 -0500 Subject: [PATCH 16/36] Move pthread library into new compatability directory structure --- src/{ => compat}/pthread/ANNOUNCE | 0 src/{ => compat}/pthread/CONTRIBUTORS.ptw32 | 0 src/{ => compat}/pthread/COPYING | 0 src/{ => compat}/pthread/COPYING.LIB | 0 src/{ => compat}/pthread/Makefile | 0 src/{ => compat}/pthread/Makefile.PSP | 0 src/{ => compat}/pthread/cleanup.c | 0 src/{ => compat}/pthread/create.c | 0 src/{ => compat}/pthread/doc/Doxyfile | 0 src/{ => compat}/pthread/doc/doxygen.css | 0 src/{ => compat}/pthread/doc/pte_dspbios.html | 0 src/{ => compat}/pthread/doc/pte_main.html | 0 .../pthread/doc/pte_osal_api.html | 0 .../pthread/doc/pte_porting_guide.html | 0 src/{ => compat}/pthread/doc/pte_psp.html | 0 .../pthread/doc/pte_users_guide.html | 0 src/{ => compat}/pthread/global.c | 0 src/{ => compat}/pthread/implement.h | 0 src/{ => compat}/pthread/nautilus_osal.c | 0 src/{ => compat}/pthread/nautilus_osal.h | 0 src/{ => compat}/pthread/need_errno.h | 0 .../pthread/platform/dspbios/dspbios-config.h | 0 .../pthread/platform/dspbios/dspbios-osal.c | 0 .../pthread/platform/dspbios/dspbios-osal.h | 0 .../pthread/platform/dspbios/main.c | 0 .../platform/dspbios/pte_lib/pte_lib.pjt | 0 .../pthread/platform/dspbios/pte_osal.h | 0 .../dspbios/pte_test/Configuration1.cdb | 0 .../dspbios/pte_test/Configuration1.tcf | 0 .../dspbios/pte_test/Configuration1.tco | 0 .../platform/dspbios/pte_test/pte_test.pjt | 0 .../pthread/platform/dspbios/pte_types.h | 0 .../pthread/platform/helper/tls-helper.c | 0 .../pthread/platform/helper/tls-helper.h | 0 .../pthread/platform/nautilus/Makefile | 0 .../pthread/platform/nautilus/Makefile.tests | 0 .../pthread/platform/nautilus}/Makefile~ | 0 .../pthread/platform/nautilus/main.c | 0 .../pthread/platform/nautilus/nautilus_osal.c | 0 .../pthread/platform/nautilus/nautilus_osal.h | 0 .../platform/nautilus/nautilus_osal.h~ | 0 .../pthread/platform/nautilus/psp_osal.c | 0 .../pthread/platform/nautilus/psp_osal.h | 0 .../pthread/platform/nautilus/pte_osal.h | 0 .../pthread/platform/nautilus/pte_osal.h~ | 0 .../pthread/platform/nautilus/pte_types.h | 0 .../pthread/platform/psp/Makefile | 0 .../pthread/platform/psp/Makefile.tests | 0 src/{ => compat}/pthread/platform/psp/main.c | 0 .../pthread/platform/psp/psp_osal.c | 0 .../pthread/platform/psp/psp_osal.h | 0 .../pthread/platform/psp/pte_osal.h | 0 .../pthread/platform/psp/pte_types.h | 0 .../pthread/pte_callUserDestroyRoutines.c | 0 .../pthread/pte_cancellable_wait.c | 0 .../pthread/pte_cond_check_need_init.c | 0 src/{ => compat}/pthread/pte_detach.c | 0 src/{ => compat}/pthread/pte_generic_osal.h | 0 src/{ => compat}/pthread/pte_getprocessors.c | 0 src/{ => compat}/pthread/pte_is_attr.c | 0 .../pthread/pte_mutex_check_need_init.c | 0 src/{ => compat}/pthread/pte_new.c | 0 src/{ => compat}/pthread/pte_osal.h | 0 src/{ => compat}/pthread/pte_relmillisecs.c | 0 src/{ => compat}/pthread/pte_reuse.c | 0 .../pthread/pte_rwlock_cancelwrwait.c | 0 .../pthread/pte_rwlock_check_need_init.c | 0 .../pthread/pte_spinlock_check_need_init.c | 0 src/{ => compat}/pthread/pte_threadDestroy.c | 0 src/{ => compat}/pthread/pte_threadStart.c | 0 src/{ => compat}/pthread/pte_throw.c | 0 src/{ => compat}/pthread/pte_tkAssocCreate.c | 0 src/{ => compat}/pthread/pte_tkAssocDestroy.c | 0 src/{ => compat}/pthread/pte_types.h | 0 src/{ => compat}/pthread/pthread.h | 0 .../pthread/pthread_attr_destroy.c | 0 .../pthread/pthread_attr_getdetachstate.c | 0 .../pthread/pthread_attr_getinheritsched.c | 0 .../pthread/pthread_attr_getschedparam.c | 0 .../pthread/pthread_attr_getschedpolicy.c | 0 .../pthread/pthread_attr_getscope.c | 0 .../pthread/pthread_attr_getstackaddr.c | 0 .../pthread/pthread_attr_getstacksize.c | 0 src/{ => compat}/pthread/pthread_attr_init.c | 0 .../pthread/pthread_attr_setdetachstate.c | 0 .../pthread/pthread_attr_setinheritsched.c | 0 .../pthread/pthread_attr_setschedparam.c | 0 .../pthread/pthread_attr_setschedpolicy.c | 0 .../pthread/pthread_attr_setscope.c | 0 .../pthread/pthread_attr_setstackaddr.c | 0 .../pthread/pthread_attr_setstacksize.c | 0 .../pthread/pthread_barrier_destroy.c | 0 .../pthread/pthread_barrier_init.c | 0 .../pthread/pthread_barrier_wait.c | 0 .../pthread/pthread_barrierattr_destroy.c | 0 .../pthread/pthread_barrierattr_getpshared.c | 0 .../pthread/pthread_barrierattr_init.c | 0 .../pthread/pthread_barrierattr_setpshared.c | 0 src/{ => compat}/pthread/pthread_cancel.c | 0 .../pthread/pthread_cond_destroy.c | 0 src/{ => compat}/pthread/pthread_cond_init.c | 0 .../pthread/pthread_cond_signal.c | 0 src/{ => compat}/pthread/pthread_cond_wait.c | 0 .../pthread/pthread_condattr_destroy.c | 0 .../pthread/pthread_condattr_getpshared.c | 0 .../pthread/pthread_condattr_init.c | 0 .../pthread/pthread_condattr_setpshared.c | 0 src/{ => compat}/pthread/pthread_delay_np.c | 0 src/{ => compat}/pthread/pthread_detach.c | 0 src/{ => compat}/pthread/pthread_equal.c | 0 src/{ => compat}/pthread/pthread_exit.c | 0 .../pthread/pthread_getconcurrency.c | 0 .../pthread/pthread_getschedparam.c | 0 .../pthread/pthread_getspecific.c | 0 src/{ => compat}/pthread/pthread_init.c | 0 src/{ => compat}/pthread/pthread_join.c | 0 src/{ => compat}/pthread/pthread_key_create.c | 0 src/{ => compat}/pthread/pthread_key_delete.c | 0 src/{ => compat}/pthread/pthread_kill.c | 0 .../pthread/pthread_mutex_destroy.c | 0 src/{ => compat}/pthread/pthread_mutex_init.c | 0 src/{ => compat}/pthread/pthread_mutex_lock.c | 0 .../pthread/pthread_mutex_timedlock.c | 0 .../pthread/pthread_mutex_trylock.c | 0 .../pthread/pthread_mutex_unlock.c | 0 .../pthread/pthread_mutexattr_destroy.c | 0 .../pthread/pthread_mutexattr_getkind_np.c | 0 .../pthread/pthread_mutexattr_getpshared.c | 0 .../pthread/pthread_mutexattr_gettype.c | 0 .../pthread/pthread_mutexattr_init.c | 0 .../pthread/pthread_mutexattr_setkind_np.c | 0 .../pthread/pthread_mutexattr_setpshared.c | 0 .../pthread/pthread_mutexattr_settype.c | 0 .../pthread/pthread_num_processors_np.c | 0 src/{ => compat}/pthread/pthread_once.c | 0 .../pthread/pthread_rwlock_destroy.c | 0 .../pthread/pthread_rwlock_init.c | 0 .../pthread/pthread_rwlock_rdlock.c | 0 .../pthread/pthread_rwlock_timedrdlock.c | 0 .../pthread/pthread_rwlock_timedwrlock.c | 0 .../pthread/pthread_rwlock_tryrdlock.c | 0 .../pthread/pthread_rwlock_trywrlock.c | 0 .../pthread/pthread_rwlock_unlock.c | 0 .../pthread/pthread_rwlock_wrlock.c | 0 .../pthread/pthread_rwlockattr_destroy.c | 0 .../pthread/pthread_rwlockattr_getpshared.c | 0 .../pthread/pthread_rwlockattr_init.c | 0 .../pthread/pthread_rwlockattr_setpshared.c | 0 src/{ => compat}/pthread/pthread_self.c | 0 .../pthread/pthread_setcancelstate.c | 0 .../pthread/pthread_setcanceltype.c | 0 .../pthread/pthread_setconcurrency.c | 0 .../pthread/pthread_setschedparam.c | 0 .../pthread/pthread_setspecific.c | 0 .../pthread/pthread_spin_destroy.c | 0 src/{ => compat}/pthread/pthread_spin_init.c | 0 src/{ => compat}/pthread/pthread_spin_lock.c | 0 .../pthread/pthread_spin_trylock.c | 0 .../pthread/pthread_spin_unlock.c | 0 src/{ => compat}/pthread/pthread_terminate.c | 0 src/{ => compat}/pthread/pthread_testcancel.c | 0 .../pthread/pthread_timechange_handler_np.c | 0 src/{ => compat}/pthread/sched.h | 0 .../pthread/sched_get_priority_max.c | 0 .../pthread/sched_get_priority_min.c | 0 src/{ => compat}/pthread/sched_setscheduler.c | 0 src/{ => compat}/pthread/sched_yield.c | 0 src/{ => compat}/pthread/sem_close.c | 0 src/{ => compat}/pthread/sem_destroy.c | 0 src/{ => compat}/pthread/sem_getvalue.c | 0 src/{ => compat}/pthread/sem_init.c | 0 src/{ => compat}/pthread/sem_open.c | 0 src/{ => compat}/pthread/sem_post.c | 0 src/{ => compat}/pthread/sem_post_multiple.c | 0 src/{ => compat}/pthread/sem_timedwait.c | 0 src/{ => compat}/pthread/sem_trywait.c | 0 src/{ => compat}/pthread/sem_unlink.c | 0 src/{ => compat}/pthread/sem_wait.c | 0 src/{ => compat}/pthread/semaphore.h | 0 src/{ => compat}/pthread/tests/ChangeLog | 0 src/{ => compat}/pthread/tests/barrier1.c | 0 src/{ => compat}/pthread/tests/barrier2.c | 0 src/{ => compat}/pthread/tests/barrier3.c | 0 src/{ => compat}/pthread/tests/barrier4.c | 0 src/{ => compat}/pthread/tests/barrier5.c | 0 src/{ => compat}/pthread/tests/benchlib.c | 0 src/{ => compat}/pthread/tests/benchtest.h | 0 src/{ => compat}/pthread/tests/benchtest1.c | 0 src/{ => compat}/pthread/tests/benchtest2.c | 0 src/{ => compat}/pthread/tests/benchtest3.c | 0 src/{ => compat}/pthread/tests/benchtest4.c | 0 src/{ => compat}/pthread/tests/benchtest5.c | 0 src/{ => compat}/pthread/tests/cancel1.c | 0 src/{ => compat}/pthread/tests/cancel2.c | 0 src/{ => compat}/pthread/tests/cancel3.c | 0 src/{ => compat}/pthread/tests/cancel4.c | 0 src/{ => compat}/pthread/tests/cancel5.c | 0 src/{ => compat}/pthread/tests/cancel6a.c | 0 src/{ => compat}/pthread/tests/cancel6d.c | 0 src/{ => compat}/pthread/tests/cleanup0.c | 0 src/{ => compat}/pthread/tests/cleanup1.c | 0 src/{ => compat}/pthread/tests/cleanup2.c | 0 src/{ => compat}/pthread/tests/cleanup3.c | 0 src/{ => compat}/pthread/tests/condvar1.c | 0 src/{ => compat}/pthread/tests/condvar1_1.c | 0 src/{ => compat}/pthread/tests/condvar1_2.c | 0 src/{ => compat}/pthread/tests/condvar2.c | 0 src/{ => compat}/pthread/tests/condvar2_1.c | 0 src/{ => compat}/pthread/tests/condvar3.c | 0 src/{ => compat}/pthread/tests/condvar3_1.c | 0 src/{ => compat}/pthread/tests/condvar3_2.c | 0 src/{ => compat}/pthread/tests/condvar3_3.c | 0 src/{ => compat}/pthread/tests/condvar4.c | 0 src/{ => compat}/pthread/tests/condvar5.c | 0 src/{ => compat}/pthread/tests/condvar6.c | 0 src/{ => compat}/pthread/tests/condvar7.c | 0 src/{ => compat}/pthread/tests/condvar8.c | 0 src/{ => compat}/pthread/tests/condvar9.c | 0 src/{ => compat}/pthread/tests/count1.c | 0 src/{ => compat}/pthread/tests/create1.c | 0 src/{ => compat}/pthread/tests/create2.c | 0 src/{ => compat}/pthread/tests/create3.c | 0 src/{ => compat}/pthread/tests/delay1.c | 0 src/{ => compat}/pthread/tests/delay2.c | 0 src/{ => compat}/pthread/tests/detach1.c | 0 src/{ => compat}/pthread/tests/equal1.c | 0 src/{ => compat}/pthread/tests/errno1.c | 0 src/{ => compat}/pthread/tests/exception1.c | 0 src/{ => compat}/pthread/tests/exception2.c | 0 src/{ => compat}/pthread/tests/exception3.c | 0 src/{ => compat}/pthread/tests/exit1.c | 0 src/{ => compat}/pthread/tests/exit2.c | 0 src/{ => compat}/pthread/tests/exit3.c | 0 src/{ => compat}/pthread/tests/exit4.c | 0 src/{ => compat}/pthread/tests/exit5.c | 0 src/{ => compat}/pthread/tests/inherit1.c | 0 src/{ => compat}/pthread/tests/join0.c | 0 src/{ => compat}/pthread/tests/join1.c | 0 src/{ => compat}/pthread/tests/join2.c | 0 src/{ => compat}/pthread/tests/join3.c | 0 src/{ => compat}/pthread/tests/join4.c | 0 src/{ => compat}/pthread/tests/kill1.c | 0 src/{ => compat}/pthread/tests/mutex1.c | 0 src/{ => compat}/pthread/tests/mutex1e.c | 0 src/{ => compat}/pthread/tests/mutex1n.c | 0 src/{ => compat}/pthread/tests/mutex1r.c | 0 src/{ => compat}/pthread/tests/mutex2.c | 0 src/{ => compat}/pthread/tests/mutex2e.c | 0 src/{ => compat}/pthread/tests/mutex2r.c | 0 src/{ => compat}/pthread/tests/mutex3.c | 0 src/{ => compat}/pthread/tests/mutex3e.c | 0 src/{ => compat}/pthread/tests/mutex3r.c | 0 src/{ => compat}/pthread/tests/mutex4.c | 0 src/{ => compat}/pthread/tests/mutex5.c | 0 src/{ => compat}/pthread/tests/mutex6.c | 0 src/{ => compat}/pthread/tests/mutex6e.c | 0 src/{ => compat}/pthread/tests/mutex6es.c | 0 src/{ => compat}/pthread/tests/mutex6n.c | 0 src/{ => compat}/pthread/tests/mutex6r.c | 0 src/{ => compat}/pthread/tests/mutex6rs.c | 0 src/{ => compat}/pthread/tests/mutex6s.c | 0 src/{ => compat}/pthread/tests/mutex7.c | 0 src/{ => compat}/pthread/tests/mutex7e.c | 0 src/{ => compat}/pthread/tests/mutex7n.c | 0 src/{ => compat}/pthread/tests/mutex7r.c | 0 src/{ => compat}/pthread/tests/mutex8.c | 0 src/{ => compat}/pthread/tests/mutex8e.c | 0 src/{ => compat}/pthread/tests/mutex8n.c | 0 src/{ => compat}/pthread/tests/mutex8r.c | 0 src/{ => compat}/pthread/tests/once1.c | 0 src/{ => compat}/pthread/tests/once2.c | 0 src/{ => compat}/pthread/tests/once3.c | 0 src/{ => compat}/pthread/tests/once4.c | 0 src/{ => compat}/pthread/tests/priority1.c | 0 src/{ => compat}/pthread/tests/priority2.c | 0 src/{ => compat}/pthread/tests/reuse1.c | 0 src/{ => compat}/pthread/tests/reuse2.c | 0 src/{ => compat}/pthread/tests/rwlock1.c | 0 src/{ => compat}/pthread/tests/rwlock2.c | 0 src/{ => compat}/pthread/tests/rwlock2_t.c | 0 src/{ => compat}/pthread/tests/rwlock3.c | 0 src/{ => compat}/pthread/tests/rwlock3_t.c | 0 src/{ => compat}/pthread/tests/rwlock4.c | 0 src/{ => compat}/pthread/tests/rwlock4_t.c | 0 src/{ => compat}/pthread/tests/rwlock5.c | 0 src/{ => compat}/pthread/tests/rwlock5_t.c | 0 src/{ => compat}/pthread/tests/rwlock6.c | 0 src/{ => compat}/pthread/tests/rwlock6_t.c | 0 src/{ => compat}/pthread/tests/rwlock6_t2.c | 0 src/{ => compat}/pthread/tests/rwlock7.c | 0 src/{ => compat}/pthread/tests/rwlock8.c | 0 src/{ => compat}/pthread/tests/self1.c | 0 src/{ => compat}/pthread/tests/self2.c | 0 src/{ => compat}/pthread/tests/semaphore1.c | 0 src/{ => compat}/pthread/tests/semaphore2.c | 0 src/{ => compat}/pthread/tests/semaphore3.c | 0 src/{ => compat}/pthread/tests/semaphore4.c | 0 src/{ => compat}/pthread/tests/semaphore4t.c | 0 src/{ => compat}/pthread/tests/semaphore5.c | 0 src/{ => compat}/pthread/tests/semaphore6.c | 0 src/{ => compat}/pthread/tests/spin1.c | 0 src/{ => compat}/pthread/tests/spin2.c | 0 src/{ => compat}/pthread/tests/spin3.c | 0 src/{ => compat}/pthread/tests/spin4.c | 0 src/{ => compat}/pthread/tests/stress1.c | 0 src/{ => compat}/pthread/tests/test.h | 0 src/{ => compat}/pthread/tests/test_main.c | 0 src/{ => compat}/pthread/tests/tsd1.c | 0 src/{ => compat}/pthread/tests/tsd2.c | 0 src/{ => compat}/pthread/tests/valid1.c | 0 src/{ => compat}/pthread/tests/valid2.c | 0 src/{ => compat}/pthread/tls-helper.c | 0 src/{ => compat}/pthread/tls-helper.h | 0 src/pthread/platform/nautilus/Makefile~ | 194 ------------------ 314 files changed, 194 deletions(-) rename src/{ => compat}/pthread/ANNOUNCE (100%) rename src/{ => compat}/pthread/CONTRIBUTORS.ptw32 (100%) rename src/{ => compat}/pthread/COPYING (100%) rename src/{ => compat}/pthread/COPYING.LIB (100%) rename src/{ => compat}/pthread/Makefile (100%) rename src/{ => compat}/pthread/Makefile.PSP (100%) rename src/{ => compat}/pthread/cleanup.c (100%) rename src/{ => compat}/pthread/create.c (100%) rename src/{ => compat}/pthread/doc/Doxyfile (100%) rename src/{ => compat}/pthread/doc/doxygen.css (100%) rename src/{ => compat}/pthread/doc/pte_dspbios.html (100%) rename src/{ => compat}/pthread/doc/pte_main.html (100%) rename src/{ => compat}/pthread/doc/pte_osal_api.html (100%) rename src/{ => compat}/pthread/doc/pte_porting_guide.html (100%) rename src/{ => compat}/pthread/doc/pte_psp.html (100%) rename src/{ => compat}/pthread/doc/pte_users_guide.html (100%) rename src/{ => compat}/pthread/global.c (100%) rename src/{ => compat}/pthread/implement.h (100%) rename src/{ => compat}/pthread/nautilus_osal.c (100%) rename src/{ => compat}/pthread/nautilus_osal.h (100%) rename src/{ => compat}/pthread/need_errno.h (100%) rename src/{ => compat}/pthread/platform/dspbios/dspbios-config.h (100%) rename src/{ => compat}/pthread/platform/dspbios/dspbios-osal.c (100%) rename src/{ => compat}/pthread/platform/dspbios/dspbios-osal.h (100%) rename src/{ => compat}/pthread/platform/dspbios/main.c (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_lib/pte_lib.pjt (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_osal.h (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_test/Configuration1.cdb (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_test/Configuration1.tcf (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_test/Configuration1.tco (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_test/pte_test.pjt (100%) rename src/{ => compat}/pthread/platform/dspbios/pte_types.h (100%) rename src/{ => compat}/pthread/platform/helper/tls-helper.c (100%) rename src/{ => compat}/pthread/platform/helper/tls-helper.h (100%) rename src/{ => compat}/pthread/platform/nautilus/Makefile (100%) rename src/{ => compat}/pthread/platform/nautilus/Makefile.tests (100%) rename src/{pthread => compat/pthread/platform/nautilus}/Makefile~ (100%) rename src/{ => compat}/pthread/platform/nautilus/main.c (100%) rename src/{ => compat}/pthread/platform/nautilus/nautilus_osal.c (100%) rename src/{ => compat}/pthread/platform/nautilus/nautilus_osal.h (100%) rename src/{ => compat}/pthread/platform/nautilus/nautilus_osal.h~ (100%) rename src/{ => compat}/pthread/platform/nautilus/psp_osal.c (100%) rename src/{ => compat}/pthread/platform/nautilus/psp_osal.h (100%) rename src/{ => compat}/pthread/platform/nautilus/pte_osal.h (100%) rename src/{ => compat}/pthread/platform/nautilus/pte_osal.h~ (100%) rename src/{ => compat}/pthread/platform/nautilus/pte_types.h (100%) rename src/{ => compat}/pthread/platform/psp/Makefile (100%) rename src/{ => compat}/pthread/platform/psp/Makefile.tests (100%) rename src/{ => compat}/pthread/platform/psp/main.c (100%) rename src/{ => compat}/pthread/platform/psp/psp_osal.c (100%) rename src/{ => compat}/pthread/platform/psp/psp_osal.h (100%) rename src/{ => compat}/pthread/platform/psp/pte_osal.h (100%) rename src/{ => compat}/pthread/platform/psp/pte_types.h (100%) rename src/{ => compat}/pthread/pte_callUserDestroyRoutines.c (100%) rename src/{ => compat}/pthread/pte_cancellable_wait.c (100%) rename src/{ => compat}/pthread/pte_cond_check_need_init.c (100%) rename src/{ => compat}/pthread/pte_detach.c (100%) rename src/{ => compat}/pthread/pte_generic_osal.h (100%) rename src/{ => compat}/pthread/pte_getprocessors.c (100%) rename src/{ => compat}/pthread/pte_is_attr.c (100%) rename src/{ => compat}/pthread/pte_mutex_check_need_init.c (100%) rename src/{ => compat}/pthread/pte_new.c (100%) rename src/{ => compat}/pthread/pte_osal.h (100%) rename src/{ => compat}/pthread/pte_relmillisecs.c (100%) rename src/{ => compat}/pthread/pte_reuse.c (100%) rename src/{ => compat}/pthread/pte_rwlock_cancelwrwait.c (100%) rename src/{ => compat}/pthread/pte_rwlock_check_need_init.c (100%) rename src/{ => compat}/pthread/pte_spinlock_check_need_init.c (100%) rename src/{ => compat}/pthread/pte_threadDestroy.c (100%) rename src/{ => compat}/pthread/pte_threadStart.c (100%) rename src/{ => compat}/pthread/pte_throw.c (100%) rename src/{ => compat}/pthread/pte_tkAssocCreate.c (100%) rename src/{ => compat}/pthread/pte_tkAssocDestroy.c (100%) rename src/{ => compat}/pthread/pte_types.h (100%) rename src/{ => compat}/pthread/pthread.h (100%) rename src/{ => compat}/pthread/pthread_attr_destroy.c (100%) rename src/{ => compat}/pthread/pthread_attr_getdetachstate.c (100%) rename src/{ => compat}/pthread/pthread_attr_getinheritsched.c (100%) rename src/{ => compat}/pthread/pthread_attr_getschedparam.c (100%) rename src/{ => compat}/pthread/pthread_attr_getschedpolicy.c (100%) rename src/{ => compat}/pthread/pthread_attr_getscope.c (100%) rename src/{ => compat}/pthread/pthread_attr_getstackaddr.c (100%) rename src/{ => compat}/pthread/pthread_attr_getstacksize.c (100%) rename src/{ => compat}/pthread/pthread_attr_init.c (100%) rename src/{ => compat}/pthread/pthread_attr_setdetachstate.c (100%) rename src/{ => compat}/pthread/pthread_attr_setinheritsched.c (100%) rename src/{ => compat}/pthread/pthread_attr_setschedparam.c (100%) rename src/{ => compat}/pthread/pthread_attr_setschedpolicy.c (100%) rename src/{ => compat}/pthread/pthread_attr_setscope.c (100%) rename src/{ => compat}/pthread/pthread_attr_setstackaddr.c (100%) rename src/{ => compat}/pthread/pthread_attr_setstacksize.c (100%) rename src/{ => compat}/pthread/pthread_barrier_destroy.c (100%) rename src/{ => compat}/pthread/pthread_barrier_init.c (100%) rename src/{ => compat}/pthread/pthread_barrier_wait.c (100%) rename src/{ => compat}/pthread/pthread_barrierattr_destroy.c (100%) rename src/{ => compat}/pthread/pthread_barrierattr_getpshared.c (100%) rename src/{ => compat}/pthread/pthread_barrierattr_init.c (100%) rename src/{ => compat}/pthread/pthread_barrierattr_setpshared.c (100%) rename src/{ => compat}/pthread/pthread_cancel.c (100%) rename src/{ => compat}/pthread/pthread_cond_destroy.c (100%) rename src/{ => compat}/pthread/pthread_cond_init.c (100%) rename src/{ => compat}/pthread/pthread_cond_signal.c (100%) rename src/{ => compat}/pthread/pthread_cond_wait.c (100%) rename src/{ => compat}/pthread/pthread_condattr_destroy.c (100%) rename src/{ => compat}/pthread/pthread_condattr_getpshared.c (100%) rename src/{ => compat}/pthread/pthread_condattr_init.c (100%) rename src/{ => compat}/pthread/pthread_condattr_setpshared.c (100%) rename src/{ => compat}/pthread/pthread_delay_np.c (100%) rename src/{ => compat}/pthread/pthread_detach.c (100%) rename src/{ => compat}/pthread/pthread_equal.c (100%) rename src/{ => compat}/pthread/pthread_exit.c (100%) rename src/{ => compat}/pthread/pthread_getconcurrency.c (100%) rename src/{ => compat}/pthread/pthread_getschedparam.c (100%) rename src/{ => compat}/pthread/pthread_getspecific.c (100%) rename src/{ => compat}/pthread/pthread_init.c (100%) rename src/{ => compat}/pthread/pthread_join.c (100%) rename src/{ => compat}/pthread/pthread_key_create.c (100%) rename src/{ => compat}/pthread/pthread_key_delete.c (100%) rename src/{ => compat}/pthread/pthread_kill.c (100%) rename src/{ => compat}/pthread/pthread_mutex_destroy.c (100%) rename src/{ => compat}/pthread/pthread_mutex_init.c (100%) rename src/{ => compat}/pthread/pthread_mutex_lock.c (100%) rename src/{ => compat}/pthread/pthread_mutex_timedlock.c (100%) rename src/{ => compat}/pthread/pthread_mutex_trylock.c (100%) rename src/{ => compat}/pthread/pthread_mutex_unlock.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_destroy.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_getkind_np.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_getpshared.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_gettype.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_init.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_setkind_np.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_setpshared.c (100%) rename src/{ => compat}/pthread/pthread_mutexattr_settype.c (100%) rename src/{ => compat}/pthread/pthread_num_processors_np.c (100%) rename src/{ => compat}/pthread/pthread_once.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_destroy.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_init.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_rdlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_timedrdlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_timedwrlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_tryrdlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_trywrlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_unlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlock_wrlock.c (100%) rename src/{ => compat}/pthread/pthread_rwlockattr_destroy.c (100%) rename src/{ => compat}/pthread/pthread_rwlockattr_getpshared.c (100%) rename src/{ => compat}/pthread/pthread_rwlockattr_init.c (100%) rename src/{ => compat}/pthread/pthread_rwlockattr_setpshared.c (100%) rename src/{ => compat}/pthread/pthread_self.c (100%) rename src/{ => compat}/pthread/pthread_setcancelstate.c (100%) rename src/{ => compat}/pthread/pthread_setcanceltype.c (100%) rename src/{ => compat}/pthread/pthread_setconcurrency.c (100%) rename src/{ => compat}/pthread/pthread_setschedparam.c (100%) rename src/{ => compat}/pthread/pthread_setspecific.c (100%) rename src/{ => compat}/pthread/pthread_spin_destroy.c (100%) rename src/{ => compat}/pthread/pthread_spin_init.c (100%) rename src/{ => compat}/pthread/pthread_spin_lock.c (100%) rename src/{ => compat}/pthread/pthread_spin_trylock.c (100%) rename src/{ => compat}/pthread/pthread_spin_unlock.c (100%) rename src/{ => compat}/pthread/pthread_terminate.c (100%) rename src/{ => compat}/pthread/pthread_testcancel.c (100%) rename src/{ => compat}/pthread/pthread_timechange_handler_np.c (100%) rename src/{ => compat}/pthread/sched.h (100%) rename src/{ => compat}/pthread/sched_get_priority_max.c (100%) rename src/{ => compat}/pthread/sched_get_priority_min.c (100%) rename src/{ => compat}/pthread/sched_setscheduler.c (100%) rename src/{ => compat}/pthread/sched_yield.c (100%) rename src/{ => compat}/pthread/sem_close.c (100%) rename src/{ => compat}/pthread/sem_destroy.c (100%) rename src/{ => compat}/pthread/sem_getvalue.c (100%) rename src/{ => compat}/pthread/sem_init.c (100%) rename src/{ => compat}/pthread/sem_open.c (100%) rename src/{ => compat}/pthread/sem_post.c (100%) rename src/{ => compat}/pthread/sem_post_multiple.c (100%) rename src/{ => compat}/pthread/sem_timedwait.c (100%) rename src/{ => compat}/pthread/sem_trywait.c (100%) rename src/{ => compat}/pthread/sem_unlink.c (100%) rename src/{ => compat}/pthread/sem_wait.c (100%) rename src/{ => compat}/pthread/semaphore.h (100%) rename src/{ => compat}/pthread/tests/ChangeLog (100%) rename src/{ => compat}/pthread/tests/barrier1.c (100%) rename src/{ => compat}/pthread/tests/barrier2.c (100%) rename src/{ => compat}/pthread/tests/barrier3.c (100%) rename src/{ => compat}/pthread/tests/barrier4.c (100%) rename src/{ => compat}/pthread/tests/barrier5.c (100%) rename src/{ => compat}/pthread/tests/benchlib.c (100%) rename src/{ => compat}/pthread/tests/benchtest.h (100%) rename src/{ => compat}/pthread/tests/benchtest1.c (100%) rename src/{ => compat}/pthread/tests/benchtest2.c (100%) rename src/{ => compat}/pthread/tests/benchtest3.c (100%) rename src/{ => compat}/pthread/tests/benchtest4.c (100%) rename src/{ => compat}/pthread/tests/benchtest5.c (100%) rename src/{ => compat}/pthread/tests/cancel1.c (100%) rename src/{ => compat}/pthread/tests/cancel2.c (100%) rename src/{ => compat}/pthread/tests/cancel3.c (100%) rename src/{ => compat}/pthread/tests/cancel4.c (100%) rename src/{ => compat}/pthread/tests/cancel5.c (100%) rename src/{ => compat}/pthread/tests/cancel6a.c (100%) rename src/{ => compat}/pthread/tests/cancel6d.c (100%) rename src/{ => compat}/pthread/tests/cleanup0.c (100%) rename src/{ => compat}/pthread/tests/cleanup1.c (100%) rename src/{ => compat}/pthread/tests/cleanup2.c (100%) rename src/{ => compat}/pthread/tests/cleanup3.c (100%) rename src/{ => compat}/pthread/tests/condvar1.c (100%) rename src/{ => compat}/pthread/tests/condvar1_1.c (100%) rename src/{ => compat}/pthread/tests/condvar1_2.c (100%) rename src/{ => compat}/pthread/tests/condvar2.c (100%) rename src/{ => compat}/pthread/tests/condvar2_1.c (100%) rename src/{ => compat}/pthread/tests/condvar3.c (100%) rename src/{ => compat}/pthread/tests/condvar3_1.c (100%) rename src/{ => compat}/pthread/tests/condvar3_2.c (100%) rename src/{ => compat}/pthread/tests/condvar3_3.c (100%) rename src/{ => compat}/pthread/tests/condvar4.c (100%) rename src/{ => compat}/pthread/tests/condvar5.c (100%) rename src/{ => compat}/pthread/tests/condvar6.c (100%) rename src/{ => compat}/pthread/tests/condvar7.c (100%) rename src/{ => compat}/pthread/tests/condvar8.c (100%) rename src/{ => compat}/pthread/tests/condvar9.c (100%) rename src/{ => compat}/pthread/tests/count1.c (100%) rename src/{ => compat}/pthread/tests/create1.c (100%) rename src/{ => compat}/pthread/tests/create2.c (100%) rename src/{ => compat}/pthread/tests/create3.c (100%) rename src/{ => compat}/pthread/tests/delay1.c (100%) rename src/{ => compat}/pthread/tests/delay2.c (100%) rename src/{ => compat}/pthread/tests/detach1.c (100%) rename src/{ => compat}/pthread/tests/equal1.c (100%) rename src/{ => compat}/pthread/tests/errno1.c (100%) rename src/{ => compat}/pthread/tests/exception1.c (100%) rename src/{ => compat}/pthread/tests/exception2.c (100%) rename src/{ => compat}/pthread/tests/exception3.c (100%) rename src/{ => compat}/pthread/tests/exit1.c (100%) rename src/{ => compat}/pthread/tests/exit2.c (100%) rename src/{ => compat}/pthread/tests/exit3.c (100%) rename src/{ => compat}/pthread/tests/exit4.c (100%) rename src/{ => compat}/pthread/tests/exit5.c (100%) rename src/{ => compat}/pthread/tests/inherit1.c (100%) rename src/{ => compat}/pthread/tests/join0.c (100%) rename src/{ => compat}/pthread/tests/join1.c (100%) rename src/{ => compat}/pthread/tests/join2.c (100%) rename src/{ => compat}/pthread/tests/join3.c (100%) rename src/{ => compat}/pthread/tests/join4.c (100%) rename src/{ => compat}/pthread/tests/kill1.c (100%) rename src/{ => compat}/pthread/tests/mutex1.c (100%) rename src/{ => compat}/pthread/tests/mutex1e.c (100%) rename src/{ => compat}/pthread/tests/mutex1n.c (100%) rename src/{ => compat}/pthread/tests/mutex1r.c (100%) rename src/{ => compat}/pthread/tests/mutex2.c (100%) rename src/{ => compat}/pthread/tests/mutex2e.c (100%) rename src/{ => compat}/pthread/tests/mutex2r.c (100%) rename src/{ => compat}/pthread/tests/mutex3.c (100%) rename src/{ => compat}/pthread/tests/mutex3e.c (100%) rename src/{ => compat}/pthread/tests/mutex3r.c (100%) rename src/{ => compat}/pthread/tests/mutex4.c (100%) rename src/{ => compat}/pthread/tests/mutex5.c (100%) rename src/{ => compat}/pthread/tests/mutex6.c (100%) rename src/{ => compat}/pthread/tests/mutex6e.c (100%) rename src/{ => compat}/pthread/tests/mutex6es.c (100%) rename src/{ => compat}/pthread/tests/mutex6n.c (100%) rename src/{ => compat}/pthread/tests/mutex6r.c (100%) rename src/{ => compat}/pthread/tests/mutex6rs.c (100%) rename src/{ => compat}/pthread/tests/mutex6s.c (100%) rename src/{ => compat}/pthread/tests/mutex7.c (100%) rename src/{ => compat}/pthread/tests/mutex7e.c (100%) rename src/{ => compat}/pthread/tests/mutex7n.c (100%) rename src/{ => compat}/pthread/tests/mutex7r.c (100%) rename src/{ => compat}/pthread/tests/mutex8.c (100%) rename src/{ => compat}/pthread/tests/mutex8e.c (100%) rename src/{ => compat}/pthread/tests/mutex8n.c (100%) rename src/{ => compat}/pthread/tests/mutex8r.c (100%) rename src/{ => compat}/pthread/tests/once1.c (100%) rename src/{ => compat}/pthread/tests/once2.c (100%) rename src/{ => compat}/pthread/tests/once3.c (100%) rename src/{ => compat}/pthread/tests/once4.c (100%) rename src/{ => compat}/pthread/tests/priority1.c (100%) rename src/{ => compat}/pthread/tests/priority2.c (100%) rename src/{ => compat}/pthread/tests/reuse1.c (100%) rename src/{ => compat}/pthread/tests/reuse2.c (100%) rename src/{ => compat}/pthread/tests/rwlock1.c (100%) rename src/{ => compat}/pthread/tests/rwlock2.c (100%) rename src/{ => compat}/pthread/tests/rwlock2_t.c (100%) rename src/{ => compat}/pthread/tests/rwlock3.c (100%) rename src/{ => compat}/pthread/tests/rwlock3_t.c (100%) rename src/{ => compat}/pthread/tests/rwlock4.c (100%) rename src/{ => compat}/pthread/tests/rwlock4_t.c (100%) rename src/{ => compat}/pthread/tests/rwlock5.c (100%) rename src/{ => compat}/pthread/tests/rwlock5_t.c (100%) rename src/{ => compat}/pthread/tests/rwlock6.c (100%) rename src/{ => compat}/pthread/tests/rwlock6_t.c (100%) rename src/{ => compat}/pthread/tests/rwlock6_t2.c (100%) rename src/{ => compat}/pthread/tests/rwlock7.c (100%) rename src/{ => compat}/pthread/tests/rwlock8.c (100%) rename src/{ => compat}/pthread/tests/self1.c (100%) rename src/{ => compat}/pthread/tests/self2.c (100%) rename src/{ => compat}/pthread/tests/semaphore1.c (100%) rename src/{ => compat}/pthread/tests/semaphore2.c (100%) rename src/{ => compat}/pthread/tests/semaphore3.c (100%) rename src/{ => compat}/pthread/tests/semaphore4.c (100%) rename src/{ => compat}/pthread/tests/semaphore4t.c (100%) rename src/{ => compat}/pthread/tests/semaphore5.c (100%) rename src/{ => compat}/pthread/tests/semaphore6.c (100%) rename src/{ => compat}/pthread/tests/spin1.c (100%) rename src/{ => compat}/pthread/tests/spin2.c (100%) rename src/{ => compat}/pthread/tests/spin3.c (100%) rename src/{ => compat}/pthread/tests/spin4.c (100%) rename src/{ => compat}/pthread/tests/stress1.c (100%) rename src/{ => compat}/pthread/tests/test.h (100%) rename src/{ => compat}/pthread/tests/test_main.c (100%) rename src/{ => compat}/pthread/tests/tsd1.c (100%) rename src/{ => compat}/pthread/tests/tsd2.c (100%) rename src/{ => compat}/pthread/tests/valid1.c (100%) rename src/{ => compat}/pthread/tests/valid2.c (100%) rename src/{ => compat}/pthread/tls-helper.c (100%) rename src/{ => compat}/pthread/tls-helper.h (100%) delete mode 100644 src/pthread/platform/nautilus/Makefile~ diff --git a/src/pthread/ANNOUNCE b/src/compat/pthread/ANNOUNCE similarity index 100% rename from src/pthread/ANNOUNCE rename to src/compat/pthread/ANNOUNCE diff --git a/src/pthread/CONTRIBUTORS.ptw32 b/src/compat/pthread/CONTRIBUTORS.ptw32 similarity index 100% rename from src/pthread/CONTRIBUTORS.ptw32 rename to src/compat/pthread/CONTRIBUTORS.ptw32 diff --git a/src/pthread/COPYING b/src/compat/pthread/COPYING similarity index 100% rename from src/pthread/COPYING rename to src/compat/pthread/COPYING diff --git a/src/pthread/COPYING.LIB b/src/compat/pthread/COPYING.LIB similarity index 100% rename from src/pthread/COPYING.LIB rename to src/compat/pthread/COPYING.LIB diff --git a/src/pthread/Makefile b/src/compat/pthread/Makefile similarity index 100% rename from src/pthread/Makefile rename to src/compat/pthread/Makefile diff --git a/src/pthread/Makefile.PSP b/src/compat/pthread/Makefile.PSP similarity index 100% rename from src/pthread/Makefile.PSP rename to src/compat/pthread/Makefile.PSP diff --git a/src/pthread/cleanup.c b/src/compat/pthread/cleanup.c similarity index 100% rename from src/pthread/cleanup.c rename to src/compat/pthread/cleanup.c diff --git a/src/pthread/create.c b/src/compat/pthread/create.c similarity index 100% rename from src/pthread/create.c rename to src/compat/pthread/create.c diff --git a/src/pthread/doc/Doxyfile b/src/compat/pthread/doc/Doxyfile similarity index 100% rename from src/pthread/doc/Doxyfile rename to src/compat/pthread/doc/Doxyfile diff --git a/src/pthread/doc/doxygen.css b/src/compat/pthread/doc/doxygen.css similarity index 100% rename from src/pthread/doc/doxygen.css rename to src/compat/pthread/doc/doxygen.css diff --git a/src/pthread/doc/pte_dspbios.html b/src/compat/pthread/doc/pte_dspbios.html similarity index 100% rename from src/pthread/doc/pte_dspbios.html rename to src/compat/pthread/doc/pte_dspbios.html diff --git a/src/pthread/doc/pte_main.html b/src/compat/pthread/doc/pte_main.html similarity index 100% rename from src/pthread/doc/pte_main.html rename to src/compat/pthread/doc/pte_main.html diff --git a/src/pthread/doc/pte_osal_api.html b/src/compat/pthread/doc/pte_osal_api.html similarity index 100% rename from src/pthread/doc/pte_osal_api.html rename to src/compat/pthread/doc/pte_osal_api.html diff --git a/src/pthread/doc/pte_porting_guide.html b/src/compat/pthread/doc/pte_porting_guide.html similarity index 100% rename from src/pthread/doc/pte_porting_guide.html rename to src/compat/pthread/doc/pte_porting_guide.html diff --git a/src/pthread/doc/pte_psp.html b/src/compat/pthread/doc/pte_psp.html similarity index 100% rename from src/pthread/doc/pte_psp.html rename to src/compat/pthread/doc/pte_psp.html diff --git a/src/pthread/doc/pte_users_guide.html b/src/compat/pthread/doc/pte_users_guide.html similarity index 100% rename from src/pthread/doc/pte_users_guide.html rename to src/compat/pthread/doc/pte_users_guide.html diff --git a/src/pthread/global.c b/src/compat/pthread/global.c similarity index 100% rename from src/pthread/global.c rename to src/compat/pthread/global.c diff --git a/src/pthread/implement.h b/src/compat/pthread/implement.h similarity index 100% rename from src/pthread/implement.h rename to src/compat/pthread/implement.h diff --git a/src/pthread/nautilus_osal.c b/src/compat/pthread/nautilus_osal.c similarity index 100% rename from src/pthread/nautilus_osal.c rename to src/compat/pthread/nautilus_osal.c diff --git a/src/pthread/nautilus_osal.h b/src/compat/pthread/nautilus_osal.h similarity index 100% rename from src/pthread/nautilus_osal.h rename to src/compat/pthread/nautilus_osal.h diff --git a/src/pthread/need_errno.h b/src/compat/pthread/need_errno.h similarity index 100% rename from src/pthread/need_errno.h rename to src/compat/pthread/need_errno.h diff --git a/src/pthread/platform/dspbios/dspbios-config.h b/src/compat/pthread/platform/dspbios/dspbios-config.h similarity index 100% rename from src/pthread/platform/dspbios/dspbios-config.h rename to src/compat/pthread/platform/dspbios/dspbios-config.h diff --git a/src/pthread/platform/dspbios/dspbios-osal.c b/src/compat/pthread/platform/dspbios/dspbios-osal.c similarity index 100% rename from src/pthread/platform/dspbios/dspbios-osal.c rename to src/compat/pthread/platform/dspbios/dspbios-osal.c diff --git a/src/pthread/platform/dspbios/dspbios-osal.h b/src/compat/pthread/platform/dspbios/dspbios-osal.h similarity index 100% rename from src/pthread/platform/dspbios/dspbios-osal.h rename to src/compat/pthread/platform/dspbios/dspbios-osal.h diff --git a/src/pthread/platform/dspbios/main.c b/src/compat/pthread/platform/dspbios/main.c similarity index 100% rename from src/pthread/platform/dspbios/main.c rename to src/compat/pthread/platform/dspbios/main.c diff --git a/src/pthread/platform/dspbios/pte_lib/pte_lib.pjt b/src/compat/pthread/platform/dspbios/pte_lib/pte_lib.pjt similarity index 100% rename from src/pthread/platform/dspbios/pte_lib/pte_lib.pjt rename to src/compat/pthread/platform/dspbios/pte_lib/pte_lib.pjt diff --git a/src/pthread/platform/dspbios/pte_osal.h b/src/compat/pthread/platform/dspbios/pte_osal.h similarity index 100% rename from src/pthread/platform/dspbios/pte_osal.h rename to src/compat/pthread/platform/dspbios/pte_osal.h diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.cdb b/src/compat/pthread/platform/dspbios/pte_test/Configuration1.cdb similarity index 100% rename from src/pthread/platform/dspbios/pte_test/Configuration1.cdb rename to src/compat/pthread/platform/dspbios/pte_test/Configuration1.cdb diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.tcf b/src/compat/pthread/platform/dspbios/pte_test/Configuration1.tcf similarity index 100% rename from src/pthread/platform/dspbios/pte_test/Configuration1.tcf rename to src/compat/pthread/platform/dspbios/pte_test/Configuration1.tcf diff --git a/src/pthread/platform/dspbios/pte_test/Configuration1.tco b/src/compat/pthread/platform/dspbios/pte_test/Configuration1.tco similarity index 100% rename from src/pthread/platform/dspbios/pte_test/Configuration1.tco rename to src/compat/pthread/platform/dspbios/pte_test/Configuration1.tco diff --git a/src/pthread/platform/dspbios/pte_test/pte_test.pjt b/src/compat/pthread/platform/dspbios/pte_test/pte_test.pjt similarity index 100% rename from src/pthread/platform/dspbios/pte_test/pte_test.pjt rename to src/compat/pthread/platform/dspbios/pte_test/pte_test.pjt diff --git a/src/pthread/platform/dspbios/pte_types.h b/src/compat/pthread/platform/dspbios/pte_types.h similarity index 100% rename from src/pthread/platform/dspbios/pte_types.h rename to src/compat/pthread/platform/dspbios/pte_types.h diff --git a/src/pthread/platform/helper/tls-helper.c b/src/compat/pthread/platform/helper/tls-helper.c similarity index 100% rename from src/pthread/platform/helper/tls-helper.c rename to src/compat/pthread/platform/helper/tls-helper.c diff --git a/src/pthread/platform/helper/tls-helper.h b/src/compat/pthread/platform/helper/tls-helper.h similarity index 100% rename from src/pthread/platform/helper/tls-helper.h rename to src/compat/pthread/platform/helper/tls-helper.h diff --git a/src/pthread/platform/nautilus/Makefile b/src/compat/pthread/platform/nautilus/Makefile similarity index 100% rename from src/pthread/platform/nautilus/Makefile rename to src/compat/pthread/platform/nautilus/Makefile diff --git a/src/pthread/platform/nautilus/Makefile.tests b/src/compat/pthread/platform/nautilus/Makefile.tests similarity index 100% rename from src/pthread/platform/nautilus/Makefile.tests rename to src/compat/pthread/platform/nautilus/Makefile.tests diff --git a/src/pthread/Makefile~ b/src/compat/pthread/platform/nautilus/Makefile~ similarity index 100% rename from src/pthread/Makefile~ rename to src/compat/pthread/platform/nautilus/Makefile~ diff --git a/src/pthread/platform/nautilus/main.c b/src/compat/pthread/platform/nautilus/main.c similarity index 100% rename from src/pthread/platform/nautilus/main.c rename to src/compat/pthread/platform/nautilus/main.c diff --git a/src/pthread/platform/nautilus/nautilus_osal.c b/src/compat/pthread/platform/nautilus/nautilus_osal.c similarity index 100% rename from src/pthread/platform/nautilus/nautilus_osal.c rename to src/compat/pthread/platform/nautilus/nautilus_osal.c diff --git a/src/pthread/platform/nautilus/nautilus_osal.h b/src/compat/pthread/platform/nautilus/nautilus_osal.h similarity index 100% rename from src/pthread/platform/nautilus/nautilus_osal.h rename to src/compat/pthread/platform/nautilus/nautilus_osal.h diff --git a/src/pthread/platform/nautilus/nautilus_osal.h~ b/src/compat/pthread/platform/nautilus/nautilus_osal.h~ similarity index 100% rename from src/pthread/platform/nautilus/nautilus_osal.h~ rename to src/compat/pthread/platform/nautilus/nautilus_osal.h~ diff --git a/src/pthread/platform/nautilus/psp_osal.c b/src/compat/pthread/platform/nautilus/psp_osal.c similarity index 100% rename from src/pthread/platform/nautilus/psp_osal.c rename to src/compat/pthread/platform/nautilus/psp_osal.c diff --git a/src/pthread/platform/nautilus/psp_osal.h b/src/compat/pthread/platform/nautilus/psp_osal.h similarity index 100% rename from src/pthread/platform/nautilus/psp_osal.h rename to src/compat/pthread/platform/nautilus/psp_osal.h diff --git a/src/pthread/platform/nautilus/pte_osal.h b/src/compat/pthread/platform/nautilus/pte_osal.h similarity index 100% rename from src/pthread/platform/nautilus/pte_osal.h rename to src/compat/pthread/platform/nautilus/pte_osal.h diff --git a/src/pthread/platform/nautilus/pte_osal.h~ b/src/compat/pthread/platform/nautilus/pte_osal.h~ similarity index 100% rename from src/pthread/platform/nautilus/pte_osal.h~ rename to src/compat/pthread/platform/nautilus/pte_osal.h~ diff --git a/src/pthread/platform/nautilus/pte_types.h b/src/compat/pthread/platform/nautilus/pte_types.h similarity index 100% rename from src/pthread/platform/nautilus/pte_types.h rename to src/compat/pthread/platform/nautilus/pte_types.h diff --git a/src/pthread/platform/psp/Makefile b/src/compat/pthread/platform/psp/Makefile similarity index 100% rename from src/pthread/platform/psp/Makefile rename to src/compat/pthread/platform/psp/Makefile diff --git a/src/pthread/platform/psp/Makefile.tests b/src/compat/pthread/platform/psp/Makefile.tests similarity index 100% rename from src/pthread/platform/psp/Makefile.tests rename to src/compat/pthread/platform/psp/Makefile.tests diff --git a/src/pthread/platform/psp/main.c b/src/compat/pthread/platform/psp/main.c similarity index 100% rename from src/pthread/platform/psp/main.c rename to src/compat/pthread/platform/psp/main.c diff --git a/src/pthread/platform/psp/psp_osal.c b/src/compat/pthread/platform/psp/psp_osal.c similarity index 100% rename from src/pthread/platform/psp/psp_osal.c rename to src/compat/pthread/platform/psp/psp_osal.c diff --git a/src/pthread/platform/psp/psp_osal.h b/src/compat/pthread/platform/psp/psp_osal.h similarity index 100% rename from src/pthread/platform/psp/psp_osal.h rename to src/compat/pthread/platform/psp/psp_osal.h diff --git a/src/pthread/platform/psp/pte_osal.h b/src/compat/pthread/platform/psp/pte_osal.h similarity index 100% rename from src/pthread/platform/psp/pte_osal.h rename to src/compat/pthread/platform/psp/pte_osal.h diff --git a/src/pthread/platform/psp/pte_types.h b/src/compat/pthread/platform/psp/pte_types.h similarity index 100% rename from src/pthread/platform/psp/pte_types.h rename to src/compat/pthread/platform/psp/pte_types.h diff --git a/src/pthread/pte_callUserDestroyRoutines.c b/src/compat/pthread/pte_callUserDestroyRoutines.c similarity index 100% rename from src/pthread/pte_callUserDestroyRoutines.c rename to src/compat/pthread/pte_callUserDestroyRoutines.c diff --git a/src/pthread/pte_cancellable_wait.c b/src/compat/pthread/pte_cancellable_wait.c similarity index 100% rename from src/pthread/pte_cancellable_wait.c rename to src/compat/pthread/pte_cancellable_wait.c diff --git a/src/pthread/pte_cond_check_need_init.c b/src/compat/pthread/pte_cond_check_need_init.c similarity index 100% rename from src/pthread/pte_cond_check_need_init.c rename to src/compat/pthread/pte_cond_check_need_init.c diff --git a/src/pthread/pte_detach.c b/src/compat/pthread/pte_detach.c similarity index 100% rename from src/pthread/pte_detach.c rename to src/compat/pthread/pte_detach.c diff --git a/src/pthread/pte_generic_osal.h b/src/compat/pthread/pte_generic_osal.h similarity index 100% rename from src/pthread/pte_generic_osal.h rename to src/compat/pthread/pte_generic_osal.h diff --git a/src/pthread/pte_getprocessors.c b/src/compat/pthread/pte_getprocessors.c similarity index 100% rename from src/pthread/pte_getprocessors.c rename to src/compat/pthread/pte_getprocessors.c diff --git a/src/pthread/pte_is_attr.c b/src/compat/pthread/pte_is_attr.c similarity index 100% rename from src/pthread/pte_is_attr.c rename to src/compat/pthread/pte_is_attr.c diff --git a/src/pthread/pte_mutex_check_need_init.c b/src/compat/pthread/pte_mutex_check_need_init.c similarity index 100% rename from src/pthread/pte_mutex_check_need_init.c rename to src/compat/pthread/pte_mutex_check_need_init.c diff --git a/src/pthread/pte_new.c b/src/compat/pthread/pte_new.c similarity index 100% rename from src/pthread/pte_new.c rename to src/compat/pthread/pte_new.c diff --git a/src/pthread/pte_osal.h b/src/compat/pthread/pte_osal.h similarity index 100% rename from src/pthread/pte_osal.h rename to src/compat/pthread/pte_osal.h diff --git a/src/pthread/pte_relmillisecs.c b/src/compat/pthread/pte_relmillisecs.c similarity index 100% rename from src/pthread/pte_relmillisecs.c rename to src/compat/pthread/pte_relmillisecs.c diff --git a/src/pthread/pte_reuse.c b/src/compat/pthread/pte_reuse.c similarity index 100% rename from src/pthread/pte_reuse.c rename to src/compat/pthread/pte_reuse.c diff --git a/src/pthread/pte_rwlock_cancelwrwait.c b/src/compat/pthread/pte_rwlock_cancelwrwait.c similarity index 100% rename from src/pthread/pte_rwlock_cancelwrwait.c rename to src/compat/pthread/pte_rwlock_cancelwrwait.c diff --git a/src/pthread/pte_rwlock_check_need_init.c b/src/compat/pthread/pte_rwlock_check_need_init.c similarity index 100% rename from src/pthread/pte_rwlock_check_need_init.c rename to src/compat/pthread/pte_rwlock_check_need_init.c diff --git a/src/pthread/pte_spinlock_check_need_init.c b/src/compat/pthread/pte_spinlock_check_need_init.c similarity index 100% rename from src/pthread/pte_spinlock_check_need_init.c rename to src/compat/pthread/pte_spinlock_check_need_init.c diff --git a/src/pthread/pte_threadDestroy.c b/src/compat/pthread/pte_threadDestroy.c similarity index 100% rename from src/pthread/pte_threadDestroy.c rename to src/compat/pthread/pte_threadDestroy.c diff --git a/src/pthread/pte_threadStart.c b/src/compat/pthread/pte_threadStart.c similarity index 100% rename from src/pthread/pte_threadStart.c rename to src/compat/pthread/pte_threadStart.c diff --git a/src/pthread/pte_throw.c b/src/compat/pthread/pte_throw.c similarity index 100% rename from src/pthread/pte_throw.c rename to src/compat/pthread/pte_throw.c diff --git a/src/pthread/pte_tkAssocCreate.c b/src/compat/pthread/pte_tkAssocCreate.c similarity index 100% rename from src/pthread/pte_tkAssocCreate.c rename to src/compat/pthread/pte_tkAssocCreate.c diff --git a/src/pthread/pte_tkAssocDestroy.c b/src/compat/pthread/pte_tkAssocDestroy.c similarity index 100% rename from src/pthread/pte_tkAssocDestroy.c rename to src/compat/pthread/pte_tkAssocDestroy.c diff --git a/src/pthread/pte_types.h b/src/compat/pthread/pte_types.h similarity index 100% rename from src/pthread/pte_types.h rename to src/compat/pthread/pte_types.h diff --git a/src/pthread/pthread.h b/src/compat/pthread/pthread.h similarity index 100% rename from src/pthread/pthread.h rename to src/compat/pthread/pthread.h diff --git a/src/pthread/pthread_attr_destroy.c b/src/compat/pthread/pthread_attr_destroy.c similarity index 100% rename from src/pthread/pthread_attr_destroy.c rename to src/compat/pthread/pthread_attr_destroy.c diff --git a/src/pthread/pthread_attr_getdetachstate.c b/src/compat/pthread/pthread_attr_getdetachstate.c similarity index 100% rename from src/pthread/pthread_attr_getdetachstate.c rename to src/compat/pthread/pthread_attr_getdetachstate.c diff --git a/src/pthread/pthread_attr_getinheritsched.c b/src/compat/pthread/pthread_attr_getinheritsched.c similarity index 100% rename from src/pthread/pthread_attr_getinheritsched.c rename to src/compat/pthread/pthread_attr_getinheritsched.c diff --git a/src/pthread/pthread_attr_getschedparam.c b/src/compat/pthread/pthread_attr_getschedparam.c similarity index 100% rename from src/pthread/pthread_attr_getschedparam.c rename to src/compat/pthread/pthread_attr_getschedparam.c diff --git a/src/pthread/pthread_attr_getschedpolicy.c b/src/compat/pthread/pthread_attr_getschedpolicy.c similarity index 100% rename from src/pthread/pthread_attr_getschedpolicy.c rename to src/compat/pthread/pthread_attr_getschedpolicy.c diff --git a/src/pthread/pthread_attr_getscope.c b/src/compat/pthread/pthread_attr_getscope.c similarity index 100% rename from src/pthread/pthread_attr_getscope.c rename to src/compat/pthread/pthread_attr_getscope.c diff --git a/src/pthread/pthread_attr_getstackaddr.c b/src/compat/pthread/pthread_attr_getstackaddr.c similarity index 100% rename from src/pthread/pthread_attr_getstackaddr.c rename to src/compat/pthread/pthread_attr_getstackaddr.c diff --git a/src/pthread/pthread_attr_getstacksize.c b/src/compat/pthread/pthread_attr_getstacksize.c similarity index 100% rename from src/pthread/pthread_attr_getstacksize.c rename to src/compat/pthread/pthread_attr_getstacksize.c diff --git a/src/pthread/pthread_attr_init.c b/src/compat/pthread/pthread_attr_init.c similarity index 100% rename from src/pthread/pthread_attr_init.c rename to src/compat/pthread/pthread_attr_init.c diff --git a/src/pthread/pthread_attr_setdetachstate.c b/src/compat/pthread/pthread_attr_setdetachstate.c similarity index 100% rename from src/pthread/pthread_attr_setdetachstate.c rename to src/compat/pthread/pthread_attr_setdetachstate.c diff --git a/src/pthread/pthread_attr_setinheritsched.c b/src/compat/pthread/pthread_attr_setinheritsched.c similarity index 100% rename from src/pthread/pthread_attr_setinheritsched.c rename to src/compat/pthread/pthread_attr_setinheritsched.c diff --git a/src/pthread/pthread_attr_setschedparam.c b/src/compat/pthread/pthread_attr_setschedparam.c similarity index 100% rename from src/pthread/pthread_attr_setschedparam.c rename to src/compat/pthread/pthread_attr_setschedparam.c diff --git a/src/pthread/pthread_attr_setschedpolicy.c b/src/compat/pthread/pthread_attr_setschedpolicy.c similarity index 100% rename from src/pthread/pthread_attr_setschedpolicy.c rename to src/compat/pthread/pthread_attr_setschedpolicy.c diff --git a/src/pthread/pthread_attr_setscope.c b/src/compat/pthread/pthread_attr_setscope.c similarity index 100% rename from src/pthread/pthread_attr_setscope.c rename to src/compat/pthread/pthread_attr_setscope.c diff --git a/src/pthread/pthread_attr_setstackaddr.c b/src/compat/pthread/pthread_attr_setstackaddr.c similarity index 100% rename from src/pthread/pthread_attr_setstackaddr.c rename to src/compat/pthread/pthread_attr_setstackaddr.c diff --git a/src/pthread/pthread_attr_setstacksize.c b/src/compat/pthread/pthread_attr_setstacksize.c similarity index 100% rename from src/pthread/pthread_attr_setstacksize.c rename to src/compat/pthread/pthread_attr_setstacksize.c diff --git a/src/pthread/pthread_barrier_destroy.c b/src/compat/pthread/pthread_barrier_destroy.c similarity index 100% rename from src/pthread/pthread_barrier_destroy.c rename to src/compat/pthread/pthread_barrier_destroy.c diff --git a/src/pthread/pthread_barrier_init.c b/src/compat/pthread/pthread_barrier_init.c similarity index 100% rename from src/pthread/pthread_barrier_init.c rename to src/compat/pthread/pthread_barrier_init.c diff --git a/src/pthread/pthread_barrier_wait.c b/src/compat/pthread/pthread_barrier_wait.c similarity index 100% rename from src/pthread/pthread_barrier_wait.c rename to src/compat/pthread/pthread_barrier_wait.c diff --git a/src/pthread/pthread_barrierattr_destroy.c b/src/compat/pthread/pthread_barrierattr_destroy.c similarity index 100% rename from src/pthread/pthread_barrierattr_destroy.c rename to src/compat/pthread/pthread_barrierattr_destroy.c diff --git a/src/pthread/pthread_barrierattr_getpshared.c b/src/compat/pthread/pthread_barrierattr_getpshared.c similarity index 100% rename from src/pthread/pthread_barrierattr_getpshared.c rename to src/compat/pthread/pthread_barrierattr_getpshared.c diff --git a/src/pthread/pthread_barrierattr_init.c b/src/compat/pthread/pthread_barrierattr_init.c similarity index 100% rename from src/pthread/pthread_barrierattr_init.c rename to src/compat/pthread/pthread_barrierattr_init.c diff --git a/src/pthread/pthread_barrierattr_setpshared.c b/src/compat/pthread/pthread_barrierattr_setpshared.c similarity index 100% rename from src/pthread/pthread_barrierattr_setpshared.c rename to src/compat/pthread/pthread_barrierattr_setpshared.c diff --git a/src/pthread/pthread_cancel.c b/src/compat/pthread/pthread_cancel.c similarity index 100% rename from src/pthread/pthread_cancel.c rename to src/compat/pthread/pthread_cancel.c diff --git a/src/pthread/pthread_cond_destroy.c b/src/compat/pthread/pthread_cond_destroy.c similarity index 100% rename from src/pthread/pthread_cond_destroy.c rename to src/compat/pthread/pthread_cond_destroy.c diff --git a/src/pthread/pthread_cond_init.c b/src/compat/pthread/pthread_cond_init.c similarity index 100% rename from src/pthread/pthread_cond_init.c rename to src/compat/pthread/pthread_cond_init.c diff --git a/src/pthread/pthread_cond_signal.c b/src/compat/pthread/pthread_cond_signal.c similarity index 100% rename from src/pthread/pthread_cond_signal.c rename to src/compat/pthread/pthread_cond_signal.c diff --git a/src/pthread/pthread_cond_wait.c b/src/compat/pthread/pthread_cond_wait.c similarity index 100% rename from src/pthread/pthread_cond_wait.c rename to src/compat/pthread/pthread_cond_wait.c diff --git a/src/pthread/pthread_condattr_destroy.c b/src/compat/pthread/pthread_condattr_destroy.c similarity index 100% rename from src/pthread/pthread_condattr_destroy.c rename to src/compat/pthread/pthread_condattr_destroy.c diff --git a/src/pthread/pthread_condattr_getpshared.c b/src/compat/pthread/pthread_condattr_getpshared.c similarity index 100% rename from src/pthread/pthread_condattr_getpshared.c rename to src/compat/pthread/pthread_condattr_getpshared.c diff --git a/src/pthread/pthread_condattr_init.c b/src/compat/pthread/pthread_condattr_init.c similarity index 100% rename from src/pthread/pthread_condattr_init.c rename to src/compat/pthread/pthread_condattr_init.c diff --git a/src/pthread/pthread_condattr_setpshared.c b/src/compat/pthread/pthread_condattr_setpshared.c similarity index 100% rename from src/pthread/pthread_condattr_setpshared.c rename to src/compat/pthread/pthread_condattr_setpshared.c diff --git a/src/pthread/pthread_delay_np.c b/src/compat/pthread/pthread_delay_np.c similarity index 100% rename from src/pthread/pthread_delay_np.c rename to src/compat/pthread/pthread_delay_np.c diff --git a/src/pthread/pthread_detach.c b/src/compat/pthread/pthread_detach.c similarity index 100% rename from src/pthread/pthread_detach.c rename to src/compat/pthread/pthread_detach.c diff --git a/src/pthread/pthread_equal.c b/src/compat/pthread/pthread_equal.c similarity index 100% rename from src/pthread/pthread_equal.c rename to src/compat/pthread/pthread_equal.c diff --git a/src/pthread/pthread_exit.c b/src/compat/pthread/pthread_exit.c similarity index 100% rename from src/pthread/pthread_exit.c rename to src/compat/pthread/pthread_exit.c diff --git a/src/pthread/pthread_getconcurrency.c b/src/compat/pthread/pthread_getconcurrency.c similarity index 100% rename from src/pthread/pthread_getconcurrency.c rename to src/compat/pthread/pthread_getconcurrency.c diff --git a/src/pthread/pthread_getschedparam.c b/src/compat/pthread/pthread_getschedparam.c similarity index 100% rename from src/pthread/pthread_getschedparam.c rename to src/compat/pthread/pthread_getschedparam.c diff --git a/src/pthread/pthread_getspecific.c b/src/compat/pthread/pthread_getspecific.c similarity index 100% rename from src/pthread/pthread_getspecific.c rename to src/compat/pthread/pthread_getspecific.c diff --git a/src/pthread/pthread_init.c b/src/compat/pthread/pthread_init.c similarity index 100% rename from src/pthread/pthread_init.c rename to src/compat/pthread/pthread_init.c diff --git a/src/pthread/pthread_join.c b/src/compat/pthread/pthread_join.c similarity index 100% rename from src/pthread/pthread_join.c rename to src/compat/pthread/pthread_join.c diff --git a/src/pthread/pthread_key_create.c b/src/compat/pthread/pthread_key_create.c similarity index 100% rename from src/pthread/pthread_key_create.c rename to src/compat/pthread/pthread_key_create.c diff --git a/src/pthread/pthread_key_delete.c b/src/compat/pthread/pthread_key_delete.c similarity index 100% rename from src/pthread/pthread_key_delete.c rename to src/compat/pthread/pthread_key_delete.c diff --git a/src/pthread/pthread_kill.c b/src/compat/pthread/pthread_kill.c similarity index 100% rename from src/pthread/pthread_kill.c rename to src/compat/pthread/pthread_kill.c diff --git a/src/pthread/pthread_mutex_destroy.c b/src/compat/pthread/pthread_mutex_destroy.c similarity index 100% rename from src/pthread/pthread_mutex_destroy.c rename to src/compat/pthread/pthread_mutex_destroy.c diff --git a/src/pthread/pthread_mutex_init.c b/src/compat/pthread/pthread_mutex_init.c similarity index 100% rename from src/pthread/pthread_mutex_init.c rename to src/compat/pthread/pthread_mutex_init.c diff --git a/src/pthread/pthread_mutex_lock.c b/src/compat/pthread/pthread_mutex_lock.c similarity index 100% rename from src/pthread/pthread_mutex_lock.c rename to src/compat/pthread/pthread_mutex_lock.c diff --git a/src/pthread/pthread_mutex_timedlock.c b/src/compat/pthread/pthread_mutex_timedlock.c similarity index 100% rename from src/pthread/pthread_mutex_timedlock.c rename to src/compat/pthread/pthread_mutex_timedlock.c diff --git a/src/pthread/pthread_mutex_trylock.c b/src/compat/pthread/pthread_mutex_trylock.c similarity index 100% rename from src/pthread/pthread_mutex_trylock.c rename to src/compat/pthread/pthread_mutex_trylock.c diff --git a/src/pthread/pthread_mutex_unlock.c b/src/compat/pthread/pthread_mutex_unlock.c similarity index 100% rename from src/pthread/pthread_mutex_unlock.c rename to src/compat/pthread/pthread_mutex_unlock.c diff --git a/src/pthread/pthread_mutexattr_destroy.c b/src/compat/pthread/pthread_mutexattr_destroy.c similarity index 100% rename from src/pthread/pthread_mutexattr_destroy.c rename to src/compat/pthread/pthread_mutexattr_destroy.c diff --git a/src/pthread/pthread_mutexattr_getkind_np.c b/src/compat/pthread/pthread_mutexattr_getkind_np.c similarity index 100% rename from src/pthread/pthread_mutexattr_getkind_np.c rename to src/compat/pthread/pthread_mutexattr_getkind_np.c diff --git a/src/pthread/pthread_mutexattr_getpshared.c b/src/compat/pthread/pthread_mutexattr_getpshared.c similarity index 100% rename from src/pthread/pthread_mutexattr_getpshared.c rename to src/compat/pthread/pthread_mutexattr_getpshared.c diff --git a/src/pthread/pthread_mutexattr_gettype.c b/src/compat/pthread/pthread_mutexattr_gettype.c similarity index 100% rename from src/pthread/pthread_mutexattr_gettype.c rename to src/compat/pthread/pthread_mutexattr_gettype.c diff --git a/src/pthread/pthread_mutexattr_init.c b/src/compat/pthread/pthread_mutexattr_init.c similarity index 100% rename from src/pthread/pthread_mutexattr_init.c rename to src/compat/pthread/pthread_mutexattr_init.c diff --git a/src/pthread/pthread_mutexattr_setkind_np.c b/src/compat/pthread/pthread_mutexattr_setkind_np.c similarity index 100% rename from src/pthread/pthread_mutexattr_setkind_np.c rename to src/compat/pthread/pthread_mutexattr_setkind_np.c diff --git a/src/pthread/pthread_mutexattr_setpshared.c b/src/compat/pthread/pthread_mutexattr_setpshared.c similarity index 100% rename from src/pthread/pthread_mutexattr_setpshared.c rename to src/compat/pthread/pthread_mutexattr_setpshared.c diff --git a/src/pthread/pthread_mutexattr_settype.c b/src/compat/pthread/pthread_mutexattr_settype.c similarity index 100% rename from src/pthread/pthread_mutexattr_settype.c rename to src/compat/pthread/pthread_mutexattr_settype.c diff --git a/src/pthread/pthread_num_processors_np.c b/src/compat/pthread/pthread_num_processors_np.c similarity index 100% rename from src/pthread/pthread_num_processors_np.c rename to src/compat/pthread/pthread_num_processors_np.c diff --git a/src/pthread/pthread_once.c b/src/compat/pthread/pthread_once.c similarity index 100% rename from src/pthread/pthread_once.c rename to src/compat/pthread/pthread_once.c diff --git a/src/pthread/pthread_rwlock_destroy.c b/src/compat/pthread/pthread_rwlock_destroy.c similarity index 100% rename from src/pthread/pthread_rwlock_destroy.c rename to src/compat/pthread/pthread_rwlock_destroy.c diff --git a/src/pthread/pthread_rwlock_init.c b/src/compat/pthread/pthread_rwlock_init.c similarity index 100% rename from src/pthread/pthread_rwlock_init.c rename to src/compat/pthread/pthread_rwlock_init.c diff --git a/src/pthread/pthread_rwlock_rdlock.c b/src/compat/pthread/pthread_rwlock_rdlock.c similarity index 100% rename from src/pthread/pthread_rwlock_rdlock.c rename to src/compat/pthread/pthread_rwlock_rdlock.c diff --git a/src/pthread/pthread_rwlock_timedrdlock.c b/src/compat/pthread/pthread_rwlock_timedrdlock.c similarity index 100% rename from src/pthread/pthread_rwlock_timedrdlock.c rename to src/compat/pthread/pthread_rwlock_timedrdlock.c diff --git a/src/pthread/pthread_rwlock_timedwrlock.c b/src/compat/pthread/pthread_rwlock_timedwrlock.c similarity index 100% rename from src/pthread/pthread_rwlock_timedwrlock.c rename to src/compat/pthread/pthread_rwlock_timedwrlock.c diff --git a/src/pthread/pthread_rwlock_tryrdlock.c b/src/compat/pthread/pthread_rwlock_tryrdlock.c similarity index 100% rename from src/pthread/pthread_rwlock_tryrdlock.c rename to src/compat/pthread/pthread_rwlock_tryrdlock.c diff --git a/src/pthread/pthread_rwlock_trywrlock.c b/src/compat/pthread/pthread_rwlock_trywrlock.c similarity index 100% rename from src/pthread/pthread_rwlock_trywrlock.c rename to src/compat/pthread/pthread_rwlock_trywrlock.c diff --git a/src/pthread/pthread_rwlock_unlock.c b/src/compat/pthread/pthread_rwlock_unlock.c similarity index 100% rename from src/pthread/pthread_rwlock_unlock.c rename to src/compat/pthread/pthread_rwlock_unlock.c diff --git a/src/pthread/pthread_rwlock_wrlock.c b/src/compat/pthread/pthread_rwlock_wrlock.c similarity index 100% rename from src/pthread/pthread_rwlock_wrlock.c rename to src/compat/pthread/pthread_rwlock_wrlock.c diff --git a/src/pthread/pthread_rwlockattr_destroy.c b/src/compat/pthread/pthread_rwlockattr_destroy.c similarity index 100% rename from src/pthread/pthread_rwlockattr_destroy.c rename to src/compat/pthread/pthread_rwlockattr_destroy.c diff --git a/src/pthread/pthread_rwlockattr_getpshared.c b/src/compat/pthread/pthread_rwlockattr_getpshared.c similarity index 100% rename from src/pthread/pthread_rwlockattr_getpshared.c rename to src/compat/pthread/pthread_rwlockattr_getpshared.c diff --git a/src/pthread/pthread_rwlockattr_init.c b/src/compat/pthread/pthread_rwlockattr_init.c similarity index 100% rename from src/pthread/pthread_rwlockattr_init.c rename to src/compat/pthread/pthread_rwlockattr_init.c diff --git a/src/pthread/pthread_rwlockattr_setpshared.c b/src/compat/pthread/pthread_rwlockattr_setpshared.c similarity index 100% rename from src/pthread/pthread_rwlockattr_setpshared.c rename to src/compat/pthread/pthread_rwlockattr_setpshared.c diff --git a/src/pthread/pthread_self.c b/src/compat/pthread/pthread_self.c similarity index 100% rename from src/pthread/pthread_self.c rename to src/compat/pthread/pthread_self.c diff --git a/src/pthread/pthread_setcancelstate.c b/src/compat/pthread/pthread_setcancelstate.c similarity index 100% rename from src/pthread/pthread_setcancelstate.c rename to src/compat/pthread/pthread_setcancelstate.c diff --git a/src/pthread/pthread_setcanceltype.c b/src/compat/pthread/pthread_setcanceltype.c similarity index 100% rename from src/pthread/pthread_setcanceltype.c rename to src/compat/pthread/pthread_setcanceltype.c diff --git a/src/pthread/pthread_setconcurrency.c b/src/compat/pthread/pthread_setconcurrency.c similarity index 100% rename from src/pthread/pthread_setconcurrency.c rename to src/compat/pthread/pthread_setconcurrency.c diff --git a/src/pthread/pthread_setschedparam.c b/src/compat/pthread/pthread_setschedparam.c similarity index 100% rename from src/pthread/pthread_setschedparam.c rename to src/compat/pthread/pthread_setschedparam.c diff --git a/src/pthread/pthread_setspecific.c b/src/compat/pthread/pthread_setspecific.c similarity index 100% rename from src/pthread/pthread_setspecific.c rename to src/compat/pthread/pthread_setspecific.c diff --git a/src/pthread/pthread_spin_destroy.c b/src/compat/pthread/pthread_spin_destroy.c similarity index 100% rename from src/pthread/pthread_spin_destroy.c rename to src/compat/pthread/pthread_spin_destroy.c diff --git a/src/pthread/pthread_spin_init.c b/src/compat/pthread/pthread_spin_init.c similarity index 100% rename from src/pthread/pthread_spin_init.c rename to src/compat/pthread/pthread_spin_init.c diff --git a/src/pthread/pthread_spin_lock.c b/src/compat/pthread/pthread_spin_lock.c similarity index 100% rename from src/pthread/pthread_spin_lock.c rename to src/compat/pthread/pthread_spin_lock.c diff --git a/src/pthread/pthread_spin_trylock.c b/src/compat/pthread/pthread_spin_trylock.c similarity index 100% rename from src/pthread/pthread_spin_trylock.c rename to src/compat/pthread/pthread_spin_trylock.c diff --git a/src/pthread/pthread_spin_unlock.c b/src/compat/pthread/pthread_spin_unlock.c similarity index 100% rename from src/pthread/pthread_spin_unlock.c rename to src/compat/pthread/pthread_spin_unlock.c diff --git a/src/pthread/pthread_terminate.c b/src/compat/pthread/pthread_terminate.c similarity index 100% rename from src/pthread/pthread_terminate.c rename to src/compat/pthread/pthread_terminate.c diff --git a/src/pthread/pthread_testcancel.c b/src/compat/pthread/pthread_testcancel.c similarity index 100% rename from src/pthread/pthread_testcancel.c rename to src/compat/pthread/pthread_testcancel.c diff --git a/src/pthread/pthread_timechange_handler_np.c b/src/compat/pthread/pthread_timechange_handler_np.c similarity index 100% rename from src/pthread/pthread_timechange_handler_np.c rename to src/compat/pthread/pthread_timechange_handler_np.c diff --git a/src/pthread/sched.h b/src/compat/pthread/sched.h similarity index 100% rename from src/pthread/sched.h rename to src/compat/pthread/sched.h diff --git a/src/pthread/sched_get_priority_max.c b/src/compat/pthread/sched_get_priority_max.c similarity index 100% rename from src/pthread/sched_get_priority_max.c rename to src/compat/pthread/sched_get_priority_max.c diff --git a/src/pthread/sched_get_priority_min.c b/src/compat/pthread/sched_get_priority_min.c similarity index 100% rename from src/pthread/sched_get_priority_min.c rename to src/compat/pthread/sched_get_priority_min.c diff --git a/src/pthread/sched_setscheduler.c b/src/compat/pthread/sched_setscheduler.c similarity index 100% rename from src/pthread/sched_setscheduler.c rename to src/compat/pthread/sched_setscheduler.c diff --git a/src/pthread/sched_yield.c b/src/compat/pthread/sched_yield.c similarity index 100% rename from src/pthread/sched_yield.c rename to src/compat/pthread/sched_yield.c diff --git a/src/pthread/sem_close.c b/src/compat/pthread/sem_close.c similarity index 100% rename from src/pthread/sem_close.c rename to src/compat/pthread/sem_close.c diff --git a/src/pthread/sem_destroy.c b/src/compat/pthread/sem_destroy.c similarity index 100% rename from src/pthread/sem_destroy.c rename to src/compat/pthread/sem_destroy.c diff --git a/src/pthread/sem_getvalue.c b/src/compat/pthread/sem_getvalue.c similarity index 100% rename from src/pthread/sem_getvalue.c rename to src/compat/pthread/sem_getvalue.c diff --git a/src/pthread/sem_init.c b/src/compat/pthread/sem_init.c similarity index 100% rename from src/pthread/sem_init.c rename to src/compat/pthread/sem_init.c diff --git a/src/pthread/sem_open.c b/src/compat/pthread/sem_open.c similarity index 100% rename from src/pthread/sem_open.c rename to src/compat/pthread/sem_open.c diff --git a/src/pthread/sem_post.c b/src/compat/pthread/sem_post.c similarity index 100% rename from src/pthread/sem_post.c rename to src/compat/pthread/sem_post.c diff --git a/src/pthread/sem_post_multiple.c b/src/compat/pthread/sem_post_multiple.c similarity index 100% rename from src/pthread/sem_post_multiple.c rename to src/compat/pthread/sem_post_multiple.c diff --git a/src/pthread/sem_timedwait.c b/src/compat/pthread/sem_timedwait.c similarity index 100% rename from src/pthread/sem_timedwait.c rename to src/compat/pthread/sem_timedwait.c diff --git a/src/pthread/sem_trywait.c b/src/compat/pthread/sem_trywait.c similarity index 100% rename from src/pthread/sem_trywait.c rename to src/compat/pthread/sem_trywait.c diff --git a/src/pthread/sem_unlink.c b/src/compat/pthread/sem_unlink.c similarity index 100% rename from src/pthread/sem_unlink.c rename to src/compat/pthread/sem_unlink.c diff --git a/src/pthread/sem_wait.c b/src/compat/pthread/sem_wait.c similarity index 100% rename from src/pthread/sem_wait.c rename to src/compat/pthread/sem_wait.c diff --git a/src/pthread/semaphore.h b/src/compat/pthread/semaphore.h similarity index 100% rename from src/pthread/semaphore.h rename to src/compat/pthread/semaphore.h diff --git a/src/pthread/tests/ChangeLog b/src/compat/pthread/tests/ChangeLog similarity index 100% rename from src/pthread/tests/ChangeLog rename to src/compat/pthread/tests/ChangeLog diff --git a/src/pthread/tests/barrier1.c b/src/compat/pthread/tests/barrier1.c similarity index 100% rename from src/pthread/tests/barrier1.c rename to src/compat/pthread/tests/barrier1.c diff --git a/src/pthread/tests/barrier2.c b/src/compat/pthread/tests/barrier2.c similarity index 100% rename from src/pthread/tests/barrier2.c rename to src/compat/pthread/tests/barrier2.c diff --git a/src/pthread/tests/barrier3.c b/src/compat/pthread/tests/barrier3.c similarity index 100% rename from src/pthread/tests/barrier3.c rename to src/compat/pthread/tests/barrier3.c diff --git a/src/pthread/tests/barrier4.c b/src/compat/pthread/tests/barrier4.c similarity index 100% rename from src/pthread/tests/barrier4.c rename to src/compat/pthread/tests/barrier4.c diff --git a/src/pthread/tests/barrier5.c b/src/compat/pthread/tests/barrier5.c similarity index 100% rename from src/pthread/tests/barrier5.c rename to src/compat/pthread/tests/barrier5.c diff --git a/src/pthread/tests/benchlib.c b/src/compat/pthread/tests/benchlib.c similarity index 100% rename from src/pthread/tests/benchlib.c rename to src/compat/pthread/tests/benchlib.c diff --git a/src/pthread/tests/benchtest.h b/src/compat/pthread/tests/benchtest.h similarity index 100% rename from src/pthread/tests/benchtest.h rename to src/compat/pthread/tests/benchtest.h diff --git a/src/pthread/tests/benchtest1.c b/src/compat/pthread/tests/benchtest1.c similarity index 100% rename from src/pthread/tests/benchtest1.c rename to src/compat/pthread/tests/benchtest1.c diff --git a/src/pthread/tests/benchtest2.c b/src/compat/pthread/tests/benchtest2.c similarity index 100% rename from src/pthread/tests/benchtest2.c rename to src/compat/pthread/tests/benchtest2.c diff --git a/src/pthread/tests/benchtest3.c b/src/compat/pthread/tests/benchtest3.c similarity index 100% rename from src/pthread/tests/benchtest3.c rename to src/compat/pthread/tests/benchtest3.c diff --git a/src/pthread/tests/benchtest4.c b/src/compat/pthread/tests/benchtest4.c similarity index 100% rename from src/pthread/tests/benchtest4.c rename to src/compat/pthread/tests/benchtest4.c diff --git a/src/pthread/tests/benchtest5.c b/src/compat/pthread/tests/benchtest5.c similarity index 100% rename from src/pthread/tests/benchtest5.c rename to src/compat/pthread/tests/benchtest5.c diff --git a/src/pthread/tests/cancel1.c b/src/compat/pthread/tests/cancel1.c similarity index 100% rename from src/pthread/tests/cancel1.c rename to src/compat/pthread/tests/cancel1.c diff --git a/src/pthread/tests/cancel2.c b/src/compat/pthread/tests/cancel2.c similarity index 100% rename from src/pthread/tests/cancel2.c rename to src/compat/pthread/tests/cancel2.c diff --git a/src/pthread/tests/cancel3.c b/src/compat/pthread/tests/cancel3.c similarity index 100% rename from src/pthread/tests/cancel3.c rename to src/compat/pthread/tests/cancel3.c diff --git a/src/pthread/tests/cancel4.c b/src/compat/pthread/tests/cancel4.c similarity index 100% rename from src/pthread/tests/cancel4.c rename to src/compat/pthread/tests/cancel4.c diff --git a/src/pthread/tests/cancel5.c b/src/compat/pthread/tests/cancel5.c similarity index 100% rename from src/pthread/tests/cancel5.c rename to src/compat/pthread/tests/cancel5.c diff --git a/src/pthread/tests/cancel6a.c b/src/compat/pthread/tests/cancel6a.c similarity index 100% rename from src/pthread/tests/cancel6a.c rename to src/compat/pthread/tests/cancel6a.c diff --git a/src/pthread/tests/cancel6d.c b/src/compat/pthread/tests/cancel6d.c similarity index 100% rename from src/pthread/tests/cancel6d.c rename to src/compat/pthread/tests/cancel6d.c diff --git a/src/pthread/tests/cleanup0.c b/src/compat/pthread/tests/cleanup0.c similarity index 100% rename from src/pthread/tests/cleanup0.c rename to src/compat/pthread/tests/cleanup0.c diff --git a/src/pthread/tests/cleanup1.c b/src/compat/pthread/tests/cleanup1.c similarity index 100% rename from src/pthread/tests/cleanup1.c rename to src/compat/pthread/tests/cleanup1.c diff --git a/src/pthread/tests/cleanup2.c b/src/compat/pthread/tests/cleanup2.c similarity index 100% rename from src/pthread/tests/cleanup2.c rename to src/compat/pthread/tests/cleanup2.c diff --git a/src/pthread/tests/cleanup3.c b/src/compat/pthread/tests/cleanup3.c similarity index 100% rename from src/pthread/tests/cleanup3.c rename to src/compat/pthread/tests/cleanup3.c diff --git a/src/pthread/tests/condvar1.c b/src/compat/pthread/tests/condvar1.c similarity index 100% rename from src/pthread/tests/condvar1.c rename to src/compat/pthread/tests/condvar1.c diff --git a/src/pthread/tests/condvar1_1.c b/src/compat/pthread/tests/condvar1_1.c similarity index 100% rename from src/pthread/tests/condvar1_1.c rename to src/compat/pthread/tests/condvar1_1.c diff --git a/src/pthread/tests/condvar1_2.c b/src/compat/pthread/tests/condvar1_2.c similarity index 100% rename from src/pthread/tests/condvar1_2.c rename to src/compat/pthread/tests/condvar1_2.c diff --git a/src/pthread/tests/condvar2.c b/src/compat/pthread/tests/condvar2.c similarity index 100% rename from src/pthread/tests/condvar2.c rename to src/compat/pthread/tests/condvar2.c diff --git a/src/pthread/tests/condvar2_1.c b/src/compat/pthread/tests/condvar2_1.c similarity index 100% rename from src/pthread/tests/condvar2_1.c rename to src/compat/pthread/tests/condvar2_1.c diff --git a/src/pthread/tests/condvar3.c b/src/compat/pthread/tests/condvar3.c similarity index 100% rename from src/pthread/tests/condvar3.c rename to src/compat/pthread/tests/condvar3.c diff --git a/src/pthread/tests/condvar3_1.c b/src/compat/pthread/tests/condvar3_1.c similarity index 100% rename from src/pthread/tests/condvar3_1.c rename to src/compat/pthread/tests/condvar3_1.c diff --git a/src/pthread/tests/condvar3_2.c b/src/compat/pthread/tests/condvar3_2.c similarity index 100% rename from src/pthread/tests/condvar3_2.c rename to src/compat/pthread/tests/condvar3_2.c diff --git a/src/pthread/tests/condvar3_3.c b/src/compat/pthread/tests/condvar3_3.c similarity index 100% rename from src/pthread/tests/condvar3_3.c rename to src/compat/pthread/tests/condvar3_3.c diff --git a/src/pthread/tests/condvar4.c b/src/compat/pthread/tests/condvar4.c similarity index 100% rename from src/pthread/tests/condvar4.c rename to src/compat/pthread/tests/condvar4.c diff --git a/src/pthread/tests/condvar5.c b/src/compat/pthread/tests/condvar5.c similarity index 100% rename from src/pthread/tests/condvar5.c rename to src/compat/pthread/tests/condvar5.c diff --git a/src/pthread/tests/condvar6.c b/src/compat/pthread/tests/condvar6.c similarity index 100% rename from src/pthread/tests/condvar6.c rename to src/compat/pthread/tests/condvar6.c diff --git a/src/pthread/tests/condvar7.c b/src/compat/pthread/tests/condvar7.c similarity index 100% rename from src/pthread/tests/condvar7.c rename to src/compat/pthread/tests/condvar7.c diff --git a/src/pthread/tests/condvar8.c b/src/compat/pthread/tests/condvar8.c similarity index 100% rename from src/pthread/tests/condvar8.c rename to src/compat/pthread/tests/condvar8.c diff --git a/src/pthread/tests/condvar9.c b/src/compat/pthread/tests/condvar9.c similarity index 100% rename from src/pthread/tests/condvar9.c rename to src/compat/pthread/tests/condvar9.c diff --git a/src/pthread/tests/count1.c b/src/compat/pthread/tests/count1.c similarity index 100% rename from src/pthread/tests/count1.c rename to src/compat/pthread/tests/count1.c diff --git a/src/pthread/tests/create1.c b/src/compat/pthread/tests/create1.c similarity index 100% rename from src/pthread/tests/create1.c rename to src/compat/pthread/tests/create1.c diff --git a/src/pthread/tests/create2.c b/src/compat/pthread/tests/create2.c similarity index 100% rename from src/pthread/tests/create2.c rename to src/compat/pthread/tests/create2.c diff --git a/src/pthread/tests/create3.c b/src/compat/pthread/tests/create3.c similarity index 100% rename from src/pthread/tests/create3.c rename to src/compat/pthread/tests/create3.c diff --git a/src/pthread/tests/delay1.c b/src/compat/pthread/tests/delay1.c similarity index 100% rename from src/pthread/tests/delay1.c rename to src/compat/pthread/tests/delay1.c diff --git a/src/pthread/tests/delay2.c b/src/compat/pthread/tests/delay2.c similarity index 100% rename from src/pthread/tests/delay2.c rename to src/compat/pthread/tests/delay2.c diff --git a/src/pthread/tests/detach1.c b/src/compat/pthread/tests/detach1.c similarity index 100% rename from src/pthread/tests/detach1.c rename to src/compat/pthread/tests/detach1.c diff --git a/src/pthread/tests/equal1.c b/src/compat/pthread/tests/equal1.c similarity index 100% rename from src/pthread/tests/equal1.c rename to src/compat/pthread/tests/equal1.c diff --git a/src/pthread/tests/errno1.c b/src/compat/pthread/tests/errno1.c similarity index 100% rename from src/pthread/tests/errno1.c rename to src/compat/pthread/tests/errno1.c diff --git a/src/pthread/tests/exception1.c b/src/compat/pthread/tests/exception1.c similarity index 100% rename from src/pthread/tests/exception1.c rename to src/compat/pthread/tests/exception1.c diff --git a/src/pthread/tests/exception2.c b/src/compat/pthread/tests/exception2.c similarity index 100% rename from src/pthread/tests/exception2.c rename to src/compat/pthread/tests/exception2.c diff --git a/src/pthread/tests/exception3.c b/src/compat/pthread/tests/exception3.c similarity index 100% rename from src/pthread/tests/exception3.c rename to src/compat/pthread/tests/exception3.c diff --git a/src/pthread/tests/exit1.c b/src/compat/pthread/tests/exit1.c similarity index 100% rename from src/pthread/tests/exit1.c rename to src/compat/pthread/tests/exit1.c diff --git a/src/pthread/tests/exit2.c b/src/compat/pthread/tests/exit2.c similarity index 100% rename from src/pthread/tests/exit2.c rename to src/compat/pthread/tests/exit2.c diff --git a/src/pthread/tests/exit3.c b/src/compat/pthread/tests/exit3.c similarity index 100% rename from src/pthread/tests/exit3.c rename to src/compat/pthread/tests/exit3.c diff --git a/src/pthread/tests/exit4.c b/src/compat/pthread/tests/exit4.c similarity index 100% rename from src/pthread/tests/exit4.c rename to src/compat/pthread/tests/exit4.c diff --git a/src/pthread/tests/exit5.c b/src/compat/pthread/tests/exit5.c similarity index 100% rename from src/pthread/tests/exit5.c rename to src/compat/pthread/tests/exit5.c diff --git a/src/pthread/tests/inherit1.c b/src/compat/pthread/tests/inherit1.c similarity index 100% rename from src/pthread/tests/inherit1.c rename to src/compat/pthread/tests/inherit1.c diff --git a/src/pthread/tests/join0.c b/src/compat/pthread/tests/join0.c similarity index 100% rename from src/pthread/tests/join0.c rename to src/compat/pthread/tests/join0.c diff --git a/src/pthread/tests/join1.c b/src/compat/pthread/tests/join1.c similarity index 100% rename from src/pthread/tests/join1.c rename to src/compat/pthread/tests/join1.c diff --git a/src/pthread/tests/join2.c b/src/compat/pthread/tests/join2.c similarity index 100% rename from src/pthread/tests/join2.c rename to src/compat/pthread/tests/join2.c diff --git a/src/pthread/tests/join3.c b/src/compat/pthread/tests/join3.c similarity index 100% rename from src/pthread/tests/join3.c rename to src/compat/pthread/tests/join3.c diff --git a/src/pthread/tests/join4.c b/src/compat/pthread/tests/join4.c similarity index 100% rename from src/pthread/tests/join4.c rename to src/compat/pthread/tests/join4.c diff --git a/src/pthread/tests/kill1.c b/src/compat/pthread/tests/kill1.c similarity index 100% rename from src/pthread/tests/kill1.c rename to src/compat/pthread/tests/kill1.c diff --git a/src/pthread/tests/mutex1.c b/src/compat/pthread/tests/mutex1.c similarity index 100% rename from src/pthread/tests/mutex1.c rename to src/compat/pthread/tests/mutex1.c diff --git a/src/pthread/tests/mutex1e.c b/src/compat/pthread/tests/mutex1e.c similarity index 100% rename from src/pthread/tests/mutex1e.c rename to src/compat/pthread/tests/mutex1e.c diff --git a/src/pthread/tests/mutex1n.c b/src/compat/pthread/tests/mutex1n.c similarity index 100% rename from src/pthread/tests/mutex1n.c rename to src/compat/pthread/tests/mutex1n.c diff --git a/src/pthread/tests/mutex1r.c b/src/compat/pthread/tests/mutex1r.c similarity index 100% rename from src/pthread/tests/mutex1r.c rename to src/compat/pthread/tests/mutex1r.c diff --git a/src/pthread/tests/mutex2.c b/src/compat/pthread/tests/mutex2.c similarity index 100% rename from src/pthread/tests/mutex2.c rename to src/compat/pthread/tests/mutex2.c diff --git a/src/pthread/tests/mutex2e.c b/src/compat/pthread/tests/mutex2e.c similarity index 100% rename from src/pthread/tests/mutex2e.c rename to src/compat/pthread/tests/mutex2e.c diff --git a/src/pthread/tests/mutex2r.c b/src/compat/pthread/tests/mutex2r.c similarity index 100% rename from src/pthread/tests/mutex2r.c rename to src/compat/pthread/tests/mutex2r.c diff --git a/src/pthread/tests/mutex3.c b/src/compat/pthread/tests/mutex3.c similarity index 100% rename from src/pthread/tests/mutex3.c rename to src/compat/pthread/tests/mutex3.c diff --git a/src/pthread/tests/mutex3e.c b/src/compat/pthread/tests/mutex3e.c similarity index 100% rename from src/pthread/tests/mutex3e.c rename to src/compat/pthread/tests/mutex3e.c diff --git a/src/pthread/tests/mutex3r.c b/src/compat/pthread/tests/mutex3r.c similarity index 100% rename from src/pthread/tests/mutex3r.c rename to src/compat/pthread/tests/mutex3r.c diff --git a/src/pthread/tests/mutex4.c b/src/compat/pthread/tests/mutex4.c similarity index 100% rename from src/pthread/tests/mutex4.c rename to src/compat/pthread/tests/mutex4.c diff --git a/src/pthread/tests/mutex5.c b/src/compat/pthread/tests/mutex5.c similarity index 100% rename from src/pthread/tests/mutex5.c rename to src/compat/pthread/tests/mutex5.c diff --git a/src/pthread/tests/mutex6.c b/src/compat/pthread/tests/mutex6.c similarity index 100% rename from src/pthread/tests/mutex6.c rename to src/compat/pthread/tests/mutex6.c diff --git a/src/pthread/tests/mutex6e.c b/src/compat/pthread/tests/mutex6e.c similarity index 100% rename from src/pthread/tests/mutex6e.c rename to src/compat/pthread/tests/mutex6e.c diff --git a/src/pthread/tests/mutex6es.c b/src/compat/pthread/tests/mutex6es.c similarity index 100% rename from src/pthread/tests/mutex6es.c rename to src/compat/pthread/tests/mutex6es.c diff --git a/src/pthread/tests/mutex6n.c b/src/compat/pthread/tests/mutex6n.c similarity index 100% rename from src/pthread/tests/mutex6n.c rename to src/compat/pthread/tests/mutex6n.c diff --git a/src/pthread/tests/mutex6r.c b/src/compat/pthread/tests/mutex6r.c similarity index 100% rename from src/pthread/tests/mutex6r.c rename to src/compat/pthread/tests/mutex6r.c diff --git a/src/pthread/tests/mutex6rs.c b/src/compat/pthread/tests/mutex6rs.c similarity index 100% rename from src/pthread/tests/mutex6rs.c rename to src/compat/pthread/tests/mutex6rs.c diff --git a/src/pthread/tests/mutex6s.c b/src/compat/pthread/tests/mutex6s.c similarity index 100% rename from src/pthread/tests/mutex6s.c rename to src/compat/pthread/tests/mutex6s.c diff --git a/src/pthread/tests/mutex7.c b/src/compat/pthread/tests/mutex7.c similarity index 100% rename from src/pthread/tests/mutex7.c rename to src/compat/pthread/tests/mutex7.c diff --git a/src/pthread/tests/mutex7e.c b/src/compat/pthread/tests/mutex7e.c similarity index 100% rename from src/pthread/tests/mutex7e.c rename to src/compat/pthread/tests/mutex7e.c diff --git a/src/pthread/tests/mutex7n.c b/src/compat/pthread/tests/mutex7n.c similarity index 100% rename from src/pthread/tests/mutex7n.c rename to src/compat/pthread/tests/mutex7n.c diff --git a/src/pthread/tests/mutex7r.c b/src/compat/pthread/tests/mutex7r.c similarity index 100% rename from src/pthread/tests/mutex7r.c rename to src/compat/pthread/tests/mutex7r.c diff --git a/src/pthread/tests/mutex8.c b/src/compat/pthread/tests/mutex8.c similarity index 100% rename from src/pthread/tests/mutex8.c rename to src/compat/pthread/tests/mutex8.c diff --git a/src/pthread/tests/mutex8e.c b/src/compat/pthread/tests/mutex8e.c similarity index 100% rename from src/pthread/tests/mutex8e.c rename to src/compat/pthread/tests/mutex8e.c diff --git a/src/pthread/tests/mutex8n.c b/src/compat/pthread/tests/mutex8n.c similarity index 100% rename from src/pthread/tests/mutex8n.c rename to src/compat/pthread/tests/mutex8n.c diff --git a/src/pthread/tests/mutex8r.c b/src/compat/pthread/tests/mutex8r.c similarity index 100% rename from src/pthread/tests/mutex8r.c rename to src/compat/pthread/tests/mutex8r.c diff --git a/src/pthread/tests/once1.c b/src/compat/pthread/tests/once1.c similarity index 100% rename from src/pthread/tests/once1.c rename to src/compat/pthread/tests/once1.c diff --git a/src/pthread/tests/once2.c b/src/compat/pthread/tests/once2.c similarity index 100% rename from src/pthread/tests/once2.c rename to src/compat/pthread/tests/once2.c diff --git a/src/pthread/tests/once3.c b/src/compat/pthread/tests/once3.c similarity index 100% rename from src/pthread/tests/once3.c rename to src/compat/pthread/tests/once3.c diff --git a/src/pthread/tests/once4.c b/src/compat/pthread/tests/once4.c similarity index 100% rename from src/pthread/tests/once4.c rename to src/compat/pthread/tests/once4.c diff --git a/src/pthread/tests/priority1.c b/src/compat/pthread/tests/priority1.c similarity index 100% rename from src/pthread/tests/priority1.c rename to src/compat/pthread/tests/priority1.c diff --git a/src/pthread/tests/priority2.c b/src/compat/pthread/tests/priority2.c similarity index 100% rename from src/pthread/tests/priority2.c rename to src/compat/pthread/tests/priority2.c diff --git a/src/pthread/tests/reuse1.c b/src/compat/pthread/tests/reuse1.c similarity index 100% rename from src/pthread/tests/reuse1.c rename to src/compat/pthread/tests/reuse1.c diff --git a/src/pthread/tests/reuse2.c b/src/compat/pthread/tests/reuse2.c similarity index 100% rename from src/pthread/tests/reuse2.c rename to src/compat/pthread/tests/reuse2.c diff --git a/src/pthread/tests/rwlock1.c b/src/compat/pthread/tests/rwlock1.c similarity index 100% rename from src/pthread/tests/rwlock1.c rename to src/compat/pthread/tests/rwlock1.c diff --git a/src/pthread/tests/rwlock2.c b/src/compat/pthread/tests/rwlock2.c similarity index 100% rename from src/pthread/tests/rwlock2.c rename to src/compat/pthread/tests/rwlock2.c diff --git a/src/pthread/tests/rwlock2_t.c b/src/compat/pthread/tests/rwlock2_t.c similarity index 100% rename from src/pthread/tests/rwlock2_t.c rename to src/compat/pthread/tests/rwlock2_t.c diff --git a/src/pthread/tests/rwlock3.c b/src/compat/pthread/tests/rwlock3.c similarity index 100% rename from src/pthread/tests/rwlock3.c rename to src/compat/pthread/tests/rwlock3.c diff --git a/src/pthread/tests/rwlock3_t.c b/src/compat/pthread/tests/rwlock3_t.c similarity index 100% rename from src/pthread/tests/rwlock3_t.c rename to src/compat/pthread/tests/rwlock3_t.c diff --git a/src/pthread/tests/rwlock4.c b/src/compat/pthread/tests/rwlock4.c similarity index 100% rename from src/pthread/tests/rwlock4.c rename to src/compat/pthread/tests/rwlock4.c diff --git a/src/pthread/tests/rwlock4_t.c b/src/compat/pthread/tests/rwlock4_t.c similarity index 100% rename from src/pthread/tests/rwlock4_t.c rename to src/compat/pthread/tests/rwlock4_t.c diff --git a/src/pthread/tests/rwlock5.c b/src/compat/pthread/tests/rwlock5.c similarity index 100% rename from src/pthread/tests/rwlock5.c rename to src/compat/pthread/tests/rwlock5.c diff --git a/src/pthread/tests/rwlock5_t.c b/src/compat/pthread/tests/rwlock5_t.c similarity index 100% rename from src/pthread/tests/rwlock5_t.c rename to src/compat/pthread/tests/rwlock5_t.c diff --git a/src/pthread/tests/rwlock6.c b/src/compat/pthread/tests/rwlock6.c similarity index 100% rename from src/pthread/tests/rwlock6.c rename to src/compat/pthread/tests/rwlock6.c diff --git a/src/pthread/tests/rwlock6_t.c b/src/compat/pthread/tests/rwlock6_t.c similarity index 100% rename from src/pthread/tests/rwlock6_t.c rename to src/compat/pthread/tests/rwlock6_t.c diff --git a/src/pthread/tests/rwlock6_t2.c b/src/compat/pthread/tests/rwlock6_t2.c similarity index 100% rename from src/pthread/tests/rwlock6_t2.c rename to src/compat/pthread/tests/rwlock6_t2.c diff --git a/src/pthread/tests/rwlock7.c b/src/compat/pthread/tests/rwlock7.c similarity index 100% rename from src/pthread/tests/rwlock7.c rename to src/compat/pthread/tests/rwlock7.c diff --git a/src/pthread/tests/rwlock8.c b/src/compat/pthread/tests/rwlock8.c similarity index 100% rename from src/pthread/tests/rwlock8.c rename to src/compat/pthread/tests/rwlock8.c diff --git a/src/pthread/tests/self1.c b/src/compat/pthread/tests/self1.c similarity index 100% rename from src/pthread/tests/self1.c rename to src/compat/pthread/tests/self1.c diff --git a/src/pthread/tests/self2.c b/src/compat/pthread/tests/self2.c similarity index 100% rename from src/pthread/tests/self2.c rename to src/compat/pthread/tests/self2.c diff --git a/src/pthread/tests/semaphore1.c b/src/compat/pthread/tests/semaphore1.c similarity index 100% rename from src/pthread/tests/semaphore1.c rename to src/compat/pthread/tests/semaphore1.c diff --git a/src/pthread/tests/semaphore2.c b/src/compat/pthread/tests/semaphore2.c similarity index 100% rename from src/pthread/tests/semaphore2.c rename to src/compat/pthread/tests/semaphore2.c diff --git a/src/pthread/tests/semaphore3.c b/src/compat/pthread/tests/semaphore3.c similarity index 100% rename from src/pthread/tests/semaphore3.c rename to src/compat/pthread/tests/semaphore3.c diff --git a/src/pthread/tests/semaphore4.c b/src/compat/pthread/tests/semaphore4.c similarity index 100% rename from src/pthread/tests/semaphore4.c rename to src/compat/pthread/tests/semaphore4.c diff --git a/src/pthread/tests/semaphore4t.c b/src/compat/pthread/tests/semaphore4t.c similarity index 100% rename from src/pthread/tests/semaphore4t.c rename to src/compat/pthread/tests/semaphore4t.c diff --git a/src/pthread/tests/semaphore5.c b/src/compat/pthread/tests/semaphore5.c similarity index 100% rename from src/pthread/tests/semaphore5.c rename to src/compat/pthread/tests/semaphore5.c diff --git a/src/pthread/tests/semaphore6.c b/src/compat/pthread/tests/semaphore6.c similarity index 100% rename from src/pthread/tests/semaphore6.c rename to src/compat/pthread/tests/semaphore6.c diff --git a/src/pthread/tests/spin1.c b/src/compat/pthread/tests/spin1.c similarity index 100% rename from src/pthread/tests/spin1.c rename to src/compat/pthread/tests/spin1.c diff --git a/src/pthread/tests/spin2.c b/src/compat/pthread/tests/spin2.c similarity index 100% rename from src/pthread/tests/spin2.c rename to src/compat/pthread/tests/spin2.c diff --git a/src/pthread/tests/spin3.c b/src/compat/pthread/tests/spin3.c similarity index 100% rename from src/pthread/tests/spin3.c rename to src/compat/pthread/tests/spin3.c diff --git a/src/pthread/tests/spin4.c b/src/compat/pthread/tests/spin4.c similarity index 100% rename from src/pthread/tests/spin4.c rename to src/compat/pthread/tests/spin4.c diff --git a/src/pthread/tests/stress1.c b/src/compat/pthread/tests/stress1.c similarity index 100% rename from src/pthread/tests/stress1.c rename to src/compat/pthread/tests/stress1.c diff --git a/src/pthread/tests/test.h b/src/compat/pthread/tests/test.h similarity index 100% rename from src/pthread/tests/test.h rename to src/compat/pthread/tests/test.h diff --git a/src/pthread/tests/test_main.c b/src/compat/pthread/tests/test_main.c similarity index 100% rename from src/pthread/tests/test_main.c rename to src/compat/pthread/tests/test_main.c diff --git a/src/pthread/tests/tsd1.c b/src/compat/pthread/tests/tsd1.c similarity index 100% rename from src/pthread/tests/tsd1.c rename to src/compat/pthread/tests/tsd1.c diff --git a/src/pthread/tests/tsd2.c b/src/compat/pthread/tests/tsd2.c similarity index 100% rename from src/pthread/tests/tsd2.c rename to src/compat/pthread/tests/tsd2.c diff --git a/src/pthread/tests/valid1.c b/src/compat/pthread/tests/valid1.c similarity index 100% rename from src/pthread/tests/valid1.c rename to src/compat/pthread/tests/valid1.c diff --git a/src/pthread/tests/valid2.c b/src/compat/pthread/tests/valid2.c similarity index 100% rename from src/pthread/tests/valid2.c rename to src/compat/pthread/tests/valid2.c diff --git a/src/pthread/tls-helper.c b/src/compat/pthread/tls-helper.c similarity index 100% rename from src/pthread/tls-helper.c rename to src/compat/pthread/tls-helper.c diff --git a/src/pthread/tls-helper.h b/src/compat/pthread/tls-helper.h similarity index 100% rename from src/pthread/tls-helper.h rename to src/compat/pthread/tls-helper.h diff --git a/src/pthread/platform/nautilus/Makefile~ b/src/pthread/platform/nautilus/Makefile~ deleted file mode 100644 index f9491e1f6..000000000 --- a/src/pthread/platform/nautilus/Makefile~ +++ /dev/null @@ -1,194 +0,0 @@ - -CLEANUP_TYPE=C -#CLEANUP_TYPE=CPP - -VPATH = ../..:../helper - -TARGET_LIB = libpthread-psp.a - - -MUTEX_OBJS = \ - pthread_mutex_unlock.o \ - pthread_mutex_init.o \ - pthread_mutex_destroy.o \ - pthread_mutex_lock.o \ - pthread_mutex_timedlock.o \ - pthread_mutex_trylock.o - -MUTEXATTR_OBJS = \ - pthread_mutexattr_destroy.o \ - pthread_mutexattr_getkind_np.o \ - pthread_mutexattr_getpshared.o \ - pthread_mutexattr_gettype.o \ - pthread_mutexattr_init.o \ - pthread_mutexattr_setkind_np.o \ - pthread_mutexattr_setpshared.o \ - pthread_mutexattr_settype.o - -SUPPORT_OBJS = \ - pte_relmillisecs.o \ - pte_mutex_check_need_init.o \ - pte_threadDestroy.o \ - pte_new.o \ - pte_threadStart.o \ - global.o \ - pte_reuse.o \ - pthread_init.o \ - pthread_terminate.o - -THREAD_OBJS = \ - create.o \ - pthread_self.o \ - pthread_equal.o \ - pthread_join.o \ - pthread_detach.o \ - pte_detach.o \ - pte_callUserDestroyRoutines.o \ - pte_tkAssocDestroy.o \ - pthread_kill.o \ - pthread_attr_destroy.o \ - pthread_attr_getdetachstate.o \ - pthread_attr_getinheritsched.o \ - pthread_attr_getschedparam.o \ - pthread_attr_getschedpolicy.o \ - pthread_attr_getscope.o \ - pthread_attr_getstackaddr.o \ - pthread_attr_getstacksize.o \ - pthread_attr_init.o \ - pthread_attr_setdetachstate.o \ - pthread_attr_setinheritsched.o \ - pthread_attr_setschedparam.o \ - pthread_attr_setschedpolicy.o \ - pthread_attr_setscope.o \ - pthread_attr_setstackaddr.o \ - pthread_attr_setstacksize.o \ - pte_is_attr.o \ - pthread_exit.o \ - pthread_getschedparam.o \ - pthread_setschedparam.o \ - sched_get_priority_max.o \ - sched_get_priority_min.o - - -TLS_OBJS = \ - pthread_key_create.o \ - pthread_key_delete.o \ - pthread_getspecific.o \ - pthread_setspecific.o \ - pte_tkAssocCreate.o - -MISC_OBJS = \ - sched_yield.o \ - pthread_delay_np.o \ - pthread_testcancel.o \ - pte_throw.o \ - cleanup.o \ - pthread_once.o \ - pthread_num_processors_np.o \ - pte_getprocessors.o \ - pte_spinlock_check_need_init.o \ - global.o \ - pthread_timechange_handler_np.o \ - pte_cond_check_need_init.o \ - pthread_getconcurrency.o \ - pthread_setconcurrency.o \ - pte_cancellable_wait.o - -SEM_OBJS = \ - sem_close.o \ - sem_destroy.o \ - sem_getvalue.o \ - sem_init.o \ - sem_open.o \ - sem_post.o \ - sem_post_multiple.o \ - sem_timedwait.o \ - sem_trywait.o \ - sem_unlink.o \ - sem_wait.o - -BARRIER_OBJS = \ - pthread_barrier_init.o \ - pthread_barrier_destroy.o \ - pthread_barrier_wait.o \ - pthread_barrierattr_init.o \ - pthread_barrierattr_destroy.o \ - pthread_barrierattr_getpshared.o \ - pthread_barrierattr_setpshared.o \ - -SPIN_OBJS = \ - pthread_spin_destroy.o \ - pthread_spin_init.o \ - pthread_spin_lock.o \ - pthread_spin_trylock.o \ - pthread_spin_unlock.o - -CONDVAR_OBJS = \ - pthread_cond_destroy.o \ - pthread_cond_init.o \ - pthread_cond_signal.o \ - pthread_cond_wait.o \ - pthread_condattr_destroy.o \ - pthread_condattr_getpshared.o \ - pthread_condattr_init.o \ - pthread_condattr_setpshared.o - -RWLOCK_OBJS = \ - pthread_rwlock_init.o \ - pthread_rwlock_destroy.o \ - pthread_rwlock_rdlock.o \ - pthread_rwlock_timedrdlock.o \ - pthread_rwlock_timedwrlock.o \ - pthread_rwlock_tryrdlock.o \ - pthread_rwlock_trywrlock.o \ - pthread_rwlock_unlock.o \ - pthread_rwlock_wrlock.o \ - pthread_rwlockattr_init.o \ - pthread_rwlockattr_destroy.o \ - pthread_rwlockattr_getpshared.o \ - pthread_rwlockattr_setpshared.o \ - pte_rwlock_check_need_init.o \ - pte_rwlock_cancelwrwait.o - -CANCEL_OBJS = \ - pthread_cancel.o \ - pthread_setcanceltype.o \ - pthread_setcancelstate.o - -OS_OBJS = \ - psp_osal.o \ - tls-helper.o - -OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) - -INCDIR = -CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper -CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX -ASFLAGS = $(CFLAGS) - -LDFLAGS = -LIBS = - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - - -ifeq ($(CLEANUP_TYPE),CPPXX) - -CC=psp-g++ - -pte_throw.o: pte_throw.c - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c ../../pte_throw.c -o pte_throw.o - -pte_threadStart.o: pte_threadStart.c - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c ../../pte_threadStart.c -o pte_threadStart.o - -endif - -install: $(TARGET_LIB) - @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib - @cp -v *.h `psp-config --psp-prefix`/include - @echo "Done." - From 6a15fe42490e63bd84a602b809f860f968260e08 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sun, 19 Jul 2020 15:07:00 -0500 Subject: [PATCH 17/36] Restructure compatability code - Create new compatability subtree and move libccompat into it - Add some functionality to libccompat - Add kconfig support for enabling/disabling different compat features --- .config | 198 ------------------ Kconfig | 24 +++ src/Makefile | 3 +- src/compat/Makefile | 6 + src/compat/libccompat/Makefile | 1 + .../libccompat}/libccompat.c | 1 - .../libccompat}/libccompat_nomacro.c | 0 src/compat/libccompat/qsort.c | 196 +++++++++++++++++ src/nautilus/Makefile | 2 - 9 files changed, 229 insertions(+), 202 deletions(-) delete mode 100644 .config create mode 100644 src/compat/Makefile create mode 100644 src/compat/libccompat/Makefile rename src/{nautilus => compat/libccompat}/libccompat.c (99%) rename src/{nautilus => compat/libccompat}/libccompat_nomacro.c (100%) create mode 100644 src/compat/libccompat/qsort.c diff --git a/.config b/.config deleted file mode 100644 index d5666712d..000000000 --- a/.config +++ /dev/null @@ -1,198 +0,0 @@ -# -# Automatically generated make config: don't edit -#Nautilus: -# Sat May 9 12:03:33 2020 -# - -# -# Platform -# -NAUT_CONFIG_X86_64_HOST=y -# NAUT_CONFIG_XEON_PHI is not set -# NAUT_CONFIG_HVM_HRT is not set -# NAUT_CONFIG_GEM5 is not set -NAUT_CONFIG_MAX_CPUS=256 -NAUT_CONFIG_MAX_IOAPICS=16 -# NAUT_CONFIG_PALACIOS is not set - -# -# Build -# -NAUT_CONFIG_USE_NAUT_BUILTINS=y -NAUT_CONFIG_CXX_SUPPORT=y -# NAUT_CONFIG_RUST_SUPPORT is not set -# NAUT_CONFIG_USE_GCC is not set -NAUT_CONFIG_USE_CLANG=y -# NAUT_CONFIG_USE_WLLVM is not set -NAUT_CONFIG_COMPILER_PREFIX="" -NAUT_CONFIG_COMPILER_SUFFIX="" -NAUT_CONFIG_TOOLCHAIN_ROOT="" - -# -# Configuration -# -NAUT_CONFIG_MAX_THREADS=1024 -# NAUT_CONFIG_RUN_TESTS_AT_BOOT is not set -NAUT_CONFIG_THREAD_EXIT_KEYCODE=196 -# NAUT_CONFIG_USE_TICKETLOCKS is not set -# NAUT_CONFIG_PARTITION_SUPPORT is not set -NAUT_CONFIG_VIRTUAL_CONSOLE_DISPLAY_NAME=y -# NAUT_CONFIG_VIRTUAL_CONSOLE_CHARDEV_CONSOLE is not set -NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR=y -NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR_ALL=y - -# -# Scheduler Options -# -NAUT_CONFIG_UTILIZATION_LIMIT=99 -NAUT_CONFIG_SPORADIC_RESERVATION=10 -NAUT_CONFIG_APERIODIC_RESERVATION=10 -NAUT_CONFIG_HZ=10 -NAUT_CONFIG_INTERRUPT_REINJECTION_DELAY_NS=10000 -# NAUT_CONFIG_AUTO_REAP is not set -# NAUT_CONFIG_WORK_STEALING is not set -# NAUT_CONFIG_TASK_IN_SCHED is not set -# NAUT_CONFIG_TASK_THREAD is not set -# NAUT_CONFIG_TASK_IN_IDLE is not set -# NAUT_CONFIG_INTERRUPT_THREAD is not set -# NAUT_CONFIG_APERIODIC_DYNAMIC_QUANTUM is not set -# NAUT_CONFIG_APERIODIC_DYNAMIC_LIFETIME is not set -# NAUT_CONFIG_APERIODIC_LOTTERY is not set -NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y - -# -# Fiber Options -# -# NAUT_CONFIG_FIBER_ENABLE is not set -# NAUT_CONFIG_REAL_MODE_INTERFACE is not set - -# -# Watchdog Options -# -NAUT_CONFIG_WATCHDOG=y -NAUT_CONFIG_WATCHDOG_DEFAULT_TIME_MS=1000 -# NAUT_CONFIG_DEBUG_WATCHDOG is not set -# NAUT_CONFIG_ISOCORE is not set -# NAUT_CONFIG_CACHEPART is not set - -# -# Garbage Collection Options -# -# NAUT_CONFIG_GARBAGE_COLLECTION is not set - -# -# FPU Options -# -# NAUT_CONFIG_XSAVE_SUPPORT is not set - -# -# Optimizations -# -NAUT_CONFIG_FPU_SAVE=y -NAUT_CONFIG_KICK_SCHEDULE=y -NAUT_CONFIG_HALT_WHILE_IDLE=y -# NAUT_CONFIG_THREAD_OPTIMIZE is not set - -# -# Debugging -# -NAUT_CONFIG_DEBUG_INFO=y -NAUT_CONFIG_DEBUG_PRINTS=y -NAUT_CONFIG_ENABLE_ASSERTS=y -# NAUT_CONFIG_PROFILE is not set -# NAUT_CONFIG_SILENCE_UNDEF_ERR is not set -# NAUT_CONFIG_ENABLE_STACK_CHECK is not set -# NAUT_CONFIG_ENABLE_REMOTE_DEBUGGING is not set -NAUT_CONFIG_ENABLE_MONITOR=y -# NAUT_CONFIG_DEBUG_PAGING is not set -# NAUT_CONFIG_DEBUG_BOOTMEM is not set -# NAUT_CONFIG_DEBUG_CMDLINE is not set -# NAUT_CONFIG_DEBUG_TESTS is not set -# NAUT_CONFIG_DEBUG_BUDDY is not set -# NAUT_CONFIG_DEBUG_KMEM is not set -# NAUT_CONFIG_DEBUG_FPU is not set -# NAUT_CONFIG_DEBUG_SMP is not set -# NAUT_CONFIG_DEBUG_SHELL is not set -# NAUT_CONFIG_DEBUG_SFI is not set -# NAUT_CONFIG_DEBUG_CXX is not set -# NAUT_CONFIG_DEBUG_THREADS is not set -# NAUT_CONFIG_DEBUG_TASKS is not set -# NAUT_CONFIG_DEBUG_WAITQUEUES is not set -# NAUT_CONFIG_DEBUG_FUTURES is not set -# NAUT_CONFIG_DEBUG_GROUP is not set -# NAUT_CONFIG_DEBUG_SCHED is not set -# NAUT_CONFIG_DEBUG_GROUP_SCHED is not set -# NAUT_CONFIG_DEBUG_TIMERS is not set -# NAUT_CONFIG_DEBUG_SEMAPHORES is not set -# NAUT_CONFIG_DEBUG_MSG_QUEUES is not set -# NAUT_CONFIG_DEBUG_SYNCH is not set -# NAUT_CONFIG_DEBUG_BARRIER is not set -# NAUT_CONFIG_DEBUG_NUMA is not set -# NAUT_CONFIG_DEBUG_VIRTUAL_CONSOLE is not set -# NAUT_CONFIG_DEBUG_DEV is not set -# NAUT_CONFIG_DEBUG_FILESYSTEM is not set -# NAUT_CONFIG_DEBUG_LOADER is not set -# NAUT_CONFIG_DEBUG_LINKER is not set -# NAUT_CONFIG_DEBUG_PMC is not set - -# -# Address Spaces -# -# NAUT_CONFIG_ASPACES is not set - -# -# Runtimes -# -# NAUT_CONFIG_LEGION_RT is not set -# NAUT_CONFIG_NDPC_RT is not set -# NAUT_CONFIG_NESL_RT is not set -NAUT_CONFIG_OPENMP_RT=y -NAUT_CONFIG_OPENMP_RT_OMP=y -NAUT_CONFIG_OPENMP_RT_INSTALL_DIR="/home/pdinda/class/ompnk" -# NAUT_CONFIG_OPENMP_RT_GOMP is not set -NAUT_CONFIG_OPENMP_RT_DEBUG=y -NAUT_CONFIG_OPENMP_RT_TESTS=y -NAUT_CONFIG_RACKET_RT=y - -# -# Devices -# - -# -# Serial Options -# -NAUT_CONFIG_SERIAL_REDIRECT=y -NAUT_CONFIG_SERIAL_REDIRECT_PORT=1 -# NAUT_CONFIG_APIC_FORCE_XAPIC_MODE is not set -# NAUT_CONFIG_APIC_TIMER_CALIBRATE_INDEPENDENTLY is not set -# NAUT_CONFIG_DEBUG_APIC is not set -# NAUT_CONFIG_DEBUG_IOAPIC is not set -# NAUT_CONFIG_DEBUG_PCI is not set -NAUT_CONFIG_DISABLE_PS2_MOUSE=y -# NAUT_CONFIG_DEBUG_PS2 is not set -# NAUT_CONFIG_GPIO is not set -# NAUT_CONFIG_DEBUG_PIT is not set -# NAUT_CONFIG_HPET is not set -# NAUT_CONFIG_VIRTIO_PCI is not set -# NAUT_CONFIG_E1000_PCI is not set -# NAUT_CONFIG_E1000E_PCI is not set -# NAUT_CONFIG_MLX3_PCI is not set -# NAUT_CONFIG_RAMDISK is not set -# NAUT_CONFIG_ATA is not set - -# -# Filesystems -# -# NAUT_CONFIG_EXT2_FILESYSTEM_DRIVER is not set -# NAUT_CONFIG_FAT32_FILESYSTEM_DRIVER is not set - -# -# Networking -# -# NAUT_CONFIG_NET_ETHERNET is not set -# NAUT_CONFIG_NET_COLLECTIVE is not set - -# -# Languages -# -# NAUT_CONFIG_LOAD_LUA is not set diff --git a/Kconfig b/Kconfig index 73a566cf2..3222aa195 100644 --- a/Kconfig +++ b/Kconfig @@ -822,6 +822,29 @@ menu "Garbage Collection Options" endmenu endmenu +menu "Compatability" + config BASE_LIBC_COMPAT + bool "Basic libc compatability"; + default y + help + Basic libc compatability layer + + config BASE_LINUX_COMPAT + bool "Basic Linux user-level compatability layer"; + depends on BASE_LIBC_COMPAT + default y + help + Basic Linux user-level compatability layer + + config BASE_PTHREAD_COMPAT + bool "POSIX threads compatability later"; + default y + depends on BASE_LIBC_COMPAT && BASE_LINUX_COMPAT + help + POSIX threads + +endmenu + menu "Optimizations" config FPU_SAVE @@ -1298,6 +1321,7 @@ menu "Address Spaces" endmenu + menu "Runtimes" config LEGION_RT diff --git a/src/Makefile b/src/Makefile index 30e204233..d2d0a1f43 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,8 @@ obj-y += \ rt/ \ net/ \ acpi/ \ - test/ pthread/ + compat/ \ + test/ obj-$(NAUT_CONFIG_CXX_SUPPORT) += cxx/ obj-$(NAUT_CONFIG_LEGION_RT) += legion_runtime/ diff --git a/src/compat/Makefile b/src/compat/Makefile new file mode 100644 index 000000000..3e5f919fa --- /dev/null +++ b/src/compat/Makefile @@ -0,0 +1,6 @@ + +obj-$(NAUT_CONFIG_BASE_LIBC_COMPAT) += libccompat/ +obj-$(NAUT_CONFIG_BASE_LINUX_COMPAT) += linux/ +obj-$(NAUT_CONFIG_BASE_PTHREAD_COMPAT) += pthread/ + + diff --git a/src/compat/libccompat/Makefile b/src/compat/libccompat/Makefile new file mode 100644 index 000000000..7a854a2cb --- /dev/null +++ b/src/compat/libccompat/Makefile @@ -0,0 +1 @@ +obj-y += libccompat.o libccompat_nomacro.o qsort.o diff --git a/src/nautilus/libccompat.c b/src/compat/libccompat/libccompat.c similarity index 99% rename from src/nautilus/libccompat.c rename to src/compat/libccompat/libccompat.c index 7e95251b0..3a7aa9c10 100644 --- a/src/nautilus/libccompat.c +++ b/src/compat/libccompat/libccompat.c @@ -934,7 +934,6 @@ GEN_DEF(pthread_self) GEN_DEF(pthread_setcancelstate) GEN_DEF(pthread_setcanceltype) GEN_DEF(pthread_setspecific) -GEN_DEF(qsort) GEN_DEF(readdir) GEN_DEF(sched_yield) GEN_DEF(setenv) diff --git a/src/nautilus/libccompat_nomacro.c b/src/compat/libccompat/libccompat_nomacro.c similarity index 100% rename from src/nautilus/libccompat_nomacro.c rename to src/compat/libccompat/libccompat_nomacro.c diff --git a/src/compat/libccompat/qsort.c b/src/compat/libccompat/qsort.c new file mode 100644 index 000000000..a06a4fe30 --- /dev/null +++ b/src/compat/libccompat/qsort.c @@ -0,0 +1,196 @@ +//qsort from clibrary + +#include +#include + +#define __compar_d_fn_t compar_d_fn_t +typedef int (*compar_d_fn_t) (const void *, const void *, void *); +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + size_t __size = (size); \ + char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ + +#define CHAR_BIT 8 +#define STACK_SIZE (CHAR_BIT * sizeof (size_t)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + + +void qsort(void *pbase, size_t total_elems, size_t size, int (*cmp)(const void *, const void*)){ + + char *base_ptr = (char *) pbase; + const size_t max_thresh = MAX_THRESH * size; + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack; + PUSH (NULL, NULL); + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + char *mid = lo + size * ((hi - lo) / size >> 1); + if ((*cmp) ((void *) mid, (void *) lo) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo) < 0) + SWAP (mid, lo, size); + jump_over:; + left_ptr = lo + size; + right_ptr = hi - size; + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid) < 0) + left_ptr += size; + while ((*cmp) ((void *) mid, (void *) right_ptr) < 0) + right_ptr -= size; + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ +#define min(x, y) ((x) < (y) ? (x) : (y)) + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + char *run_ptr; + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0) + tmp_ptr = run_ptr; + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr ) < 0) + tmp_ptr -= size; + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} diff --git a/src/nautilus/Makefile b/src/nautilus/Makefile index 07acf2325..84d62193d 100644 --- a/src/nautilus/Makefile +++ b/src/nautilus/Makefile @@ -37,8 +37,6 @@ obj-y += \ cpu.o \ acpi.o \ numa.o \ - libccompat.o \ - libccompat_nomacro.o \ env.o \ nemo.o \ pmc.o \ From 0449db3c3e30983c088e8c3309062569d0d67e55 Mon Sep 17 00:00:00 2001 From: MJC Date: Sun, 19 Jul 2020 15:12:10 -0500 Subject: [PATCH 18/36] Add Linux compatability tree and stub out sysconf() --- src/compat/linux/Makefile | 3 + src/compat/linux/sysconf.c | 1054 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1057 insertions(+) create mode 100644 src/compat/linux/Makefile create mode 100644 src/compat/linux/sysconf.c diff --git a/src/compat/linux/Makefile b/src/compat/linux/Makefile new file mode 100644 index 000000000..af4529d4f --- /dev/null +++ b/src/compat/linux/Makefile @@ -0,0 +1,3 @@ +CFLAGS += -w + +obj-y += sysconf.o diff --git a/src/compat/linux/sysconf.c b/src/compat/linux/sysconf.c new file mode 100644 index 000000000..eba87af2d --- /dev/null +++ b/src/compat/linux/sysconf.c @@ -0,0 +1,1054 @@ +/* Copyright (C) 1991-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#define ERROR(fmt, args...) ERROR_PRINT("sysconf: " fmt, ##args) + +#define INFO(fmt, args...) INFO_PRINT("sysconf: " fmt, ##args) + + +#define DEBUG(fmt, args...) +#ifdef NAUT_CONFIG_OPENMP_RT_DEBUG +#undef DEBUG +#define DEBUG(fmt, args...) DEBUG_PRINT("sysconf: " fmt, ##args) +#endif + +#define _SC_EQUIV_CLASS_MAX -1 + +#define _SC_THREADS 67 +#define _SC_THREAD_THREADS_MAX 76 +#define _SC_THREAD_STACK_MIN 75 + + +long int +__sysconf (int name) +{ + + //DEBUG("name %d\n", name); + switch (name) + { + + /* Also add obsolete or unnecessarily added constants here. */ + case _SC_THREADS: + DEBUG("_SC_THREADS %d\n", name); + return 0x31069; + case _SC_THREAD_THREADS_MAX: + DEBUG("_sc_thread_threads_max %d\n", name); + return 0x1000; + case _SC_THREAD_STACK_MIN: + DEBUG("sc_thread_stack_min %d\n", name); + return 0x4000; + case 84: + DEBUG("unknown %d\n", name); + return 8; + default: + DEBUG("name %d\n", name); + return 0; + + +/* case _SC_ARG_MAX: */ +/* #ifdef ARG_MAX */ +/* return ARG_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_CHILD_MAX: */ +/* #ifdef CHILD_MAX */ +/* return CHILD_MAX; */ +/* #else */ +/* return __get_child_max (); */ +/* #endif */ +/* case _SC_CLK_TCK: */ +/* return __getclktck (); */ +/* case _SC_NGROUPS_MAX: */ +/* #ifdef NGROUPS_MAX */ +/* return NGROUPS_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_OPEN_MAX: */ +/* return __getdtablesize (); */ +/* case _SC_STREAM_MAX: */ +/* #ifdef STREAM_MAX */ +/* return STREAM_MAX; */ +/* #else */ +/* return FOPEN_MAX; */ +/* #endif */ +/* case _SC_TZNAME_MAX: */ +/* return -1; */ +/* case _SC_JOB_CONTROL: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL) */ +/* return _POSIX_JOB_CONTROL; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SAVED_IDS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SAVED_IDS) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_REALTIME_SIGNALS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_REALTIME_SIGNALS) */ +/* return _POSIX_REALTIME_SIGNALS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PRIORITY_SCHEDULING: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PRIORITY_SCHEDULING) */ +/* return _POSIX_PRIORITY_SCHEDULING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TIMERS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TIMERS) */ +/* return _POSIX_TIMERS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_ASYNCHRONOUS_IO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_ASYNCHRONOUS_IO) */ +/* return _POSIX_ASYNCHRONOUS_IO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PRIORITIZED_IO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PRIORITIZED_IO) */ +/* return _POSIX_PRIORITIZED_IO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SYNCHRONIZED_IO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SYNCHRONIZED_IO) */ +/* return _POSIX_SYNCHRONIZED_IO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FSYNC: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FSYNC) */ +/* return _POSIX_FSYNC; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MAPPED_FILES: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MAPPED_FILES) */ +/* return _POSIX_MAPPED_FILES; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MEMLOCK: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MEMLOCK) */ +/* return _POSIX_MEMLOCK; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MEMLOCK_RANGE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MEMLOCK_RANGE) */ +/* return _POSIX_MEMLOCK_RANGE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MEMORY_PROTECTION: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MEMORY_PROTECTION) */ +/* return _POSIX_MEMORY_PROTECTION; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MESSAGE_PASSING: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MESSAGE_PASSING) */ +/* return _POSIX_MESSAGE_PASSING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SEMAPHORES: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SEMAPHORES) */ +/* return _POSIX_SEMAPHORES; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SHARED_MEMORY_OBJECTS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SHARED_MEMORY_OBJECTS) */ +/* return _POSIX_SHARED_MEMORY_OBJECTS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_VERSION: */ +/* return _POSIX_VERSION; */ +/* case _SC_PAGESIZE: */ +/* return __getpagesize (); */ +/* case _SC_AIO_LISTIO_MAX: */ +/* #ifdef AIO_LISTIO_MAX */ +/* return AIO_LISTIO_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_AIO_MAX: */ +/* #ifdef AIO_MAX */ +/* return AIO_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_AIO_PRIO_DELTA_MAX: */ +/* #ifdef AIO_PRIO_DELTA_MAX */ +/* return AIO_PRIO_DELTA_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_DELAYTIMER_MAX: */ +/* #ifdef DELAYTIMER_MAX */ +/* return DELAYTIMER_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MQ_OPEN_MAX: */ +/* #ifdef MQ_OPEN_MAX */ +/* return MQ_OPEN_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MQ_PRIO_MAX: */ +/* #ifdef MQ_PRIO_MAX */ +/* return MQ_PRIO_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_RTSIG_MAX: */ +/* #ifdef RTSIG_MAX */ +/* return RTSIG_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SEM_NSEMS_MAX: */ +/* #ifdef SEM_NSEMS_MAX */ +/* return SEM_NSEMS_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SEM_VALUE_MAX: */ +/* #ifdef SEM_VALUE_MAX */ +/* return SEM_VALUE_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SIGQUEUE_MAX: */ +/* #ifdef SIGQUEUE_MAX */ +/* return SIGQUEUE_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TIMER_MAX: */ +/* #ifdef TIMER_MAX */ +/* return TIMER_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BC_BASE_MAX: */ +/* #ifdef BC_BASE_MAX */ +/* return BC_BASE_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BC_DIM_MAX: */ +/* #ifdef BC_DIM_MAX */ +/* return BC_DIM_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BC_SCALE_MAX: */ +/* #ifdef BC_SCALE_MAX */ +/* return BC_SCALE_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BC_STRING_MAX: */ +/* #ifdef BC_STRING_MAX */ +/* return BC_STRING_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_COLL_WEIGHTS_MAX: */ +/* #ifdef COLL_WEIGHTS_MAX */ +/* return COLL_WEIGHTS_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_EXPR_NEST_MAX: */ +/* #ifdef EXPR_NEST_MAX */ +/* return EXPR_NEST_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_LINE_MAX: */ +/* #ifdef LINE_MAX */ +/* return LINE_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_RE_DUP_MAX: */ +/* #ifdef RE_DUP_MAX */ +/* return RE_DUP_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_CHARCLASS_NAME_MAX: */ +/* #ifdef CHARCLASS_NAME_MAX */ +/* return CHARCLASS_NAME_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_XTI: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_XTI) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_SOCKET: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_SOCKET) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_INTERNET: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_INTERNET) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_OSI: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_OSI) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_POLL: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_POLL) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SELECT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SELECT) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* /\* The same as _SC_IOV_MAX. *\/ */ +/* case _SC_UIO_MAXIOV: */ +/* #ifdef UIO_MAXIOV */ +/* return UIO_MAXIOV; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_INTERNET_STREAM: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_INTERNET_STREAM) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_INTERNET_DGRAM: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_INTERNET_DGRAM) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_OSI_COTS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_OSI_COTS) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_OSI_CLTS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_OSI_CLTS) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PII_OSI_M: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PII_OSI_M) */ +/* return 1; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_T_IOV_MAX: */ +/* #ifdef _T_IOV_MAX */ +/* return _T_IOV_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_VERSION: */ +/* return _POSIX2_VERSION; */ +/* case _SC_2_C_BIND: */ +/* #ifdef _POSIX2_C_BIND */ +/* return _POSIX2_C_BIND; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_C_DEV: */ +/* #ifdef _POSIX2_C_DEV */ +/* return _POSIX2_C_DEV; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_C_VERSION: */ +/* #ifdef _POSIX2_C_VERSION */ +/* return _POSIX2_C_VERSION; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_FORT_DEV: */ +/* #ifdef _POSIX2_FORT_DEV */ +/* return _POSIX2_FORT_DEV; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_FORT_RUN: */ +/* #ifdef _POSIX2_FORT_RUN */ +/* return _POSIX2_FORT_RUN; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_LOCALEDEF: */ +/* #ifdef _POSIX2_LOCALEDEF */ +/* return _POSIX2_LOCALEDEF; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_SW_DEV: */ +/* #ifdef _POSIX2_SW_DEV */ +/* return _POSIX2_SW_DEV; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_CHAR_TERM: */ +/* #ifdef _POSIX2_CHAR_TERM */ +/* return _POSIX2_CHAR_TERM; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_UPE: */ +/* #ifdef _POSIX2_UPE */ +/* return _POSIX2_UPE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* /\* POSIX 1003.1c (POSIX Threads). *\/ */ +/* case _SC_THREADS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREADS) */ +/* return _POSIX_THREADS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_SAFE_FUNCTIONS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_SAFE_FUNCTIONS) */ +/* return _POSIX_THREAD_SAFE_FUNCTIONS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_GETGR_R_SIZE_MAX: */ +/* return NSS_BUFLEN_GROUP; */ +/* case _SC_GETPW_R_SIZE_MAX: */ +/* return NSS_BUFLEN_PASSWD; */ +/* case _SC_LOGIN_NAME_MAX: */ +/* #ifdef LOGIN_NAME_MAX */ +/* return LOGIN_NAME_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TTY_NAME_MAX: */ +/* #ifdef TTY_NAME_MAX */ +/* return TTY_NAME_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_DESTRUCTOR_ITERATIONS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_DESTRUCTOR_ITERATIONS) */ +/* return _POSIX_THREAD_DESTRUCTOR_ITERATIONS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_KEYS_MAX: */ +/* #ifdef PTHREAD_KEYS_MAX */ +/* return PTHREAD_KEYS_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_STACK_MIN: */ +/* #ifdef PTHREAD_STACK_MIN */ +/* return PTHREAD_STACK_MIN; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_THREADS_MAX: */ +/* #ifdef PTHREAD_THREADS_MAX */ +/* return PTHREAD_THREADS_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_ATTR_STACKADDR: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_ATTR_STACKADDR) */ +/* return _POSIX_THREAD_ATTR_STACKADDR; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_ATTR_STACKSIZE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_ATTR_STACKSIZE) */ +/* return _POSIX_THREAD_ATTR_STACKSIZE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_PRIORITY_SCHEDULING: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_PRIORITY_SCHEDULING) */ +/* return _POSIX_THREAD_PRIORITY_SCHEDULING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_PRIO_INHERIT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_PRIO_INHERIT) */ +/* return _POSIX_THREAD_PRIO_INHERIT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_PRIO_PROTECT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_PRIO_PROTECT) */ +/* return _POSIX_THREAD_PRIO_PROTECT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_PROCESS_SHARED: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_PROCESS_SHARED) */ +/* return _POSIX_THREAD_PROCESS_SHARED; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NPROCESSORS_CONF: */ +/* return __get_nprocs_conf (); */ +/* case _SC_NPROCESSORS_ONLN: */ +/* return __get_nprocs (); */ +/* case _SC_PHYS_PAGES: */ +/* return __get_phys_pages (); */ +/* case _SC_AVPHYS_PAGES: */ +/* return __get_avphys_pages (); */ +/* case _SC_ATEXIT_MAX: */ +/* /\* We have no limit since we use lists. *\/ */ +/* return INT_MAX; */ +/* case _SC_PASS_MAX: */ +/* /\* We have no limit but since the return value might be used to */ +/* allocate a buffer we restrict the value. *\/ */ +/* return BUFSIZ; */ +/* case _SC_XOPEN_VERSION: */ +/* return _XOPEN_VERSION; */ +/* case _SC_XOPEN_XCU_VERSION: */ +/* return _XOPEN_XCU_VERSION; */ +/* case _SC_XOPEN_UNIX: */ +/* return _XOPEN_UNIX; */ +/* case _SC_XOPEN_CRYPT: */ +/* #ifdef _XOPEN_CRYPT */ +/* return _XOPEN_CRYPT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_ENH_I18N: */ +/* #ifdef _XOPEN_ENH_I18N */ +/* return _XOPEN_ENH_I18N; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_SHM: */ +/* #ifdef _XOPEN_SHM */ +/* return _XOPEN_SHM; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_XPG2: */ +/* #ifdef _XOPEN_XPG2 */ +/* return _XOPEN_XPG2; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_XPG3: */ +/* #ifdef _XOPEN_XPG3 */ +/* return _XOPEN_XPG3; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_XPG4: */ +/* #ifdef _XOPEN_XPG4 */ +/* return _XOPEN_XPG4; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_CHAR_BIT: */ +/* return CHAR_BIT; */ +/* case _SC_CHAR_MAX: */ +/* return CHAR_MAX; */ +/* case _SC_CHAR_MIN: */ +/* return CHAR_MIN; */ +/* case _SC_INT_MAX: */ +/* return INT_MAX; */ +/* case _SC_INT_MIN: */ +/* return INT_MIN; */ +/* case _SC_LONG_BIT: */ +/* return sizeof (long int) * CHAR_BIT; */ +/* case _SC_WORD_BIT: */ +/* return sizeof (int) * CHAR_BIT; */ +/* case _SC_MB_LEN_MAX: */ +/* return MB_LEN_MAX; */ +/* case _SC_NZERO: */ +/* return NZERO; */ +/* case _SC_SSIZE_MAX: */ +/* return _POSIX_SSIZE_MAX; */ +/* case _SC_SCHAR_MAX: */ +/* return SCHAR_MAX; */ +/* case _SC_SCHAR_MIN: */ +/* return SCHAR_MIN; */ +/* case _SC_SHRT_MAX: */ +/* return SHRT_MAX; */ +/* case _SC_SHRT_MIN: */ +/* return SHRT_MIN; */ +/* case _SC_UCHAR_MAX: */ +/* return UCHAR_MAX; */ +/* case _SC_UINT_MAX: */ +/* return UINT_MAX; */ +/* case _SC_ULONG_MAX: */ +/* return ULONG_MAX; */ +/* case _SC_USHRT_MAX: */ +/* return USHRT_MAX; */ +/* case _SC_NL_ARGMAX: */ +/* #ifdef NL_ARGMAX */ +/* return NL_ARGMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NL_LANGMAX: */ +/* #ifdef NL_LANGMAX */ +/* return NL_LANGMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NL_MSGMAX: */ +/* #ifdef NL_MSGMAX */ +/* return NL_MSGMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NL_NMAX: */ +/* #ifdef NL_NMAX */ +/* return NL_NMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NL_SETMAX: */ +/* #ifdef NL_SETMAX */ +/* return NL_SETMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NL_TEXTMAX: */ +/* #ifdef NL_TEXTMAX */ +/* return NL_TEXTMAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* #define START_ENV_GROUP(VERSION) \ */ +/* /\* Empty. *\/ */ +/* #define END_ENV_GROUP(VERSION) \ */ +/* /\* Empty. *\/ */ +/* #define KNOWN_ABSENT_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX) \ */ +/* case _SC_##SC_PREFIX##_##SUFFIX: \ */ +/* return _##ENV_PREFIX##_##SUFFIX; */ +/* #define KNOWN_PRESENT_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX) \ */ +/* case _SC_##SC_PREFIX##_##SUFFIX: \ */ +/* return _##ENV_PREFIX##_##SUFFIX; */ +/* #define UNKNOWN_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX) \ */ +/* case _SC_##SC_PREFIX##_##SUFFIX: \ */ +/* return __sysconf_check_spec (#SUFFIX); */ +/* #include */ +/* #undef START_ENV_GROUP */ +/* #undef END_ENV_GROUP */ +/* #undef KNOWN_ABSENT_ENVIRONMENT */ +/* #undef KNOWN_PRESENT_ENVIRONMENT */ +/* #undef UNKNOWN_ENVIRONMENT */ +/* case _SC_XOPEN_LEGACY: */ +/* return _XOPEN_LEGACY; */ +/* case _SC_XOPEN_REALTIME: */ +/* #ifdef _XOPEN_REALTIME */ +/* return _XOPEN_REALTIME; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_XOPEN_REALTIME_THREADS: */ +/* #ifdef _XOPEN_REALTIME_THREADS */ +/* return _XOPEN_REALTIME_THREADS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_ADVISORY_INFO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_ADVISORY_INFO) */ +/* return _POSIX_ADVISORY_INFO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BARRIERS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_BARRIERS) */ +/* return _POSIX_BARRIERS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_BASE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_BASE) */ +/* return _POSIX_BASE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_C_LANG_SUPPORT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_C_LANG_SUPPORT) */ +/* return _POSIX_C_LANG_SUPPORT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_C_LANG_SUPPORT_R: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_C_LANG_SUPPORT_R) */ +/* return _POSIX_C_LANG_SUPPORT_R; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_CLOCK_SELECTION: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_CLOCK_SELECTION) */ +/* return _POSIX_CLOCK_SELECTION; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_CPUTIME: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_CPUTIME) */ +/* return _POSIX_CPUTIME; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_DEVICE_IO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_DEVICE_IO) */ +/* return _POSIX_DEVICE_IO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_DEVICE_SPECIFIC: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_DEVICE_SPECIFIC) */ +/* return _POSIX_DEVICE_SPECIFIC; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_DEVICE_SPECIFIC_R: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_DEVICE_SPECIFIC_R) */ +/* return _POSIX_DEVICE_SPECIFIC_R; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FD_MGMT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FD_MGMT) */ +/* return _POSIX_FD_MGMT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FIFO: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FIFO) */ +/* return _POSIX_FIFO; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_PIPE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_PIPE) */ +/* return _POSIX_PIPE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FILE_ATTRIBUTES: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FILE_ATTRIBUTES) */ +/* return _POSIX_FILE_ATTRIBUTES; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FILE_LOCKING: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FILE_LOCKING) */ +/* return _POSIX_FILE_LOCKING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_FILE_SYSTEM: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_FILE_SYSTEM) */ +/* return _POSIX_FILE_SYSTEM; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MONOTONIC_CLOCK: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MONOTONIC_CLOCK) */ +/* return _POSIX_MONOTONIC_CLOCK; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_MULTI_PROCESS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_MULTI_PROCESS) */ +/* return _POSIX_MULTI_PROCESS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SINGLE_PROCESS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SINGLE_PROCESS) */ +/* return _POSIX_SINGLE_PROCESS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_NETWORKING: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_NETWORKING) */ +/* return _POSIX_NETWORKING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_READER_WRITER_LOCKS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_READER_WRITER_LOCKS) */ +/* return _POSIX_READER_WRITER_LOCKS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SPIN_LOCKS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SPIN_LOCKS) */ +/* return _POSIX_SPIN_LOCKS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_REGEXP: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_REGEXP) */ +/* return _POSIX_REGEXP; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* /\* _REGEX_VERSION has been removed with IEEE Std 1003.1-2001/Cor 2-2004, */ +/* item XSH/TC2/D6/137. *\/ */ +/* case _SC_REGEX_VERSION: */ +/* return -1; */ +/* case _SC_SHELL: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SHELL) */ +/* return _POSIX_SHELL; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SIGNALS: */ +/* #if CONF_IS_DEFINED (_POSIX_SIGNALS) */ +/* return _POSIX_SIGNALS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SPAWN: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SPAWN) */ +/* return _POSIX_SPAWN; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SPORADIC_SERVER: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SPORADIC_SERVER) */ +/* return _POSIX_SPORADIC_SERVER; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_SPORADIC_SERVER: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_SPORADIC_SERVER) */ +/* return _POSIX_THREAD_SPORADIC_SERVER; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SYSTEM_DATABASE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SYSTEM_DATABASE) */ +/* return _POSIX_SYSTEM_DATABASE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SYSTEM_DATABASE_R: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_SYSTEM_DATABASE_R) */ +/* return _POSIX_SYSTEM_DATABASE_R; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_THREAD_CPUTIME: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_THREAD_CPUTIME) */ +/* return _POSIX_THREAD_CPUTIME; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TIMEOUTS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TIMEOUTS) */ +/* return _POSIX_TIMEOUTS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TYPED_MEMORY_OBJECTS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TYPED_MEMORY_OBJECTS) */ +/* return _POSIX_TYPED_MEMORY_OBJECTS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_USER_GROUPS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_USER_GROUPS) */ +/* return _POSIX_USER_GROUPS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_USER_GROUPS_R: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_USER_GROUPS_R) */ +/* return _POSIX_USER_GROUPS_R; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS: */ +/* #ifdef _POSIX2_PBS */ +/* return _POSIX2_PBS; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS_ACCOUNTING: */ +/* #ifdef _POSIX2_PBS_ACCOUNTING */ +/* return _POSIX2_PBS_ACCOUNTING; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS_CHECKPOINT: */ +/* #ifdef _POSIX2_PBS_CHECKPOINT */ +/* return _POSIX2_PBS_CHECKPOINT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS_LOCATE: */ +/* #ifdef _POSIX2_PBS_LOCATE */ +/* return _POSIX2_PBS_LOCATE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS_MESSAGE: */ +/* #ifdef _POSIX2_PBS_MESSAGE */ +/* return _POSIX2_PBS_MESSAGE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_2_PBS_TRACK: */ +/* #ifdef _POSIX2_PBS_TRACK */ +/* return _POSIX2_PBS_TRACK; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_SYMLOOP_MAX: */ +/* #ifdef SYMLOOP_MAX */ +/* return SYMLOOP_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_STREAMS: */ +/* return -1; */ +/* case _SC_HOST_NAME_MAX: */ +/* #ifdef HOST_NAME_MAX */ +/* return HOST_NAME_MAX; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TRACE: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TRACE) */ +/* return _POSIX_TRACE; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TRACE_EVENT_FILTER: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TRACE_EVENT_FILTER) */ +/* return _POSIX_TRACE_EVENT_FILTER; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TRACE_INHERIT: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TRACE_INHERIT) */ +/* return _POSIX_TRACE_INHERIT; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TRACE_LOG: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_TRACE_LOG) */ +/* return _POSIX_TRACE_LOG; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_TRACE_EVENT_NAME_MAX: */ +/* case _SC_TRACE_NAME_MAX: */ +/* case _SC_TRACE_SYS_MAX: */ +/* case _SC_TRACE_USER_EVENT_MAX: */ +/* /\* No support for tracing. *\/ */ +/* case _SC_XOPEN_STREAMS: */ +/* /\* No support for STREAMS. *\/ */ +/* return -1; */ +/* case _SC_LEVEL1_ICACHE_SIZE: */ +/* case _SC_LEVEL1_ICACHE_ASSOC: */ +/* case _SC_LEVEL1_ICACHE_LINESIZE: */ +/* case _SC_LEVEL1_DCACHE_SIZE: */ +/* case _SC_LEVEL1_DCACHE_ASSOC: */ +/* case _SC_LEVEL1_DCACHE_LINESIZE: */ +/* case _SC_LEVEL2_CACHE_SIZE: */ +/* case _SC_LEVEL2_CACHE_ASSOC: */ +/* case _SC_LEVEL2_CACHE_LINESIZE: */ +/* case _SC_LEVEL3_CACHE_SIZE: */ +/* case _SC_LEVEL3_CACHE_ASSOC: */ +/* case _SC_LEVEL3_CACHE_LINESIZE: */ +/* case _SC_LEVEL4_CACHE_SIZE: */ +/* case _SC_LEVEL4_CACHE_ASSOC: */ +/* case _SC_LEVEL4_CACHE_LINESIZE: */ +/* /\* In general we cannot determine these values. Therefore we */ +/* return zero which indicates that no information is */ +/* available. *\/ */ +/* return 0; */ +/* case _SC_IPV6: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_IPV6) */ +/* return _POSIX_IPV6; */ +/* #else */ +/* return -1; */ +/* #endif */ +/* case _SC_RAW_SOCKETS: */ +/* #if CONF_IS_DEFINED_SET (_POSIX_RAW_SOCKETS) */ +/* return _POSIX_RAW_SOCKETS; */ +/* #else */ +/* return -1; */ +/* #endif */ + } +} +//#undef __sysconf +//weak_alias (__sysconf, sysconf) +//libc_hidden_def (__sysconf) +/* #if NEED_CHECK_SPEC */ + +/* static long int */ +/* __sysconf_check_spec (const char *spec) */ +/* { */ +/* int save_errno = errno; */ +/* const char *getconf_dir = __libc_secure_getenv ("GETCONF_DIR") ?: GETCONF_DIR; */ +/* size_t getconf_dirlen = strlen (getconf_dir); */ +/* size_t speclen = strlen (spec); */ +/* char name[getconf_dirlen + sizeof ("/POSIX_V6_") + speclen]; */ +/* memcpy (mempcpy (mempcpy (name, getconf_dir, getconf_dirlen), */ +/* "/POSIX_V6_", sizeof ("/POSIX_V6_") - 1), */ +/* spec, speclen + 1); */ +/* struct stat64 st; */ +/* long int ret = __xstat64 (_STAT_VER, name, &st) >= 0 ? 1 : -1; */ +/* __set_errno (save_errno); */ +/* return ret; */ +/* } */ +/* #endif */ From acf2bafa3d7194d6d6e213f0384f27f190fa08b5 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Wed, 15 Jul 2020 13:09:13 -0500 Subject: [PATCH 19/36] Adds optional runtime support for hardware TLS via the FSBASE msr This adds an fsbase field to the thread structure. A child thread inherits the fsbase of its parent. A function allows the thread to change fsbase at any time. The context switch code switches fsbase on a thread context switch. This feature can be Kconfiged off. --- Kconfig | 9 +++++++++ include/nautilus/thread.h | 6 ++++++ src/asm/thread_lowlevel.S | 16 ++++++++++++++++ src/nautilus/thread.c | 10 ++++++++++ 4 files changed, 41 insertions(+) diff --git a/Kconfig b/Kconfig index 3222aa195..cda0e12bd 100644 --- a/Kconfig +++ b/Kconfig @@ -662,6 +662,15 @@ config DEBUG_ISOCORE Adds debugging output for isolated core execution The low-level code does not have debugging output +config HARDWARE_TLS + bool "Enable hardware thread-local storage (FSBASE)" + default n + depends on X86_64_HOST + help + Enables use of FSBASE to do faster TLS + When enabled, a thread context switch includes an + FSBASE context switch + config CACHEPART bool "Enable cache partitioning" default n diff --git a/include/nautilus/thread.h b/include/nautilus/thread.h index f9af66ef3..200e60762 100644 --- a/include/nautilus/thread.h +++ b/include/nautilus/thread.h @@ -104,6 +104,9 @@ void nk_set_thread_output(void * result); // Give a thread a name int nk_thread_name(nk_thread_id_t tid, char *name); +// Give a thread a HW TLS space +int nk_thread_change_hw_tls(nk_thread_id_t tid, void *hwtls); + // explicit yield (hides details of the scheduler) void nk_yield(); @@ -181,6 +184,9 @@ struct nk_thread { cache_part_state; /* Always included to reserve this "slot" for asm code */ nk_aspace_t *aspace; /* +24 SHOULD NOT CHANGE POSITION */ /* Always included to reserve this "slot" for asm code */ + void *hwtls; /* +32 SHOULD NOT CHANGE POSITION */ + /* Always included to reserve this "slot" for asm code */ + /* even if TLS is off; this is the FSBASE for the thread */ nk_stack_size_t stack_size; unsigned long tid; diff --git a/src/asm/thread_lowlevel.S b/src/asm/thread_lowlevel.S index d734a9cfe..7d768eb55 100644 --- a/src/asm/thread_lowlevel.S +++ b/src/asm/thread_lowlevel.S @@ -147,6 +147,22 @@ continue_context_switch: call nk_aspace_switch pop %rax #endif + +#ifdef NAUT_CONFIG_HARDWARE_TLS + push %rax // save regs we will use + push %rdx + push %rcx + + movl 36(%rax), %edx // get big end of fsbase from thread struct + movl 32(%rax), %eax // get little end of fsbase from thread struct + movq $0xc0000100, %rcx // get FSBASE MSR number into RCX for use by wrmsr + + wrmsr // actually change fsbase + + pop %rcx // restore regs we have usd + pop %rdx + pop %rax +#endif movq %rax, %gs:0x0 /* make it the new current thread */ movq (%rax), %rsp /* load its stack pointer */ diff --git a/src/nautilus/thread.c b/src/nautilus/thread.c index 3fa0c96e0..f94e9d8e8 100644 --- a/src/nautilus/thread.c +++ b/src/nautilus/thread.c @@ -367,6 +367,9 @@ nk_thread_create (nk_thread_fun_t fun, // a thread joins its creator's address space t->aspace = get_cur_thread()->aspace; + + // a thread joins its creator's HW TLS space + t->hwtls = get_cur_thread()->hwtls; t->fun = fun; t->input = input; @@ -515,6 +518,13 @@ int nk_thread_name(nk_thread_id_t tid, char *name) return 0; } +int nk_thread_change_hw_tls(nk_thread_id_t tid, void *hwtls) +{ + ((nk_thread_t*)tid)->hwtls = hwtls; + msr_write(MSR_FS_BASE,(uint64_t)hwtls); + return 0; +} + /* * wake_waiters From 92be9440244ac7714f6e500a9bbd7ece077af9cc Mon Sep 17 00:00:00 2001 From: MJC Date: Sun, 19 Jul 2020 17:19:48 -0500 Subject: [PATCH 20/36] Initial port of pthread library to NK --- src/compat/pthread/Makefile | 22 +- src/compat/pthread/create.c | 12 +- src/compat/pthread/debug.h | 14 + src/compat/pthread/implement.h | 7 +- src/compat/pthread/nk/Makefile | 7 + src/compat/pthread/nk/nk_osal.c | 678 ++++++++++++++++++ src/compat/pthread/nk/pte_generic_osal.h | 449 ++++++++++++ src/compat/pthread/nk/pte_osal.h | 70 ++ src/compat/pthread/nk/pte_types.h | 52 ++ .../pthread/pte_callUserDestroyRoutines.c | 8 +- src/compat/pthread/pte_cancellable_wait.c | 6 +- src/compat/pthread/pte_generic_osal.h | 1 - src/compat/pthread/pte_new.c | 9 +- src/compat/pthread/pte_relmillisecs.c | 2 +- src/compat/pthread/pte_reuse.c | 10 +- src/compat/pthread/pte_threadDestroy.c | 9 +- src/compat/pthread/pte_threadStart.c | 12 +- src/compat/pthread/pte_throw.c | 5 +- src/compat/pthread/pte_tkAssocCreate.c | 7 +- src/compat/pthread/pte_tkAssocDestroy.c | 5 +- src/compat/pthread/pthread.h | 28 +- src/compat/pthread/pthread_attr_destroy.c | 5 +- .../pthread/pthread_attr_getschedparam.c | 8 +- src/compat/pthread/pthread_attr_init.c | 5 +- .../pthread/pthread_attr_setschedparam.c | 8 +- src/compat/pthread/pthread_barrier_destroy.c | 8 +- src/compat/pthread/pthread_barrier_init.c | 10 +- .../pthread/pthread_barrierattr_destroy.c | 5 +- src/compat/pthread/pthread_barrierattr_init.c | 7 +- src/compat/pthread/pthread_cancel.c | 5 +- src/compat/pthread/pthread_cond_destroy.c | 8 +- src/compat/pthread/pthread_cond_init.c | 9 +- src/compat/pthread/pthread_condattr_destroy.c | 8 +- src/compat/pthread/pthread_condattr_init.c | 7 +- src/compat/pthread/pthread_delay_np.c | 4 +- src/compat/pthread/pthread_detach.c | 4 +- src/compat/pthread/pthread_init.c | 6 +- src/compat/pthread/pthread_join.c | 10 +- src/compat/pthread/pthread_key_create.c | 7 +- src/compat/pthread/pthread_key_delete.c | 6 +- src/compat/pthread/pthread_kill.c | 9 +- src/compat/pthread/pthread_mutex_destroy.c | 9 +- src/compat/pthread/pthread_mutex_init.c | 18 +- src/compat/pthread/pthread_mutex_lock.c | 13 +- src/compat/pthread/pthread_mutex_timedlock.c | 8 +- src/compat/pthread/pthread_mutex_unlock.c | 13 +- .../pthread/pthread_mutexattr_destroy.c | 4 +- src/compat/pthread/pthread_mutexattr_init.c | 6 +- src/compat/pthread/pthread_once.c | 4 +- src/compat/pthread/pthread_rwlock_destroy.c | 10 +- src/compat/pthread/pthread_rwlock_init.c | 13 +- src/compat/pthread/pthread_rwlock_rdlock.c | 6 +- .../pthread/pthread_rwlock_timedrdlock.c | 6 +- .../pthread/pthread_rwlock_timedwrlock.c | 6 +- src/compat/pthread/pthread_rwlock_tryrdlock.c | 6 +- src/compat/pthread/pthread_rwlock_trywrlock.c | 6 +- src/compat/pthread/pthread_rwlock_unlock.c | 6 +- src/compat/pthread/pthread_rwlock_wrlock.c | 6 +- .../pthread/pthread_rwlockattr_destroy.c | 9 +- .../pthread/pthread_rwlockattr_getpshared.c | 6 +- src/compat/pthread/pthread_rwlockattr_init.c | 10 +- .../pthread/pthread_rwlockattr_setpshared.c | 6 +- src/compat/pthread/pthread_self.c | 6 +- src/compat/pthread/pthread_spin_destroy.c | 7 +- src/compat/pthread/pthread_spin_init.c | 9 +- src/compat/pthread/pthread_terminate.c | 9 +- .../pthread/pthread_timechange_handler_np.c | 2 +- src/compat/pthread/sched.h | 2 +- src/compat/pthread/sched_yield.c | 8 +- src/compat/pthread/sem_destroy.c | 8 +- src/compat/pthread/sem_init.c | 8 +- src/compat/pthread/sem_post.c | 6 +- src/compat/pthread/sem_post_multiple.c | 6 +- src/compat/pthread/sem_timedwait.c | 6 +- src/compat/pthread/sem_wait.c | 6 +- 75 files changed, 1568 insertions(+), 238 deletions(-) create mode 100644 src/compat/pthread/debug.h create mode 100644 src/compat/pthread/nk/Makefile create mode 100644 src/compat/pthread/nk/nk_osal.c create mode 100644 src/compat/pthread/nk/pte_generic_osal.h create mode 100644 src/compat/pthread/nk/pte_osal.h create mode 100644 src/compat/pthread/nk/pte_types.h diff --git a/src/compat/pthread/Makefile b/src/compat/pthread/Makefile index 46112397e..71f2dfb49 100644 --- a/src/compat/pthread/Makefile +++ b/src/compat/pthread/Makefile @@ -1,3 +1,10 @@ +CFLAGS += -w +NK_LIB =\ + nk/ + +PTHREAD_TEST =\ + pthreadtest/ + MUTEX_OBJS = \ pthread_mutex_unlock.o \ pthread_mutex_init.o \ @@ -58,8 +65,9 @@ THREAD_OBJS = \ pthread_getschedparam.o \ pthread_setschedparam.o \ sched_get_priority_max.o \ - sched_get_priority_min.o - + sched_get_priority_min.o \ + pthread_attr_getstack.o \ + pthread_getattr_np.o TLS_OBJS = \ pthread_key_create.o \ @@ -146,13 +154,11 @@ CANCEL_OBJS = \ pthread_setcanceltype.o \ pthread_setcancelstate.o -OS_OBJS = \ - nautilus_osal.o \ - tls-helper.o -OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) -CFLAGS += -I/home/pdinda/class/nautilus-pdinda/src/pthread +OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) +obj-y +=$(OBJS) \ + $(NK_LIB) \ + $(PTHREAD_TEST) -obj-y := $(OBJS) diff --git a/src/compat/pthread/create.c b/src/compat/pthread/create.c index 1cb6539ab..5a4945892 100644 --- a/src/compat/pthread/create.c +++ b/src/compat/pthread/create.c @@ -41,12 +41,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include "pte_osal.h" -#include -#include - +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" +#include int pthread_create (pthread_t * tid, @@ -139,6 +137,9 @@ pthread_create (pthread_t * tid, parms->start = start; parms->arg = arg; + //mjc add thread attr + //thread.attr = *attr; + if (a != NULL) { stackSize = a->stacksize; @@ -206,7 +207,8 @@ pthread_create (pthread_t * tid, (void) pthread_mutex_unlock (&tp->threadLock); } - osResult = pte_osThreadCreate(pte_threadStart, + //mjc change pte_threadstart to function pointer + osResult = pte_osThreadCreate((void *)&pte_threadStart, stackSize, priority, parms, diff --git a/src/compat/pthread/debug.h b/src/compat/pthread/debug.h new file mode 100644 index 000000000..0440975ad --- /dev/null +++ b/src/compat/pthread/debug.h @@ -0,0 +1,14 @@ +#ifndef _PTHREAD_DEBUG +#define _PTHREAD_DEBUG + +#define ERROR(fmt, args...) ERROR_PRINT("pthread: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("pthread: " fmt, ##args) + +#ifdef NAUT_CONFIG_DEBUG_BASE_PTHREAD_COMPAT +#define DEBUG(fmt, args...) DEBUG_PRINT("pthread: " fmt, ##args) +#else +#define DEBUG(fmt, args...) +#endif + +#endif + diff --git a/src/compat/pthread/implement.h b/src/compat/pthread/implement.h index 25ae4f181..b54e302b3 100644 --- a/src/compat/pthread/implement.h +++ b/src/compat/pthread/implement.h @@ -51,7 +51,7 @@ #ifndef _IMPLEMENT_H #define _IMPLEMENT_H -#include "pte_osal.h" +#include "nk/pte_osal.h" /* use local include files during development */ #include "semaphore.h" @@ -476,8 +476,9 @@ extern "C" int pte_setthreadpriority (pthread_t thread, int policy, int priority); void pte_rwlock_cancelwrwait (void *arg); - - int pte_threadStart (void *vthreadParms); + + //mjc add out + int pte_threadStart (void *vthreadParms, void ** out); void pte_callUserDestroyRoutines (pthread_t thread); diff --git a/src/compat/pthread/nk/Makefile b/src/compat/pthread/nk/Makefile new file mode 100644 index 000000000..ed18ff07c --- /dev/null +++ b/src/compat/pthread/nk/Makefile @@ -0,0 +1,7 @@ +#obj-y += openmpbench_C_v31/ +CFLAGS += -w + +obj-y += nk_osal.o + +#obj-$(NAUT_CONFIG_OPENMP_RT) += pthread_emb/ + diff --git a/src/compat/pthread/nk/nk_osal.c b/src/compat/pthread/nk/nk_osal.c new file mode 100644 index 000000000..ce38c7641 --- /dev/null +++ b/src/compat/pthread/nk/nk_osal.c @@ -0,0 +1,678 @@ + +#include "../debug.h" +#include "pte_types.h" +#include "pte_osal.h" +#include +#include +#include +#include +#include + + +#define STATE_UNLOCK(a,b) spin_unlock_irq_restore(a,b) +#define STATE_TRY_LOCK(a,b) spin_try_lock_irq_save(a,b) +#define STATE_LOCK(a) spin_lock_irq_save(a) +#define RESTORE_UNIRQ(a,b) irq_enable_restore(b) + + +#define ZOMBIE 200 //after busy wait for ZOMBIE time check condition +#define ZOMBIE_mode true //Put to sleep if true after ZOMBIE time + + +//retrive osHandle from thread +#define poffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#define pcontainer_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define TIME() (unsigned int)nk_sched_get_realtime(); + +//nano s to micro seconds +#define NS 1000000ULL + + +//specific/duplicate of nk function goes here +static int exit_check(void *state) +{ + volatile nk_thread_t *thethread = (nk_thread_t *)state; + + DEBUG("exit_check: thread (%lu %s) status is %u\n",thethread->tid,thethread->name,thethread->status); + return thethread->status==NK_THR_EXITED; +} + + +pte_osResult pte_osInit(void){ + return PTE_OS_OK; +} + +/*=============================================================================* + * Creates a mutex + * @param pHandle Set to the handle of the newly created mutex. + * + * @return PTE_OS_OK - Mutex successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex + *==========================================================================*/ + +pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle){ + + *pHandle = malloc(sizeof(struct pmutex)); + spinlock_init(&((*pHandle)->lock)); + DEBUG("osMutexCreate\n"); + return PTE_OS_OK; +} + +pte_osResult pte_osMutexDelete(pte_osMutexHandle handle){ + spinlock_deinit(&(handle->lock)); + DEBUG("osMutexDelete\n"); + return PTE_OS_OK; +} + +/*=================================================================* + * Locks the mutex + * + * @param handle Handle of mutex to lock. + * + * @return PTE_OS_OK - Mutex successfully locked. + *=================================================================*/ +pte_osResult pte_osMutexLock(pte_osMutexHandle handle){ + + handle->flags = STATE_LOCK(&(handle->lock)); + DEBUG("osMutexLock\n"); + return PTE_OS_OK; + +} + + +pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeout){ + unsigned int start = TIME(); + unsigned int end = start; + int res = -1; + while( (end-start) lock), &(handle->flags) ); + DEBUG("osMutexTimedLock\n"); + end = TIME(); + if(res == 0){ + return PTE_OS_OK; + } + } + return PTE_OS_TIMEOUT; +} + + +pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle){ + STATE_UNLOCK(&(handle->lock), handle->flags); + DEBUG("osMutexUnlock\n"); + return PTE_OS_OK; +} + +/*======================================================================================================* + * Creates a new thread. The thread must be started in a suspended state - it will be + * explicitly started when pte_osThreadStart() is called. + * + * @param entryPoint Entry point to the new thread. + * @param stackSize The initial stack size, in bytes. Note that this can be considered a minimum - + * for instance if the OS requires a larger stack space than what the caller specified. + * @param initialPriority The priority that the new thread should be initially set to. + * @param argv Parameter to pass to the new thread. + * @param ppte_osThreadHandle set to the handle of the new thread. + * + * @return PTE_OS_OK - New thread successfully created. + * @return PTE_OS_NO_RESOURCES - Insufficient resources to create thread + *============================================================================================================*/ + +pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, + int stackSize, + int initialPriority, + void *argv, + pte_osThreadHandle* handle) +{ + //pte_osThreadEntryPoint is nk_thread_fun + //pte_osThreadhandle will be nk_thread_id + + pte_osThreadHandle handleobj = malloc(sizeof(struct thread_with_signal)); + + memset(handleobj,0,sizeof(struct thread_with_signal)); + + int ret = nk_thread_create(entryPoint, argv, NULL, false,(nk_stack_size_t) stackSize, &(handleobj->tid),-1); + if (ret != 0){ + ERROR("create error exit\n"); + return PTE_OS_NO_RESOURCES; + } + + *handle = handleobj; + struct nk_thread* thread = (struct nk_thread*) (*handle)->tid; + + DEBUG("osThreadCreate %p, %lu ref %lu\n", thread, thread->tid, thread->refcount); + + return PTE_OS_OK; +} + + +pte_osResult pte_osThreadStart(pte_osThreadHandle handle){ + + nk_thread_run(handle->tid); + DEBUG("osThreadStart %08x\n", handle); + + return PTE_OS_OK; +} + +void pte_osThreadExit(){ + DEBUG("osthread EXIT\n"); + nk_thread_exit(NULL); +} + + +/*=================================================================* + * Waits for the specified thread to end. + * If the thread has already terminated, this returns immediately. + * @param threadHandle Handle fo thread to wait for. + * + * @return PTE_OS_OK - specified thread terminated. + *=================================================================*/ +pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle){ + DEBUG("pte osThread Wait For End\n"); + nk_thread_t *thethread = (nk_thread_t*) (threadHandle->tid); + + // both ok + //nk_wait_queue_sleep_extended(thethread->waitq, exit_check, thethread); + + return nk_join(thethread, NULL); +} + + +/*=================================================================* + * Returns the handle of the currently executing thread. + *=================================================================*/ +pte_osThreadHandle pte_osThreadGetHandle(void){ + //note pte_osThreadHandle is a pointer of struct _thread_with_signal + nk_thread_t* thethread = get_cur_thread(); + DEBUG("osThreadGetHandle\n"); + return (pte_osThreadHandle) pcontainer_of(thethread,struct thread_with_signal, tid); +} + +int pte_osThreadGetPriority(pte_osThreadHandle threadHandle){ + return 0; +} + +pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority){ + return PTE_OS_OK; + +} + +pte_osResult pte_osThreadDelete(pte_osThreadHandle handle){ + DEBUG("osThreadDelete\n"); + nk_thread_exit(NULL); + return PTE_OS_OK; +} + +/*============================================================================================== + * Frees resources associated with the specified thread and then causes the thread to exit. + * This is called after the thread has terminated and is no longer needed (e.g. after + * pthread_join returns). This call will always be made from the context of the target thread. + *===============================================================================================*/ +pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle){ + + DEBUG("osThreadExitDelete\n"); + nk_thread_exit(NULL); + +} + +/*======================================================================================= + * Cancel Not Supported + * This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel() + * to return @p PTE_OS_INTERRUPTED. + * + * @param threadHandle handle to the thread to cancel. + * @return Thread successfully canceled. + *=======================================================================================*/ +pte_osResult pte_osThreadCancel(pte_osThreadHandle handle){ + ERROR("osThreadCancel \n"); + return PTE_OS_GENERAL_FAILURE; + + handle->signal = NK_THREAD_CANCEL; + // if thread is waiting in queue, wake up + /* if(handle->in_queue){ */ + /* nk_wait_queue_wake_all(handle->in_queue); */ + /* } */ + return PTE_OS_OK; +} + +//CANCEL not supported +pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle handle){ + + ERROR("osThreadCheckCancel\n"); + return PTE_OS_OK; + nk_thread_t * thethread = (nk_thread_t*) handle->tid; + + if (thethread->status ==NK_THR_EXITED){ + return PTE_OS_INTERRUPTED; + }else{ + return PTE_OS_OK; + } +} + +/*===================================================*/ +/* indeed yield operation, do not use wait queue */ +/* fast yield */ +/*===================================================*/ +void pte_osThreadSleep(unsigned int msecs){ + nk_yield(); +} + +/*============================================= + * Returns the maximum allowable priority + *============================================*/ +int pte_osThreadGetMaxPriority(){ + return 3; + +} + +/*==========================================* + * Returns the minimum allowable priority + *=========================================*/ +int pte_osThreadGetMinPriority(){ + return 0; +} + +/*==================================================================================* + * Returns the priority that should be used if the caller to pthread_create doesn't + * explicitly set one. + *===================================================================================*/ +int pte_osThreadGetDefaultPriority(){ + return 0; +} + +/*=================================================================================* + * Creates a semaphore + * + * @param initialValue Initial value of the semaphore + * @param pHandle Set to the handle of the newly created semaphore. + * + * @return PTE_OS_OK - Semaphore successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore + *==================================================================================*/ +pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle){ + + //pte_osSemaphoreHandle is nk_semaphore + DEBUG("osSemaphoreCreate\n"); + + *pHandle = malloc(sizeof(struct psemaphore)); + memset(*pHandle,0,sizeof(struct psemaphore)); + + spinlock_init(&((*pHandle)->lock)); + (*pHandle)->count = 0; + + (*pHandle)->wait_queue = nk_wait_queue_create(NULL); + + if (!(*pHandle)->wait_queue) { + free(*pHandle); + ERROR("Failed to allocate wait queue\n"); + return PTE_OS_NO_RESOURCES; + } + + return PTE_OS_OK; +} + +/*==============================================================* + * Deletes a semaphore and frees any associated resources. + * + * @param handle Handle of semaphore to delete. + * + * @return PTE_OS_OK - Semaphore successfully deleted. + *===============================================================*/ +pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle){ + //nk_semaphore_release(handle); + spinlock_deinit(&(handle->lock)); + free(handle); + DEBUG("osSemaphoreDelete\n"); + return PTE_OS_OK; +} + +/*================================================================* + * Posts to the semaphore + * + * @param handle Semaphore to release + * @param count Amount to increment the semaphore by. + * + * @return PTE_OS_OK - semaphore successfully released. + *================================================================*/ +pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count){ + + DEBUG("releaseosSemaphorePost\n"); + + handle->flags = STATE_LOCK(&(handle->lock)); + handle->count += count; + // int old = pte_osAtomicAdd(&(handle->count), count); + int a = count; + if(a > handle->sleepcount){ + a = handle->sleepcount; + } + handle->sleepcount -= a; + while(a--){ + nk_wait_queue_wake_one(handle->wait_queue); + } + + STATE_UNLOCK(&(handle->lock), handle->flags); + return PTE_OS_OK; +} + +/*====================================================================================* + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + *======================================================================================*/ + +pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout){ + + + int busy_wait = 0; + + if(pTimeout == NULL){ + while(1){ + //DEBUG("osSemaphoreBusyWaitPend\n"); + handle->flags = STATE_LOCK(&(handle->lock)); + if(handle->count > 0){ + handle->count--; + //pte_osAtomicDecrement(&(handle->count));; + STATE_UNLOCK(&(handle->lock), handle->flags); + return PTE_OS_OK; + }else{ + STATE_UNLOCK(&(handle->lock), handle->flags); + busy_wait++; + if(busy_wait > ZOMBIE){ + busy_wait=0; + if(ZOMBIE_mode) + break; + } + nk_yield(); + } + } + // We are ZOMBIE NOW! GO to sleep! + while(1){ + ERROR("osSemaphoreSleepPend\n"); + handle->flags = STATE_LOCK(&(handle->lock)); + if(handle->count > 0){ + handle->count--; + //int ori = pte_osAtomicDecrement(&(handle->count)); + STATE_UNLOCK(&(handle->lock), handle->flags); + return PTE_OS_OK; + }else{ + //we need to gracefully put ourselves to sleep + nk_thread_t *t = get_cur_thread(); + + // disable preemption early since interrupts may remain on given our locking model + preempt_disable(); + t->status = NK_THR_WAITING; + nk_wait_queue_enqueue(handle->wait_queue,t); + handle->sleepcount++; + //pte_osAtomicIncrement(&(handle->sleepcount)); + + // and go to sleep - this will also release the lock + // and reenable preemption + nk_sched_sleep(&(handle->lock)); + DEBUG("*********wake up******\n"); + irq_enable_restore(handle->flags); + + } + } + }else{ + + DEBUG("timed pend semaphore\n"); + unsigned int start = (unsigned int) nk_sched_get_realtime(); + unsigned int end = start; + int res = -1; + while( (end-start) < (*pTimeout)*NS ){ + DEBUG("osSemaphorePend %d \n", end-start); + handle->flags = STATE_LOCK(&(handle->lock)); + if(handle->count > 0){ + handle->count--; + //pte_osAtomicDecrement(&(handle->count)); + STATE_UNLOCK(&(handle->lock), handle->flags); + return PTE_OS_OK; + }else{ + STATE_UNLOCK(&(handle->lock), handle->flags); + nk_yield(); + } + end = (unsigned int) nk_sched_get_realtime(); + } + return PTE_OS_TIMEOUT; + } +} + +/*==========================================================================================* + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * Call must return immediately if pte_osThreadCancel() is called on the thread waiting for + * the semaphore. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + ================================================================================================*/ +pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout){ + + //cancel not allowed !!! + return pte_osSemaphorePend(handle, pTimeout); +} + + +/*=============================================================== + * Sets the thread specific value for the specified key for the + * currently executing thread. + * + * @param index The TLS key for the value. + * @param value The value to save + *===============================================================*/ +pte_osResult pte_osTlsSetValue(unsigned int key, void * value){ + DEBUG("pte_osTlsSetvalue\n"); + nk_tls_set(key, value); + return PTE_OS_OK; +} + +/** + * Retrieves the thread specific value for the specified key for + * the currently executing thread. If a value has not been set + * for this key, NULL should be returned (i.e. TLS values default + * to NULL). + * + * @param index The TLS key for the value. + * + * @return The value associated with @p key for the current thread. + */ +void * pte_osTlsGetValue(unsigned int key){ + DEBUG("osTlsGetValue\n"); + return nk_tls_get(key); +} + +/*=====================================================================* + * Initializes the OS TLS support. This is called by the PTE library + * prior to performing ANY TLS operation. + *====================================================================*/ +void pte_osTlsInit(void){ + //skip +} + +/*===============================================================* + * Allocates a new TLS key. + * + * @param pKey On success will be set to the newly allocated key. + * + * @return PTE_OS_OK - TLS key successfully allocated. + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g. + * maximum number of keys reached). + *===================================================================*/ +pte_osResult pte_osTlsAlloc(unsigned int *pKey){ + DEBUG("osTlsAlloc\n"); + nk_tls_key_create(pKey, NULL); + return PTE_OS_OK; +} + +/*===============================================================* + * Frees the specified TLS key. + * @param index TLS key to free + * @return PTE_OS_OK - TLS key was successfully freed. + *================================================================*/ +pte_osResult pte_osTlsFree(unsigned int key){ + DEBUG("osTlsFree\n"); + nk_tls_key_delete(key); + return PTE_OS_OK; +} + +/*=================================================================* + * Sets the target to the specified value as an atomic operation. + * @param pTarg Pointer to the value to be exchanged. + * @param val Value to be exchanged + * @return original value of destination + *=================================================================*/ +int pte_osAtomicExchange(int *pTarg, int val){ + + return __atomic_exchange_n(pTarg,val,__ATOMIC_SEQ_CST); +} + +/*========================================================================================* + * Performs an atomic compare-and-exchange oepration on the specified + * value. + * @param pdest Pointer to the destination value. + * @param exchange Exchange value (value to set destination to if destination == comparand) + * @param comp The value to compare to destination. + * @return Original value of destination + *==========================================================================================*/ +int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp){ + DEBUG("AtomicCompareEXCHANGE"); + return __sync_val_compare_and_swap(pdest,comp,exchange); + // return atomic_cmpswap(pdest, comp, exchange); +} + +/*=================================================================* + * Adds the value to target as an atomic operation + * @param pdest Pointer to the variable to be updated. + * @param value Value to be added to the variable. + * @return Original value of destination + *=================================================================*/ +int pte_osAtomicExchangeAdd(int volatile* pdest, int value){ + + DEBUG("AtomicEXCHANGEAdd\n"); + return __sync_fetch_and_add(pdest, value); +} + +/*=================================================================* + * @param pdest Destination value to decrement + * @return Original destination value + *=================================================================*/ +int pte_osAtomicDecrement(int *pdest){ + + DEBUG("AtomicDecrement\n" ); + return __sync_fetch_and_sub(pdest,1); +} + +int pte_osAtomicIncrement(int *pdest){ + DEBUG("AtomicIncrement\n"); + return __sync_fetch_and_add(pdest,1); + +} + +//Not used +int ftime(struct timeb *tb){ + tb->time = 0; + tb->millitm = 0; + tb->timezone = 0; + tb->dstflag=0; + return 0; +} + + +//Not Used +/* #define SEMAPHORE_LOCK_CONF uint8_t _semaphore_lock_flags */ +/* #define SEMAPHORE_LOCK(s) _semaphore_lock_flags = spin_lock_irq_save(&(s)->lock) */ +/* #define SEMAPHORE_TRY_LOCK(s) spin_try_lock_irq_save(&(s)->lock,&_semaphore_lock_flags) */ +/* #define SEMAPHORE_UNLOCK(s) spin_unlock_irq_restore(&(s)->lock, _semaphore_lock_flags) */ +/* #define SEMAPHORE_UNIRQ(s) irq_enable_restore(_semaphore_lock_flags) */ + +/* pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout){ */ + +/* //cancel not allowed !!! */ +/* return pte_osSemaphorePend(handle, pTimeout); */ + +/* nk_thread_t* thethread= get_cur_thread(); */ +/* pte_osThreadHandle oshandle = pcontainer_of(thethread, struct thread_with_signal, tid); */ +/* DEBUG("osSemaphorecancelablepend\n"); */ +/* int res = -1; */ +/* if(pTimeout == NULL){ */ +/* while(1){ */ +/* if(oshandle->signal == NK_THREAD_CANCEL){ */ +/* DEBUG("pthread cancel exit...\n"); */ +/* nk_thread_exit(NULL); */ +/* return PTE_OS_INTERRUPTED; */ +/* } */ +/* // DEBUG("osSemaphorecancelablepend aquire lock\n"); */ +/* handle->flags = STATE_LOCK(&(handle->lock)); */ +/* int ori = pte_osAtomicDecrement(&(handle->count)); */ +/* if(ori > 0){ */ +/* //handle->count--; */ +/* STATE_UNLOCK(&(handle->lock), handle->flags); */ +/* DEBUG("pending done\n"); */ +/* return PTE_OS_OK; */ +/* }else{ */ + +/* // STATE_UNLOCK(&(handle->lock), handle->flags); */ +/* //nk_yield(); */ +/* nk_thread_t *t = get_cur_thread(); */ +/* // disable preemption early since interrupts may remain on given our locking model */ +/* //preempt_disable(); */ + +/* // onto the semaphore's wait queue we go */ +/* ERROR("=====semaphore sleep\n"); */ +/* preempt_disable(); */ +/* t->status = NK_THR_WAITING; */ +/* nk_wait_queue_enqueue(handle->wait_queue,t); */ +/* //STATE_UNLOCK(&(handle->lock), handle->flags); */ +/* // and go to sleep - this will also release the lock */ +/* // and reenable preemption */ +/* nk_sched_sleep(&(handle->lock)); */ +/* ERROR("*********wake up******\n"); */ +/* irq_enable_restore(handle->flags); */ +/* return PTE_OS_OK; */ +/* } */ +/* } */ +/* }else{ */ +/* DEBUG("release semaphore\n"); */ +/* unsigned int start = TIME(); */ +/* unsigned int end = start; */ +/* while( (end-start) < (*pTimeout)*NS ){ */ +/* if(oshandle->signal == NK_THREAD_CANCEL){ */ +/* return PTE_OS_INTERRUPTED; */ +/* } */ +/* handle->flags = STATE_LOCK(&(handle->lock)); */ +/* if(handle->count > 0){ */ +/* pte_osAtomicDecrement(&(handle->count)); */ +/* STATE_UNLOCK(&(handle->lock), handle->flags); */ +/* return PTE_OS_OK; */ +/* }else{ */ +/* STATE_UNLOCK(&(handle->lock), handle->flags); */ +/* nk_yield(); */ +/* } */ +/* end = TIME(); */ +/* } */ +/* return PTE_OS_TIMEOUT; */ +/* } */ +/* } */ + + +// not included in the base pthread library +// and currently impossible in NK since there +// are no forks + +int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) +{ + DEBUG("no support for pthrad_atfork()\n"); + return -1; +} diff --git a/src/compat/pthread/nk/pte_generic_osal.h b/src/compat/pthread/nk/pte_generic_osal.h new file mode 100644 index 000000000..795d4a054 --- /dev/null +++ b/src/compat/pthread/nk/pte_generic_osal.h @@ -0,0 +1,449 @@ +/* + * pte_cancellable_wait.c + * + * Description: + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _GENERIC_OS_SUPPORT_H_ +#define _GENERIC_OS_SUPPORT_H_ +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** @name Misc */ +//@{ +typedef enum pte_osResult +{ + + /** Operation completed successfully */ + PTE_OS_OK = 0, + + /** Operation failed because there insufficient resources */ + PTE_OS_NO_RESOURCES, + + /** Operation failed due to a general failure */ + PTE_OS_GENERAL_FAILURE, + + /** Operation did not complete because a user specified timeout expired. */ + PTE_OS_TIMEOUT, + + /** The operation was interrupted before it could complete. */ + PTE_OS_INTERRUPTED, + + /** An invalid parameter was specified */ + PTE_OS_INVALID_PARAM + + +} pte_osResult; + +/** + * Provides a hook for the OSAL to implement any OS specific initialization. This is guaranteed to be + * called before any other OSAL function. + */ +pte_osResult pte_osInit(void); +//@} + +/** @name Mutexes */ +//@{ + +/** + * Creates a mutex + * + * @param pHandle Set to the handle of the newly created mutex. + * + * @return PTE_OS_OK - Mutex successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex + */ +pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle); + +/** + * Deletes a mutex and frees any associated resources. + * + * @param handle Handle of mutex to delete. + * + * @return PTE_OS_OK - Mutex successfully deleted. + */ +pte_osResult pte_osMutexDelete(pte_osMutexHandle handle); + +/** + * Locks the mutex + * + * @param handle Handle of mutex to lock. + * + * @return PTE_OS_OK - Mutex successfully locked. + */ +pte_osResult pte_osMutexLock(pte_osMutexHandle handle); + +/** + * Locks the mutex, returning after @p timeoutMsecs if the resources is not + * available. Can be used for polling mutex by using @p timeoutMsecs of zero. + * + * @param handle Handle of mutex to lock. + * @param timeoutMsecs Number of milliseconds to wait for resource before returning. + * + * @return PTE_OS_OK - Mutex successfully locked. + * @return PTE_OS_TIMEOUT - Timeout expired before lock was obtained. + */ +pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs); + +/** + * Unlocks the mutex + * + * @param handle Handle of mutex to unlock + * + * @return PTE_OS_OK - Mutex successfully unlocked. + */ +pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle); +//@} + +/** @name Threads */ +//@{ + +/* typedef int (*pte_osThreadEntryPoint)(void *params); */ + + +/** + * Creates a new thread. The thread must be started in a suspended state - it will be + * explicitly started when pte_osThreadStart() is called. + * + * @param entryPoint Entry point to the new thread. + * @param stackSize The initial stack size, in bytes. Note that this can be considered a minimum - + * for instance if the OS requires a larger stack space than what the caller specified. + * @param initialPriority The priority that the new thread should be initially set to. + * @param argv Parameter to pass to the new thread. + * @param ppte_osThreadHandle set to the handle of the new thread. + * + * @return PTE_OS_OK - New thread successfully created. + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create thread + */ +pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, + int stackSize, + int initialPriority, + void *argv, + pte_osThreadHandle* ppte_osThreadHandle); + +/** + * Starts executing the specified thread. + * + * @param osThreadHandle handle of the thread to start. + * + * @return PTE_OS_OK - thread successfully started. + */ +pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle); + +/** + * Causes the current thread to stop executing. + * + * @return Never returns (thread terminated) + */ +void pte_osThreadExit(); + +/** + * Waits for the specified thread to end. If the thread has already terminated, this returns + * immediately. + * + * @param threadHandle Handle fo thread to wait for. + * + * @return PTE_OS_OK - specified thread terminated. + */ +pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle); + +/** + * Returns the handle of the currently executing thread. + */ +pte_osThreadHandle pte_osThreadGetHandle(void); + +/** + * Returns the priority of the specified thread. + */ +int pte_osThreadGetPriority(pte_osThreadHandle threadHandle); + +/** + * Sets the priority of the specified thread. + * + * @return PTE_OS_OK - thread priority successfully set + */ +pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority); + +/** + * Frees resources associated with the specified thread. This is called after the thread has terminated + * and is no longer needed (e.g. after pthread_join returns). This call will always be made + * from a different context than that of the target thread. + */ +pte_osResult pte_osThreadDelete(pte_osThreadHandle handle); + +/** + * Frees resources associated with the specified thread and then causes the thread to exit. + * This is called after the thread has terminated and is no longer needed (e.g. after + * pthread_join returns). This call will always be made from the context of the target thread. + */ +pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle); + +/** + * Cancels the specified thread. This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel() + * to return @p PTE_OS_INTERRUPTED. + * + * @param threadHandle handle to the thread to cancel. + * + * @return Thread successfully canceled. + */ +pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle); + +/** + * Check if pte_osThreadCancel() has been called on the specified thread. + * + * @param threadHandle handle of thread to check the state of. + * + * @return PTE_OS_OK - Thread has not been cancelled + * @return PTE_OS_INTERRUPTED - Thread has been cancelled. + */ +pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle); + +/** + * Causes the current thread to sleep for the specified number of milliseconds. + */ +void pte_osThreadSleep(unsigned int msecs); + +/** + * Returns the maximum allowable priority + */ +int pte_osThreadGetMaxPriority(); + +/** + * Returns the minimum allowable priority + */ +int pte_osThreadGetMinPriority(); + +/** + * Returns the priority that should be used if the caller to pthread_create doesn't + * explicitly set one. + */ +int pte_osThreadGetDefaultPriority(); + +//@} + + +/** @name Semaphores */ +//@{ + +/** + * Creates a semaphore + * + * @param initialValue Initial value of the semaphore + * @param pHandle Set to the handle of the newly created semaphore. + * + * @return PTE_OS_OK - Semaphore successfully created + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore + */ +pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle); + +/** + * Deletes a semaphore and frees any associated resources. + * + * @param handle Handle of semaphore to delete. + * + * @return PTE_OS_OK - Semaphore successfully deleted. + */ +pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle); + +/** + * Posts to the semaphore + * + * @param handle Semaphore to release + * @param count Amount to increment the semaphore by. + * + * @return PTE_OS_OK - semaphore successfully released. + */ +pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count); + +/** + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + */ +pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); + +/** + * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not + * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. + * Call must return immediately if pte_osThreadCancel() is called on the thread waiting for + * the semaphore. + * + * @param handle Handle of semaphore to acquire. + * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore + * before returning. If set to NULL, wait forever. + * + * @return PTE_OS_OK - Semaphore successfully acquired. + * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. + */ +pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); +//@} + + +/** @name Thread Local Storage */ +//@{ +/** + * Sets the thread specific value for the specified key for the + * currently executing thread. + * + * @param index The TLS key for the value. + * @param value The value to save + */ +pte_osResult pte_osTlsSetValue(unsigned int key, void * value); + +/** + * Retrieves the thread specific value for the specified key for + * the currently executing thread. If a value has not been set + * for this key, NULL should be returned (i.e. TLS values default + * to NULL). + * + * @param index The TLS key for the value. + * + * @return The value associated with @p key for the current thread. + */ +void * pte_osTlsGetValue(unsigned int key); + +/** + * Initializes the OS TLS support. This is called by the PTE library + * prior to performing ANY TLS operation. + */ +void pte_osTlsInit(void); + +/** + * Allocates a new TLS key. + * + * @param pKey On success will be set to the newly allocated key. + * + * @return PTE_OS_OK - TLS key successfully allocated. + * @return PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g. + * maximum number of keys reached). + */ +pte_osResult pte_osTlsAlloc(unsigned int *pKey); + +/** + * Frees the specified TLS key. + * + * @param index TLS key to free + * + * @return PTE_OS_OK - TLS key was successfully freed. + */ +pte_osResult pte_osTlsFree(unsigned int key); +//@} + +/** @name Atomic operations */ +//@{ + +/** + * Sets the target to the specified value as an atomic operation. + * + * \code + * origVal = *ptarg + * *ptarg = val + * return origVal + * \endcode + * + * @param pTarg Pointer to the value to be exchanged. + * @param val Value to be exchanged + * + * @return original value of destination + */ +int pte_osAtomicExchange(int *pTarg, int val); + +/** + * Performs an atomic compare-and-exchange oepration on the specified + * value. That is: + * + * \code + * origVal = *pdest + * if (*pdest == comp) + * then *pdest = exchange + * return origVal + * \endcode + * + * @param pdest Pointer to the destination value. + * @param exchange Exchange value (value to set destination to if destination == comparand) + * @param comp The value to compare to destination. + * + * @return Original value of destination + */ +int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp); + +/** + * Adds the value to target as an atomic operation + * + * \code + * origVal = *pdest + * *pAddend += value + * return origVal + * \endcode + * + * @param pdest Pointer to the variable to be updated. + * @param value Value to be added to the variable. + * + * @return Original value of destination + */ +int pte_osAtomicExchangeAdd(int volatile* pdest, int value); + +/** + * Decrements the destination. + * + * \code + * origVal = *pdest + * *pdest++ + * return origVal + * \endcode + * + * @param pdest Destination value to decrement + * + * @return Original destination value + */ +int pte_osAtomicDecrement(int *pdest); + +/** + * Increments the destination value + * + * \code + * origVal = *pdest; + * *pdest++; + * return origVal; + */ +int pte_osAtomicIncrement(int *pdest); +//@} + +struct timeb; + +int ftime(struct timeb *tb); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _OS_SUPPORT_H_ diff --git a/src/compat/pthread/nk/pte_osal.h b/src/compat/pthread/nk/pte_osal.h new file mode 100644 index 000000000..fe70b245a --- /dev/null +++ b/src/compat/pthread/nk/pte_osal.h @@ -0,0 +1,70 @@ +#ifndef _PTE_OSAL_H_ +#define _PTE_OSAL_H_ +#include "pte_types.h" +#include "pte_generic_osal.h" +#include + +#define calloc(a,b) malloc(a*b) + +#ifndef EPERM +#define EPERM 1 +#endif // EPERM + +#ifndef ESRCH +#define ESRCH 3 +#endif // ESRCH + +#ifndef EINTR +#define EINTR 4 +#endif // EINTR + +#ifndef EIO +#define EIO 5 +#endif // EIO + +#ifndef EAGAIN +#define EAGAIN 11 +#endif // EAGAIN + +#ifndef ENOMEM +#define ENOMEM 12 +#endif // ENOMEM + +#ifndef EBUSY +#define EBUSY 16 +#endif // EBUSY + +#ifndef EINVAL +#define EINVAL 22 +#endif // EINVAL + +#ifndef ENOSPC +#define ENOSPC 28 +#endif // ENOSPC + +#ifndef EDEADLK +#define EDEADLK 35 +#endif /* EDEADLK */ + +#ifndef ENOSYS +#define ENOSYS 38 +#endif /* ENOSYS */ + +#ifndef ENOTSUP +#define ENOTSUP 95 +#endif /* ENOTSUP */ + +#ifndef ETIMEDOUT +#define ETIMEDOUT 116 +#endif // ETIMEDOUT + +#ifndef ENOENT +#define ENOENT 7 +#endif + +#ifndef ERANGE +#define ERANGE 9 +#endif + + +#endif diff --git a/src/compat/pthread/nk/pte_types.h b/src/compat/pthread/nk/pte_types.h new file mode 100644 index 000000000..50c9d1830 --- /dev/null +++ b/src/compat/pthread/nk/pte_types.h @@ -0,0 +1,52 @@ +/* pte_types.h */ +#ifndef PTE_TYPES_H +#define PTE_TYPES_H +#include +#include +#include +#include +#include +#include + +struct pmutex{ + spinlock_t lock; + uint8_t flags; +}; + +struct psemaphore{ + int sleepcount; + spinlock_t lock; + int count; + nk_wait_queue_t *wait_queue; + uint8_t flags; +}; +struct thread_with_signal{ + nk_thread_id_t tid; + uint8_t signal; + // nk_wait_queue_t *in_queue; +}; + +typedef struct pmutex* pte_osMutexHandle; +typedef nk_thread_fun_t pte_osThreadEntryPoint; +typedef struct thread_with_signal* pte_osThreadHandle; +typedef struct psemaphore* pte_osSemaphoreHandle; + +typedef enum _pthread_signal{ + NK_THREAD_NORM, + NK_THREAD_CANCEL +}pthread_signal; + + +typedef nk_thread_fun_t pte_osThreadEntryPoint; +typedef int pid_t; +typedef unsigned int mode_t; + +struct timeb +{ + time_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; + +#endif /* PTE_TYPES_H */ diff --git a/src/compat/pthread/pte_callUserDestroyRoutines.c b/src/compat/pthread/pte_callUserDestroyRoutines.c index 07076f23b..81f2c8327 100644 --- a/src/compat/pthread/pte_callUserDestroyRoutines.c +++ b/src/compat/pthread/pte_callUserDestroyRoutines.c @@ -1,3 +1,4 @@ + /* * pte_callUserDestroyRoutines.c * @@ -41,13 +42,14 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" -#include +#include "nk/pte_osal.h" #ifdef __cplusplus #include diff --git a/src/compat/pthread/pte_cancellable_wait.c b/src/compat/pthread/pte_cancellable_wait.c index 2579fcbe8..d96b8ff6d 100644 --- a/src/compat/pthread/pte_cancellable_wait.c +++ b/src/compat/pthread/pte_cancellable_wait.c @@ -1,3 +1,4 @@ + /* * pte_cancellable_wait.c * @@ -39,9 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" diff --git a/src/compat/pthread/pte_generic_osal.h b/src/compat/pthread/pte_generic_osal.h index 3ce7f4964..7af234c6a 100644 --- a/src/compat/pthread/pte_generic_osal.h +++ b/src/compat/pthread/pte_generic_osal.h @@ -28,7 +28,6 @@ #ifndef _GENERIC_OS_SUPPORT_H_ #define _GENERIC_OS_SUPPORT_H_ - #ifdef __cplusplus extern "C" { #endif // __cplusplus diff --git a/src/compat/pthread/pte_new.c b/src/compat/pthread/pte_new.c index d3614aa63..edf70d371 100644 --- a/src/compat/pthread/pte_new.c +++ b/src/compat/pthread/pte_new.c @@ -1,3 +1,4 @@ + /* * pte_new.c * @@ -40,9 +41,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -68,7 +69,7 @@ pte_new (void) { /* No reuse threads available */ tp = (pte_thread_t *) calloc (1, sizeof(pte_thread_t)); - + memset(tp, 0, sizeof(pte_thread_t)*1); if (tp == NULL) { return nil; diff --git a/src/compat/pthread/pte_relmillisecs.c b/src/compat/pthread/pte_relmillisecs.c index dc78fd0eb..75ca8e32c 100644 --- a/src/compat/pthread/pte_relmillisecs.c +++ b/src/compat/pthread/pte_relmillisecs.c @@ -40,7 +40,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pte_reuse.c b/src/compat/pthread/pte_reuse.c index 87e3e540a..d633f47f5 100644 --- a/src/compat/pthread/pte_reuse.c +++ b/src/compat/pthread/pte_reuse.c @@ -1,3 +1,4 @@ + /* * pte_threadReuse.c * @@ -40,10 +41,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pte_threadDestroy.c b/src/compat/pthread/pte_threadDestroy.c index a60a794b3..83e08e690 100644 --- a/src/compat/pthread/pte_threadDestroy.c +++ b/src/compat/pthread/pte_threadDestroy.c @@ -41,10 +41,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pte_threadStart.c b/src/compat/pthread/pte_threadStart.c index a58d22661..e8e206e89 100644 --- a/src/compat/pthread/pte_threadStart.c +++ b/src/compat/pthread/pte_threadStart.c @@ -1,3 +1,4 @@ + /* * pte_threadStart.c * @@ -41,9 +42,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -75,7 +76,7 @@ pte_terminate () #endif -int pte_threadStart (void *vthreadParms) +int pte_threadStart (void *vthreadParms, void ** out) { ThreadParms * threadParms = (ThreadParms *) vthreadParms; pthread_t self; @@ -84,8 +85,7 @@ int pte_threadStart (void *vthreadParms) void * arg; #ifdef PTE_CLEANUP_C -#include - +#include int setjmp_rc; #endif diff --git a/src/compat/pthread/pte_throw.c b/src/compat/pthread/pte_throw.c index 81f616f73..7f1ee7e31 100644 --- a/src/compat/pthread/pte_throw.c +++ b/src/compat/pthread/pte_throw.c @@ -1,3 +1,4 @@ + /* * pte_throw.c * @@ -40,8 +41,8 @@ * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pte_tkAssocCreate.c b/src/compat/pthread/pte_tkAssocCreate.c index 83aec9680..7effe3e3c 100644 --- a/src/compat/pthread/pte_tkAssocCreate.c +++ b/src/compat/pthread/pte_tkAssocCreate.c @@ -1,3 +1,4 @@ + /* * pte_tkAssocCreate.c * @@ -41,8 +42,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -90,7 +91,7 @@ pte_tkAssocCreate (pte_thread_t * sp, pthread_key_t key) * entry to this routine. */ assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc)); - + memset(assoc, 0, 1*sizeof(*assoc)); if (assoc == NULL) { return ENOMEM; diff --git a/src/compat/pthread/pte_tkAssocDestroy.c b/src/compat/pthread/pte_tkAssocDestroy.c index c874c2ee5..af9381576 100644 --- a/src/compat/pthread/pte_tkAssocDestroy.c +++ b/src/compat/pthread/pte_tkAssocDestroy.c @@ -1,3 +1,4 @@ + /* * pte_tkAssocDestroy.c * @@ -41,8 +42,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread.h b/src/compat/pthread/pthread.h index a66a371da..07f3bcfd3 100644 --- a/src/compat/pthread/pthread.h +++ b/src/compat/pthread/pthread.h @@ -44,9 +44,9 @@ #if !defined( PTHREAD_H ) #define PTHREAD_H -#include +#include "nk/pte_types.h" -#include +#include "sched.h" #define PTE_VERSION 2,8,0,0 #define PTE_VERSION_STRING "2, 8, 0, 0\0" @@ -176,9 +176,9 @@ * ------------------------------------------------------------- */ -#include +//#include -#include +#include #include /* @@ -367,7 +367,7 @@ enum #define PTHREAD_STACK_MIN 0 #undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 +#define _POSIX_THREAD_THREADS_MAX 256 /* Arbitrary value */ #undef PTHREAD_THREADS_MAX @@ -396,6 +396,8 @@ enum { void * p; /* Pointer to actual object */ unsigned int x; /* Extra information - reuse count etc */ + //mjc add attr into pthread_t + //struct pthread_attr_t_* attr; } pte_handle_t; typedef pte_handle_t pthread_t; @@ -654,10 +656,6 @@ enum #endif /* PTE_CLEANUP_C */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - /* * =============== * =============== @@ -684,7 +682,9 @@ extern "C" { int pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize); - + int pthread_attr_getstack (const pthread_attr_t * attr, + void **stackaddr, + size_t *stacksize); int pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate); @@ -738,6 +738,9 @@ extern "C" { pthread_t pthread_self (void); + //mjc + int pthread_getattr_np(pthread_t thread, pthread_attr_t * attr); + int pthread_cancel (pthread_t thread); int pthread_setcancelstate (int state, @@ -964,10 +967,6 @@ extern "C" { #endif /*PTE_LEVEL >= PTE_LEVEL_MAX - 1 */ -#ifdef __cplusplus -} -#endif /* cplusplus */ - #if PTE_LEVEL >= PTE_LEVEL_MAX @@ -1007,4 +1006,5 @@ extern "C" { #undef PTE_LEVEL #undef PTE_LEVEL_MAX + #endif /* PTHREAD_H */ diff --git a/src/compat/pthread/pthread_attr_destroy.c b/src/compat/pthread/pthread_attr_destroy.c index 221218c94..0dc1e4289 100644 --- a/src/compat/pthread/pthread_attr_destroy.c +++ b/src/compat/pthread/pthread_attr_destroy.c @@ -1,3 +1,4 @@ + /* * pthread_attr_destroy.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_attr_getschedparam.c b/src/compat/pthread/pthread_attr_getschedparam.c index 782403d59..4a7fcac9e 100644 --- a/src/compat/pthread/pthread_attr_getschedparam.c +++ b/src/compat/pthread/pthread_attr_getschedparam.c @@ -1,3 +1,4 @@ + /* * pthread_attr_getschedparam.c * @@ -40,9 +41,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" #include "sched.h" diff --git a/src/compat/pthread/pthread_attr_init.c b/src/compat/pthread/pthread_attr_init.c index bf20d3c17..0474c5ce2 100644 --- a/src/compat/pthread/pthread_attr_init.c +++ b/src/compat/pthread/pthread_attr_init.c @@ -1,3 +1,4 @@ + /* * pthread_attr_init.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_attr_setschedparam.c b/src/compat/pthread/pthread_attr_setschedparam.c index ef33a2b32..053472536 100644 --- a/src/compat/pthread/pthread_attr_setschedparam.c +++ b/src/compat/pthread/pthread_attr_setschedparam.c @@ -1,3 +1,4 @@ + /* * pthread_attr_setschedparam.c * @@ -40,9 +41,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" #include "sched.h" diff --git a/src/compat/pthread/pthread_barrier_destroy.c b/src/compat/pthread/pthread_barrier_destroy.c index 305f36398..d3de0a6be 100644 --- a/src/compat/pthread/pthread_barrier_destroy.c +++ b/src/compat/pthread/pthread_barrier_destroy.c @@ -1,3 +1,4 @@ + /* * pthread_barrier_destroy.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -64,7 +65,8 @@ pthread_barrier_destroy (pthread_barrier_t * barrier) { if (0 == (result = sem_destroy (&(b->semBarrierBreeched[1])))) { - (void) free (b); + free(b); + //(void) free (b); return 0; } (void) sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0); diff --git a/src/compat/pthread/pthread_barrier_init.c b/src/compat/pthread/pthread_barrier_init.c index 6659fec8f..6ee740eaa 100644 --- a/src/compat/pthread/pthread_barrier_init.c +++ b/src/compat/pthread/pthread_barrier_init.c @@ -1,3 +1,4 @@ + /* * pthread_barrier_init.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -59,6 +60,7 @@ pthread_barrier_init (pthread_barrier_t * barrier, if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b)))) { + memset(b,0, 1*sizeof(*b)); b->pshared = (attr != NULL && *attr != NULL ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE); @@ -82,7 +84,9 @@ pthread_barrier_init (pthread_barrier_t * barrier, } (void) sem_destroy (&(b->semBarrierBreeched[0])); } - (void) free (b); + //mjc + // (void) free (b); + free(b); } return ENOMEM; diff --git a/src/compat/pthread/pthread_barrierattr_destroy.c b/src/compat/pthread/pthread_barrierattr_destroy.c index bc3b5711b..650d939f4 100644 --- a/src/compat/pthread/pthread_barrierattr_destroy.c +++ b/src/compat/pthread/pthread_barrierattr_destroy.c @@ -1,3 +1,4 @@ + /* * pthread_barrier_attr_destroy.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_barrierattr_init.c b/src/compat/pthread/pthread_barrierattr_init.c index bd653f180..77814247f 100644 --- a/src/compat/pthread/pthread_barrierattr_init.c +++ b/src/compat/pthread/pthread_barrierattr_init.c @@ -1,3 +1,4 @@ + /* * pthread_barrier_attr_init.c * @@ -40,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -77,7 +78,7 @@ pthread_barrierattr_init (pthread_barrierattr_t * attr) int result = 0; ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba)); - + memset(ba, 0, 1*sizeof(*ba)); if (ba == NULL) { result = ENOMEM; diff --git a/src/compat/pthread/pthread_cancel.c b/src/compat/pthread/pthread_cancel.c index dce60b282..a7df3acca 100644 --- a/src/compat/pthread/pthread_cancel.c +++ b/src/compat/pthread/pthread_cancel.c @@ -1,3 +1,4 @@ + /* * pthread_cancel.c * @@ -42,8 +43,8 @@ #include "pthread.h" #include "implement.h" -#include - +/* #include */ +#include int pthread_cancel (pthread_t thread) /* diff --git a/src/compat/pthread/pthread_cond_destroy.c b/src/compat/pthread/pthread_cond_destroy.c index c17a02f04..dbf04653c 100644 --- a/src/compat/pthread/pthread_cond_destroy.c +++ b/src/compat/pthread/pthread_cond_destroy.c @@ -41,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -212,8 +212,8 @@ pthread_cond_destroy (pthread_cond_t * cond) { cv->next->prev = cv->prev; } - - (void) free (cv); + free(cv); + //(void) free (cv); } pte_osMutexUnlock(pte_cond_list_lock); diff --git a/src/compat/pthread/pthread_cond_init.c b/src/compat/pthread/pthread_cond_init.c index 607a0d255..2fb4d92aa 100644 --- a/src/compat/pthread/pthread_cond_init.c +++ b/src/compat/pthread/pthread_cond_init.c @@ -41,8 +41,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -96,7 +96,7 @@ pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) } cv = (pthread_cond_t) calloc (1, sizeof (*cv)); - + memset(cv,0,1*sizeof(*cv)); if (cv == NULL) { result = ENOMEM; @@ -140,7 +140,8 @@ pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) (void) sem_destroy (&(cv->semBlockLock)); FAIL0: - (void) free (cv); + free(cv); + //(void) free (cv); cv = NULL; DONE: diff --git a/src/compat/pthread/pthread_condattr_destroy.c b/src/compat/pthread/pthread_condattr_destroy.c index b56f76c29..cef9c8320 100644 --- a/src/compat/pthread/pthread_condattr_destroy.c +++ b/src/compat/pthread/pthread_condattr_destroy.c @@ -1,3 +1,4 @@ + /* * condvar_attr_destroy.c * @@ -41,8 +42,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -83,7 +84,8 @@ pthread_condattr_destroy (pthread_condattr_t * attr) } else { - (void) free (*attr); + free(*attr); + //(void) free (*attr); *attr = NULL; result = 0; diff --git a/src/compat/pthread/pthread_condattr_init.c b/src/compat/pthread/pthread_condattr_init.c index 393cf0499..85d82fa33 100644 --- a/src/compat/pthread/pthread_condattr_init.c +++ b/src/compat/pthread/pthread_condattr_init.c @@ -1,3 +1,4 @@ + /* * pthread_condattr_init.c * @@ -41,8 +42,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -82,7 +83,7 @@ pthread_condattr_init (pthread_condattr_t * attr) int result = 0; attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result)); - + memset(attr_result, 0, 1*sizeof(*attr_result)); if (attr_result == NULL) { result = ENOMEM; diff --git a/src/compat/pthread/pthread_delay_np.c b/src/compat/pthread/pthread_delay_np.c index c954e610c..bb21e2640 100644 --- a/src/compat/pthread/pthread_delay_np.c +++ b/src/compat/pthread/pthread_delay_np.c @@ -40,8 +40,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_detach.c b/src/compat/pthread/pthread_detach.c index 21e4da28d..f85899569 100644 --- a/src/compat/pthread/pthread_detach.c +++ b/src/compat/pthread/pthread_detach.c @@ -41,7 +41,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" @@ -131,7 +131,7 @@ pthread_detach (pthread_t thread) /* The thread has exited or is exiting but has not been joined or * detached. Need to wait in case it's still exiting. */ - pte_osThreadWaitForEnd(tp->threadId); + pte_osThreadWaitForEnd(tp->threadId); pte_threadDestroy (thread); } diff --git a/src/compat/pthread/pthread_init.c b/src/compat/pthread/pthread_init.c index 316edfe11..7470e803a 100644 --- a/src/compat/pthread/pthread_init.c +++ b/src/compat/pthread/pthread_init.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_join.c b/src/compat/pthread/pthread_join.c index 2e0545edc..073512aa9 100644 --- a/src/compat/pthread/pthread_join.c +++ b/src/compat/pthread/pthread_join.c @@ -41,12 +41,12 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +#include "nk/pte_osal.h" +#include #include "pthread.h" #include "implement.h" -#include +//#include int pthread_join (pthread_t thread, void **value_ptr) @@ -145,7 +145,9 @@ pthread_join (pthread_t thread, void **value_ptr) * pthread_join() or pthread_detach() specifying the same * target is undefined. */ - result = pthread_detach (thread); + + //mjc detached already + //result = pthread_detach (thread); } else if (result == PTE_OS_INTERRUPTED) { diff --git a/src/compat/pthread/pthread_key_create.c b/src/compat/pthread/pthread_key_create.c index 850433c13..d693272f7 100644 --- a/src/compat/pthread/pthread_key_create.c +++ b/src/compat/pthread/pthread_key_create.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - -#include "pte_osal.h" +/* #include */ +#include +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" @@ -89,6 +89,7 @@ pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) } else { + memset(newkey,0,1*sizeof(*newkey)); pte_osResult osResult = pte_osTlsAlloc(&(newkey->key)); if (osResult != PTE_OS_OK) diff --git a/src/compat/pthread/pthread_key_delete.c b/src/compat/pthread/pthread_key_delete.c index 37cfcbfb9..9d28de1fb 100644 --- a/src/compat/pthread/pthread_key_delete.c +++ b/src/compat/pthread/pthread_key_delete.c @@ -40,10 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_kill.c b/src/compat/pthread/pthread_kill.c index d3fd70b03..b5f58e035 100644 --- a/src/compat/pthread/pthread_kill.c +++ b/src/compat/pthread/pthread_kill.c @@ -40,10 +40,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_mutex_destroy.c b/src/compat/pthread/pthread_mutex_destroy.c index 64a4cde2c..94ac2cfe2 100644 --- a/src/compat/pthread/pthread_mutex_destroy.c +++ b/src/compat/pthread/pthread_mutex_destroy.c @@ -40,10 +40,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_mutex_init.c b/src/compat/pthread/pthread_mutex_init.c index 62f275bc0..581045ce6 100644 --- a/src/compat/pthread/pthread_mutex_init.c +++ b/src/compat/pthread/pthread_mutex_init.c @@ -40,12 +40,12 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" - +#include "debug.h" int pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) @@ -60,7 +60,7 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) } mx = (pthread_mutex_t) calloc (1, sizeof (*mx)); - + memset(mx, 0, 1*sizeof(*mx)); if (mx == NULL) { result = ENOMEM; @@ -69,8 +69,14 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) { mx->lock_idx = 0; mx->recursive_count = 0; - mx->kind = (attr == NULL || *attr == NULL + DEBUG("attr addr %08x\n", attr); + DEBUG("attr kind %08x\n", *attr); + + mx->kind = PTHREAD_MUTEX_DEFAULT; + //mjc + //mx->kind = (attr == NULL || *attr == NULL \ ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); + DEBUG("pass mxkind\n"); mx->ownerThread.p = NULL; pte_osSemaphoreCreate(0,&mx->handle); diff --git a/src/compat/pthread/pthread_mutex_lock.c b/src/compat/pthread/pthread_mutex_lock.c index 90f5474bc..2220f2846 100644 --- a/src/compat/pthread/pthread_mutex_lock.c +++ b/src/compat/pthread/pthread_mutex_lock.c @@ -40,12 +40,12 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" - +#include "debug.h" int pthread_mutex_lock (pthread_mutex_t * mutex) @@ -74,8 +74,10 @@ pthread_mutex_lock (pthread_mutex_t * mutex) return (result); } } - + + //orig mx = *mutex; + //mjc if (mx->kind == PTHREAD_MUTEX_NORMAL) { @@ -135,6 +137,7 @@ pthread_mutex_lock (pthread_mutex_t * mutex) } } + DEBUG("mx :%d, mutex:%d \n", mx->lock_idx, (*mutex)->lock_idx); return (result); } diff --git a/src/compat/pthread/pthread_mutex_timedlock.c b/src/compat/pthread/pthread_mutex_timedlock.c index 7fd42857c..4af36e948 100644 --- a/src/compat/pthread/pthread_mutex_timedlock.c +++ b/src/compat/pthread/pthread_mutex_timedlock.c @@ -40,11 +40,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - -#include -#include +#include "nk/pte_osal.h" +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_mutex_unlock.c b/src/compat/pthread/pthread_mutex_unlock.c index 17bce62a4..b16df22bc 100644 --- a/src/compat/pthread/pthread_mutex_unlock.c +++ b/src/compat/pthread/pthread_mutex_unlock.c @@ -40,11 +40,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - -#include -#include +#include "nk/pte_osal.h" +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -60,8 +60,11 @@ pthread_mutex_unlock (pthread_mutex_t * mutex) /* * Let the system deal with invalid pointers. */ - + //orig mx = *mutex; + //mjc + //pthread_mutex_t *mx; + //mx = mutex; /* * If the thread calling us holds the mutex then there is no diff --git a/src/compat/pthread/pthread_mutexattr_destroy.c b/src/compat/pthread/pthread_mutexattr_destroy.c index 9cef18cad..8802f760d 100644 --- a/src/compat/pthread/pthread_mutexattr_destroy.c +++ b/src/compat/pthread/pthread_mutexattr_destroy.c @@ -40,8 +40,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_mutexattr_init.c b/src/compat/pthread/pthread_mutexattr_init.c index d2b58127e..84e3c785f 100644 --- a/src/compat/pthread/pthread_mutexattr_init.c +++ b/src/compat/pthread/pthread_mutexattr_init.c @@ -40,8 +40,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -77,7 +77,7 @@ pthread_mutexattr_init (pthread_mutexattr_t * attr) pthread_mutexattr_t ma; ma = (pthread_mutexattr_t) calloc (1, sizeof (*ma)); - + memset(ma,0,1*sizeof(*ma)); if (ma == NULL) { result = ENOMEM; diff --git a/src/compat/pthread/pthread_once.c b/src/compat/pthread/pthread_once.c index a8166f51c..5faba0f83 100644 --- a/src/compat/pthread/pthread_once.c +++ b/src/compat/pthread/pthread_once.c @@ -40,7 +40,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include "pte_osal.h" +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" @@ -168,7 +168,7 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) { /* we were last */ if ((sema = - (pte_osSemaphoreHandle) PTE_ATOMIC_EXCHANGE((int *) &once_control->semaphore,0))) + (pte_osSemaphoreHandle)PTE_ATOMIC_EXCHANGE((int *) &once_control->semaphore,0))) { pte_osSemaphoreDelete(sema); } diff --git a/src/compat/pthread/pthread_rwlock_destroy.c b/src/compat/pthread/pthread_rwlock_destroy.c index 0f4904790..96c5b6f14 100644 --- a/src/compat/pthread/pthread_rwlock_destroy.c +++ b/src/compat/pthread/pthread_rwlock_destroy.c @@ -40,10 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -111,7 +111,7 @@ pthread_rwlock_destroy (pthread_rwlock_t * rwlock) result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted)); result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); - (void) free (rwl); + free (rwl); } } else diff --git a/src/compat/pthread/pthread_rwlock_init.c b/src/compat/pthread/pthread_rwlock_init.c index 847bfab31..6bc0468ad 100644 --- a/src/compat/pthread/pthread_rwlock_init.c +++ b/src/compat/pthread/pthread_rwlock_init.c @@ -40,10 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -66,7 +66,7 @@ pthread_rwlock_init (pthread_rwlock_t * rwlock, } rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl)); - + memset(rwl, 0, 1*sizeof(*rwl)); if (rwl == NULL) { result = ENOMEM; @@ -107,7 +107,8 @@ pthread_rwlock_init (pthread_rwlock_t * rwlock, (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); FAIL0: - (void) free (rwl); + free(rwl) + // (void) free (rwl); rwl = NULL; DONE: diff --git a/src/compat/pthread/pthread_rwlock_rdlock.c b/src/compat/pthread/pthread_rwlock_rdlock.c index ad6dd9915..5f493ad5d 100644 --- a/src/compat/pthread/pthread_rwlock_rdlock.c +++ b/src/compat/pthread/pthread_rwlock_rdlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_timedrdlock.c b/src/compat/pthread/pthread_rwlock_timedrdlock.c index 111205b52..877554ecf 100644 --- a/src/compat/pthread/pthread_rwlock_timedrdlock.c +++ b/src/compat/pthread/pthread_rwlock_timedrdlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_timedwrlock.c b/src/compat/pthread/pthread_rwlock_timedwrlock.c index 3611e1b29..e00acdc57 100644 --- a/src/compat/pthread/pthread_rwlock_timedwrlock.c +++ b/src/compat/pthread/pthread_rwlock_timedwrlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_tryrdlock.c b/src/compat/pthread/pthread_rwlock_tryrdlock.c index 65b683b20..fc67a37e5 100644 --- a/src/compat/pthread/pthread_rwlock_tryrdlock.c +++ b/src/compat/pthread/pthread_rwlock_tryrdlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_trywrlock.c b/src/compat/pthread/pthread_rwlock_trywrlock.c index 19172bb52..a5907cbdb 100644 --- a/src/compat/pthread/pthread_rwlock_trywrlock.c +++ b/src/compat/pthread/pthread_rwlock_trywrlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_unlock.c b/src/compat/pthread/pthread_rwlock_unlock.c index 931c8233b..78f2c6c21 100644 --- a/src/compat/pthread/pthread_rwlock_unlock.c +++ b/src/compat/pthread/pthread_rwlock_unlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlock_wrlock.c b/src/compat/pthread/pthread_rwlock_wrlock.c index 33ff5c227..4dd56d683 100644 --- a/src/compat/pthread/pthread_rwlock_wrlock.c +++ b/src/compat/pthread/pthread_rwlock_wrlock.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlockattr_destroy.c b/src/compat/pthread/pthread_rwlockattr_destroy.c index 4587329bc..5372609cb 100644 --- a/src/compat/pthread/pthread_rwlockattr_destroy.c +++ b/src/compat/pthread/pthread_rwlockattr_destroy.c @@ -40,10 +40,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlockattr_getpshared.c b/src/compat/pthread/pthread_rwlockattr_getpshared.c index c3e75aed3..cca5e6508 100644 --- a/src/compat/pthread/pthread_rwlockattr_getpshared.c +++ b/src/compat/pthread/pthread_rwlockattr_getpshared.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_rwlockattr_init.c b/src/compat/pthread/pthread_rwlockattr_init.c index d1dbaf112..81ca75535 100644 --- a/src/compat/pthread/pthread_rwlockattr_init.c +++ b/src/compat/pthread/pthread_rwlockattr_init.c @@ -40,10 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -75,7 +75,7 @@ pthread_rwlockattr_init (pthread_rwlockattr_t * attr) pthread_rwlockattr_t rwa; rwa = (pthread_rwlockattr_t) calloc (1, sizeof (*rwa)); - + memset(rwa, 0, sizeof(*rwa)); if (rwa == NULL) { result = ENOMEM; diff --git a/src/compat/pthread/pthread_rwlockattr_setpshared.c b/src/compat/pthread/pthread_rwlockattr_setpshared.c index 58c3f76c7..6a94e89bb 100644 --- a/src/compat/pthread/pthread_rwlockattr_setpshared.c +++ b/src/compat/pthread/pthread_rwlockattr_setpshared.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_self.c b/src/compat/pthread/pthread_self.c index 20b371fcd..e5f075d9d 100644 --- a/src/compat/pthread/pthread_self.c +++ b/src/compat/pthread/pthread_self.c @@ -40,9 +40,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_spin_destroy.c b/src/compat/pthread/pthread_spin_destroy.c index 99c2cd397..c115270eb 100644 --- a/src/compat/pthread/pthread_spin_destroy.c +++ b/src/compat/pthread/pthread_spin_destroy.c @@ -40,8 +40,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -79,7 +79,8 @@ pthread_spin_destroy (pthread_spinlock_t * lock) * have finished with the spinlock before destroying it. */ *lock = NULL; - (void) free (s); + free(s); + //(void) free (s); } } else diff --git a/src/compat/pthread/pthread_spin_init.c b/src/compat/pthread/pthread_spin_init.c index ff4141489..32c5aa104 100644 --- a/src/compat/pthread/pthread_spin_init.c +++ b/src/compat/pthread/pthread_spin_init.c @@ -40,8 +40,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include - +/* #include */ +#include #include "pthread.h" #include "implement.h" @@ -89,7 +89,7 @@ pthread_spin_init (pthread_spinlock_t * lock, int pshared) } s = (pthread_spinlock_t) calloc (1, sizeof (*s)); - + memset(s, 0, sizeof(*s)); if (s == NULL) { return ENOMEM; @@ -123,7 +123,8 @@ pthread_spin_init (pthread_spinlock_t * lock, int pshared) } else { - (void) free (s); + free(s); + // (void) free (s); *lock = NULL; } diff --git a/src/compat/pthread/pthread_terminate.c b/src/compat/pthread/pthread_terminate.c index a58961296..87236a08b 100644 --- a/src/compat/pthread/pthread_terminate.c +++ b/src/compat/pthread/pthread_terminate.c @@ -39,10 +39,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include -#include - +/* #include */ +/* #include */ +/* #include */ +#include +#include #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/pthread_timechange_handler_np.c b/src/compat/pthread/pthread_timechange_handler_np.c index c523c1f04..58f3111dc 100644 --- a/src/compat/pthread/pthread_timechange_handler_np.c +++ b/src/compat/pthread/pthread_timechange_handler_np.c @@ -110,5 +110,5 @@ pthread_timechange_handler_np (void *arg) pte_osMutexUnlock(pte_cond_list_lock); - return (void *) (result != 0 ? EAGAIN : 0); + return (void *)(result != 0 ? EAGAIN : 0); } diff --git a/src/compat/pthread/sched.h b/src/compat/pthread/sched.h index 464d0395f..f18536eb0 100644 --- a/src/compat/pthread/sched.h +++ b/src/compat/pthread/sched.h @@ -51,7 +51,7 @@ #ifndef _SCHED_H #define _SCHED_H -#include +#include "nk/pte_types.h" #undef PTE_LEVEL diff --git a/src/compat/pthread/sched_yield.c b/src/compat/pthread/sched_yield.c index e0416ab09..9cb492817 100644 --- a/src/compat/pthread/sched_yield.c +++ b/src/compat/pthread/sched_yield.c @@ -40,10 +40,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - -#include "pte_osal.h" +/* #include */ +/* #include */ +#include +#include "nk/pte_osal.h" #include "pthread.h" #include "implement.h" diff --git a/src/compat/pthread/sem_destroy.c b/src/compat/pthread/sem_destroy.c index cf2240f82..67a6a9dcf 100644 --- a/src/compat/pthread/sem_destroy.c +++ b/src/compat/pthread/sem_destroy.c @@ -47,10 +47,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - -#include "pte_osal.h" +/* #include */ +/* #include */ +#include +#include "nk/pte_osal.h" #include "pthread.h" #include "semaphore.h" diff --git a/src/compat/pthread/sem_init.c b/src/compat/pthread/sem_init.c index e497098fc..bb53551b4 100644 --- a/src/compat/pthread/sem_init.c +++ b/src/compat/pthread/sem_init.c @@ -39,9 +39,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" @@ -105,7 +105,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value) else { s = (sem_t) calloc (1, sizeof (*s)); - + memset(s, 0, sizeof(*s)); if (NULL == s) { result = ENOMEM; diff --git a/src/compat/pthread/sem_post.c b/src/compat/pthread/sem_post.c index 18985e938..fecb80458 100644 --- a/src/compat/pthread/sem_post.c +++ b/src/compat/pthread/sem_post.c @@ -47,9 +47,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" diff --git a/src/compat/pthread/sem_post_multiple.c b/src/compat/pthread/sem_post_multiple.c index b7e6d21aa..46ae6270d 100644 --- a/src/compat/pthread/sem_post_multiple.c +++ b/src/compat/pthread/sem_post_multiple.c @@ -47,9 +47,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" diff --git a/src/compat/pthread/sem_timedwait.c b/src/compat/pthread/sem_timedwait.c index 0601c5742..f100b5137 100644 --- a/src/compat/pthread/sem_timedwait.c +++ b/src/compat/pthread/sem_timedwait.c @@ -47,9 +47,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" diff --git a/src/compat/pthread/sem_wait.c b/src/compat/pthread/sem_wait.c index 4fcc8de84..e89556599 100644 --- a/src/compat/pthread/sem_wait.c +++ b/src/compat/pthread/sem_wait.c @@ -47,9 +47,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - +/* #include */ +/* #include */ +#include #include "pthread.h" #include "semaphore.h" #include "implement.h" From 3c73fd2a181a09a807c2d313fdc44bf754eec0bb Mon Sep 17 00:00:00 2001 From: MJC Date: Sun, 19 Jul 2020 17:24:53 -0500 Subject: [PATCH 21/36] Update libccompat and linux with features needed by pthreads/omp --- Kconfig | 49 ++++++- README.cs446-s20 | 36 ------ configs/cs446-s20-example-config | 201 ----------------------------- src/compat/libccompat/libccompat.c | 182 ++++++++++++++++++++------ src/compat/linux/sysconf.c | 7 + src/nautilus/env.c | 2 +- 6 files changed, 192 insertions(+), 285 deletions(-) delete mode 100644 README.cs446-s20 delete mode 100644 configs/cs446-s20-example-config diff --git a/Kconfig b/Kconfig index cda0e12bd..c6ac34d5f 100644 --- a/Kconfig +++ b/Kconfig @@ -833,25 +833,59 @@ endmenu menu "Compatability" config BASE_LIBC_COMPAT - bool "Basic libc compatability"; + bool "Basic libc compatability" default y help Basic libc compatability layer + config DEBUG_BASE_LIBC_COMPAT + bool "Debug basic libc compatability" + depends on BASE_LIBC_COMPAT + default n + help + Enable debugging output from the basic libc compatability layer + + config BASE_LIBM_COMPAT + bool "Basic libm compatability" + default y + help + Basic libm compatability layer + + config DEBUG_BASE_LIBM_COMPAT + bool "Debug basic libm compatability" + depends on BASE_LIBM_COMPAT + default n + help + Enable debugging output from the basic libm compatability layer + config BASE_LINUX_COMPAT - bool "Basic Linux user-level compatability layer"; + bool "Basic Linux user-level compatability layer" depends on BASE_LIBC_COMPAT default y help Basic Linux user-level compatability layer - + + config DEBUG_BASE_LINUX_COMPAT + bool "Debug basic Linux compatability" + depends on BASE_LINUX_COMPAT + default n + help + Enable debugging output from the basic Linux compatability layer + config BASE_PTHREAD_COMPAT - bool "POSIX threads compatability later"; + bool "POSIX threads compatability layer" default y depends on BASE_LIBC_COMPAT && BASE_LINUX_COMPAT help POSIX threads + config DEBUG_BASE_PTHREAD_COMPAT + bool "Debug basic POSIX threads compatability layer" + depends on BASE_PTHREAD_COMPAT + default n + help + Enable debugging output from the basic POSIX threads compatability layer + endmenu menu "Optimizations" @@ -1085,6 +1119,13 @@ menu Debugging help Turn on debug prints for C++ initialization/support code + config DEBUG_ENVS + bool "Debug Environments" + depends on DEBUG_PRINTS + default n + help + Turn on debug prints for environment variable support + config DEBUG_THREADS bool "Debug Threads" depends on DEBUG_PRINTS diff --git a/README.cs446-s20 b/README.cs446-s20 deleted file mode 100644 index e122f6a7f..000000000 --- a/README.cs446-s20 +++ /dev/null @@ -1,36 +0,0 @@ -To set up: - -You should be on the cs446-s20 branch to start - -$ cp configs/cs446-s20-example-config .config - -$ make isoimage - -$ ./run - - -CHANGING CONFIGURATION - -$ make menuconfig - - -MONITOR - -to enter the monitor, press F9 - -The monitor will also be entered on any unhandled -exception, interrupt, panic, hang, etc. - -The watchdog timer is active and will bark after one -second of seeing no interrupts - -GDB - -to attach a debugger: - -$ ./run & - -$ gdb nautilus.bin -(gdb) target remote localhost:1234 - - diff --git a/configs/cs446-s20-example-config b/configs/cs446-s20-example-config deleted file mode 100644 index f36e9c4ad..000000000 --- a/configs/cs446-s20-example-config +++ /dev/null @@ -1,201 +0,0 @@ -# -# Automatically generated make config: don't edit -#Nautilus: -# Mon Apr 13 13:31:21 2020 -# - -# -# Platform -# -NAUT_CONFIG_X86_64_HOST=y -# NAUT_CONFIG_XEON_PHI is not set -# NAUT_CONFIG_HVM_HRT is not set -# NAUT_CONFIG_GEM5 is not set -NAUT_CONFIG_MAX_CPUS=256 -NAUT_CONFIG_MAX_IOAPICS=16 -# NAUT_CONFIG_PALACIOS is not set - -# -# Build -# -NAUT_CONFIG_USE_NAUT_BUILTINS=y -NAUT_CONFIG_CXX_SUPPORT=y -# NAUT_CONFIG_RUST_SUPPORT is not set -NAUT_CONFIG_USE_GCC=y -# NAUT_CONFIG_USE_CLANG is not set -# NAUT_CONFIG_USE_WLLVM is not set -NAUT_CONFIG_COMPILER_PREFIX="" -NAUT_CONFIG_COMPILER_SUFFIX="" -NAUT_CONFIG_TOOLCHAIN_ROOT="" - -# -# Configuration -# -NAUT_CONFIG_MAX_THREADS=1024 -# NAUT_CONFIG_RUN_TESTS_AT_BOOT is not set -NAUT_CONFIG_THREAD_EXIT_KEYCODE=196 -# NAUT_CONFIG_USE_TICKETLOCKS is not set -# NAUT_CONFIG_PARTITION_SUPPORT is not set -NAUT_CONFIG_VIRTUAL_CONSOLE_DISPLAY_NAME=y -# NAUT_CONFIG_VIRTUAL_CONSOLE_CHARDEV_CONSOLE is not set -NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR=y -NAUT_CONFIG_VIRTUAL_CONSOLE_SERIAL_MIRROR_ALL=y - -# -# Scheduler Options -# -NAUT_CONFIG_UTILIZATION_LIMIT=99 -NAUT_CONFIG_SPORADIC_RESERVATION=10 -NAUT_CONFIG_APERIODIC_RESERVATION=10 -NAUT_CONFIG_HZ=10 -NAUT_CONFIG_INTERRUPT_REINJECTION_DELAY_NS=10000 -# NAUT_CONFIG_AUTO_REAP is not set -# NAUT_CONFIG_WORK_STEALING is not set -# NAUT_CONFIG_TASK_IN_SCHED is not set -# NAUT_CONFIG_TASK_THREAD is not set -# NAUT_CONFIG_TASK_IN_IDLE is not set -# NAUT_CONFIG_INTERRUPT_THREAD is not set -# NAUT_CONFIG_APERIODIC_DYNAMIC_QUANTUM is not set -# NAUT_CONFIG_APERIODIC_DYNAMIC_LIFETIME is not set -# NAUT_CONFIG_APERIODIC_LOTTERY is not set -NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y - -# -# Fiber Options -# -# NAUT_CONFIG_FIBER_ENABLE is not set -# NAUT_CONFIG_REAL_MODE_INTERFACE is not set - -# -# Watchdog Options -# -NAUT_CONFIG_WATCHDOG=y -NAUT_CONFIG_WATCHDOG_DEFAULT_TIME_MS=1000 -# NAUT_CONFIG_DEBUG_WATCHDOG is not set -# NAUT_CONFIG_ISOCORE is not set -# NAUT_CONFIG_CACHEPART is not set - -# -# Garbage Collection Options -# -# NAUT_CONFIG_GARBAGE_COLLECTION is not set - -# -# FPU Options -# -# NAUT_CONFIG_XSAVE_SUPPORT is not set - -# -# Optimizations -# -NAUT_CONFIG_FPU_SAVE=y -NAUT_CONFIG_KICK_SCHEDULE=y -NAUT_CONFIG_HALT_WHILE_IDLE=y -# NAUT_CONFIG_THREAD_OPTIMIZE is not set - -# -# Debugging -# -NAUT_CONFIG_DEBUG_INFO=y -NAUT_CONFIG_DEBUG_PRINTS=y -NAUT_CONFIG_ENABLE_ASSERTS=y -# NAUT_CONFIG_PROFILE is not set -# NAUT_CONFIG_SILENCE_UNDEF_ERR is not set -# NAUT_CONFIG_ENABLE_STACK_CHECK is not set -# NAUT_CONFIG_ENABLE_REMOTE_DEBUGGING is not set -NAUT_CONFIG_ENABLE_MONITOR=y -# NAUT_CONFIG_DEBUG_PAGING is not set -# NAUT_CONFIG_DEBUG_BOOTMEM is not set -# NAUT_CONFIG_DEBUG_CMDLINE is not set -# NAUT_CONFIG_DEBUG_TESTS is not set -# NAUT_CONFIG_DEBUG_BUDDY is not set -# NAUT_CONFIG_DEBUG_KMEM is not set -# NAUT_CONFIG_DEBUG_FPU is not set -# NAUT_CONFIG_DEBUG_SMP is not set -# NAUT_CONFIG_DEBUG_SHELL is not set -# NAUT_CONFIG_DEBUG_SFI is not set -# NAUT_CONFIG_DEBUG_CXX is not set -# NAUT_CONFIG_DEBUG_THREADS is not set -# NAUT_CONFIG_DEBUG_TASKS is not set -# NAUT_CONFIG_DEBUG_WAITQUEUES is not set -# NAUT_CONFIG_DEBUG_FUTURES is not set -# NAUT_CONFIG_DEBUG_GROUP is not set -# NAUT_CONFIG_DEBUG_SCHED is not set -# NAUT_CONFIG_DEBUG_GROUP_SCHED is not set -# NAUT_CONFIG_DEBUG_TIMERS is not set -# NAUT_CONFIG_DEBUG_SEMAPHORES is not set -# NAUT_CONFIG_DEBUG_MSG_QUEUES is not set -# NAUT_CONFIG_DEBUG_SYNCH is not set -# NAUT_CONFIG_DEBUG_BARRIER is not set -# NAUT_CONFIG_DEBUG_NUMA is not set -# NAUT_CONFIG_DEBUG_VIRTUAL_CONSOLE is not set -# NAUT_CONFIG_DEBUG_DEV is not set -# NAUT_CONFIG_DEBUG_FILESYSTEM is not set -# NAUT_CONFIG_DEBUG_LOADER is not set -# NAUT_CONFIG_DEBUG_LINKER is not set -# NAUT_CONFIG_DEBUG_PMC is not set - -# -# Address Spaces -# -# NAUT_CONFIG_ASPACES is not set - -# -# Runtimes -# -# NAUT_CONFIG_LEGION_RT is not set -# NAUT_CONFIG_NDPC_RT is not set -# NAUT_CONFIG_NESL_RT is not set -# NAUT_CONFIG_OPENMP_RT is not set -NAUT_CONFIG_RACKET_RT=y - -# -# Devices -# - -# -# Serial Options -# -NAUT_CONFIG_SERIAL_REDIRECT=y -NAUT_CONFIG_SERIAL_REDIRECT_PORT=1 -# NAUT_CONFIG_APIC_FORCE_XAPIC_MODE is not set -# NAUT_CONFIG_APIC_TIMER_CALIBRATE_INDEPENDENTLY is not set -# NAUT_CONFIG_DEBUG_APIC is not set -# NAUT_CONFIG_DEBUG_IOAPIC is not set -# NAUT_CONFIG_DEBUG_PCI is not set -NAUT_CONFIG_DISABLE_PS2_MOUSE=y -# NAUT_CONFIG_DEBUG_PS2 is not set -# NAUT_CONFIG_GPIO is not set -# NAUT_CONFIG_DEBUG_PIT is not set -# NAUT_CONFIG_HPET is not set -NAUT_CONFIG_VIRTIO_PCI=y -# NAUT_CONFIG_DEBUG_VIRTIO_PCI is not set -NAUT_CONFIG_VIRTIO_NET=y -# NAUT_CONFIG_DEBUG_VIRTIO_NET is not set -NAUT_CONFIG_VIRTIO_BLK=y -# NAUT_CONFIG_DEBUG_VIRTIO_BLK is not set -NAUT_CONFIG_E1000_PCI=y -# NAUT_CONFIG_DEBUG_E1000_PCI is not set -NAUT_CONFIG_E1000E_PCI=y -# NAUT_CONFIG_DEBUG_E1000E_PCI is not set -# NAUT_CONFIG_MLX3_PCI is not set -# NAUT_CONFIG_RAMDISK is not set -NAUT_CONFIG_ATA=y -# NAUT_CONFIG_DEBUG_ATA is not set - -# -# Filesystems -# -# NAUT_CONFIG_EXT2_FILESYSTEM_DRIVER is not set -# NAUT_CONFIG_FAT32_FILESYSTEM_DRIVER is not set - -# -# Networking -# -# NAUT_CONFIG_NET_ETHERNET is not set -# NAUT_CONFIG_NET_COLLECTIVE is not set - -# -# Languages -# -# NAUT_CONFIG_LOAD_LUA is not set diff --git a/src/compat/libccompat/libccompat.c b/src/compat/libccompat/libccompat.c index 3a7aa9c10..745f23d58 100644 --- a/src/compat/libccompat/libccompat.c +++ b/src/compat/libccompat/libccompat.c @@ -36,9 +36,20 @@ #include #include #include +#include #include +#ifdef NAUT_CONFIG_DEBUG_BASE_LIBC_COMPAT +#define DEBUG(fmt, args...) DEBUG_PRINT("libc: " fmt, ##args) +#else +#define DEBUG(fmt, args...) +#endif +#define INFO(fmt, args...) INFO_PRINT("libc: " fmt, ##args) +#define ERROR(fmt, args...) ERROR_PRINT("libc: " fmt, ##args) +#define WARN(fmt, args...) WARN_PRINT("libc: " fmt, ##args) + + int errno=0; #define GEN_DEF(x) \ @@ -202,8 +213,12 @@ __assert_fail (const char * assertion, const char * file, unsigned line, const c int vfprintf (FILE * stream, const char * format, va_list arg) { +#if 0 UNDEF_FUN_ERR(); return -1; +#else + return vprintk(format,arg); +#endif } @@ -303,12 +318,20 @@ drand48(void) } -char * -strerror (int errnum) +char* strerror_r(int errnum, char* buf, size_t buflen) { - UNDEF_FUN_ERR(); - return NULL; + snprintf(buf,buflen,"error %d (dunno?)",errnum); + return buf; } + + +char *strerror (int errnum) +{ + static char strerr_buf[128]; + return strerror_r(errnum,strerr_buf,128); +} + + FILE *tmpfile(void) { @@ -359,12 +382,35 @@ fdopen (int fd, const char * mode) return NULL; } -char *getenv(const char *name) + +int setenv(const char *key, const char *value, int overwrite) { + char *curval; + struct nk_env * env = nk_env_find(NK_ENV_GLOBAL_NAME); + if (nk_env_search(env,(char*)key,&curval)) { + if (overwrite) { + return nk_env_update(env,(char*)key,(char*)value); + } else { + return -1; + } + } else { + return nk_env_insert(env, (char*)key, (char*)value); + } +} - UNDEF_FUN_ERR(); - return NULL; + +char *getenv(const char *key) +{ + struct nk_env *env = nk_env_find(NK_ENV_GLOBAL_NAME); + if (!env) { + return 0; + } + char *value =NULL; + nk_env_search(env,(char*)key,&value); + return value; } + + //For LUA Support clock_t clock() { @@ -811,6 +857,57 @@ double exp(double x) return x; } +unsigned long getpid(void) +{ + return ((nk_thread_t*)get_cur_thread())->tid; +} + +unsigned long getppid(void) +{ + if (((nk_thread_t*)get_cur_thread())->parent) { + return ((nk_thread_t*)get_cur_thread())->parent->tid; + } else { + return 0; + } +} + + + +#define suseconds_t uint64_t +struct timeval { + time_t tv_sec; /* seconds */ + suseconds_t tv_usec; /* microseconds */ +}; + +struct timezone; + +int gettimeofday(struct timeval *tv, struct timezone *tz_ignored) +{ + uint64_t ns = nk_sched_get_realtime(); + + tv->tv_sec = ns / 1000000000ULL; + tv->tv_usec = (ns % 1000000000ULL)/1000ULL; + + return 0; +} + +#define rlim_t uint32_t + +struct rlimit { + rlim_t rlim_cur; /* Soft limit */ + rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ +}; + +int getrlimit(int resource, struct rlimit *rlim) +{ + DEBUG("getrlimit %d\n", resource); + rlim->rlim_cur = 0xF0000000; + rlim->rlim_max = 0xF0000000; + return 0; +} + + + /* became lazy... */ GEN_DEF(writev) GEN_DEF(ungetwc) @@ -857,9 +954,6 @@ GEN_DEF(__towupper_l) GEN_DEF(__uselocale) GEN_DEF(__strftime_l) GEN_DEF(mbsnrtowcs) -GEN_DEF(pthread_mutex_init) -GEN_DEF(pthread_mutex_lock) -GEN_DEF(pthread_mutex_unlock) GEN_DEF(wcscoll) //GEN_DEF(strcoll) GEN_DEF(towupper) @@ -879,35 +973,12 @@ GEN_DEF(wcsxfrm) GEN_DEF(__kernel_standard); GEN_DEF(__get_cpu_features); - -// KMP - -// SOFT FLOAT - NOT SURE WHY IT IS USING THESE -GEN_DEF(__mulxc3) -GEN_DEF(__muldc3) -GEN_DEF(__mulsc3) -GEN_DEF(__divxc3) -GEN_DEF(__divdc3) -GEN_DEF(__divsc3) - - -// Other stuff KMP needs, for a start -GEN_DEF(atexit) -GEN_DEF(catclose) -GEN_DEF(catgets) -GEN_DEF(catopen) -GEN_DEF(close) -GEN_DEF(closedir) -GEN_DEF(dlsym) -GEN_DEF(environ) -GEN_DEF(fgetc) -GEN_DEF(gethostname) -GEN_DEF(getpid) -GEN_DEF(getrlimit) -GEN_DEF(getrusage) -GEN_DEF(gettimeofday) -GEN_DEF(open) -GEN_DEF(opendir) +// pthread functionality is in the pthread compatability +// directory, if it is included +#ifndef NAUT_CONFIG_BASE_PTHREAD_COMPAT +GEN_DEF(pthread_mutex_init) +GEN_DEF(pthread_mutex_lock) +GEN_DEF(pthread_mutex_unlock) GEN_DEF(pthread_atfork) GEN_DEF(pthread_attr_destroy) GEN_DEF(pthread_attr_getstack) @@ -934,9 +1005,36 @@ GEN_DEF(pthread_self) GEN_DEF(pthread_setcancelstate) GEN_DEF(pthread_setcanceltype) GEN_DEF(pthread_setspecific) -GEN_DEF(readdir) GEN_DEF(sched_yield) -GEN_DEF(setenv) +#endif + + +// KMP + +// SOFT FLOAT - NOT SURE WHY IT IS USING THESE +GEN_DEF(__mulxc3) +GEN_DEF(__muldc3) +GEN_DEF(__mulsc3) +GEN_DEF(__divxc3) +GEN_DEF(__divdc3) +GEN_DEF(__divsc3) + + +// Other stuff KMP needs, for a start +GEN_DEF(atexit) +GEN_DEF(catclose) +GEN_DEF(catgets) +GEN_DEF(catopen) +GEN_DEF(close) +GEN_DEF(closedir) +GEN_DEF(dlsym) +GEN_DEF(environ) +GEN_DEF(fgetc) +GEN_DEF(gethostname) +GEN_DEF(getrusage) +GEN_DEF(open) +GEN_DEF(opendir) +GEN_DEF(readdir) GEN_DEF(sigaction) GEN_DEF(sigaddset) GEN_DEF(sigdelset) @@ -944,9 +1042,7 @@ GEN_DEF(sigemptyset) GEN_DEF(sigfillset) GEN_DEF(sigismember) GEN_DEF(sleep) -GEN_DEF(strerror_r) GEN_DEF(strtok_r) -GEN_DEF(sysconf) GEN_DEF(times) GEN_DEF(unsetenv) GEN_DEF(vfscanf) diff --git a/src/compat/linux/sysconf.c b/src/compat/linux/sysconf.c index eba87af2d..9607a98e2 100644 --- a/src/compat/linux/sysconf.c +++ b/src/compat/linux/sysconf.c @@ -1052,3 +1052,10 @@ __sysconf (int name) /* return ret; */ /* } */ /* #endif */ + + +long sysconf(int name){ + //DEBUG("sysconf, %d",name); + long conf = __sysconf(name); + return conf; +} diff --git a/src/nautilus/env.c b/src/nautilus/env.c index f0c0599f7..95f68e6b8 100644 --- a/src/nautilus/env.c +++ b/src/nautilus/env.c @@ -28,7 +28,7 @@ -#if 0 +#if NAUT_CONFIG_DEBUG_ENVS #define DEBUG(fmt, args...) DEBUG_PRINT("env: " fmt, ##args) #else #define DEBUG(fmt, args...) From b142168dda98a14fce170066227df9fde011712f Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Sun, 19 Jul 2020 18:49:06 -0500 Subject: [PATCH 22/36] Factor out libc and libm compatability. Make missing functionality easier to find --- include/nautilus/libccompat.h | 6 +- src/compat/Makefile | 1 + src/compat/libccompat/libccompat.c | 410 +++++++++++------------------ src/compat/libmcompat/Makefile | 1 + src/compat/libmcompat/libmcompat.c | 189 +++++++++++++ src/nautilus/naut_string.c | 14 + 6 files changed, 370 insertions(+), 251 deletions(-) create mode 100644 src/compat/libmcompat/Makefile create mode 100644 src/compat/libmcompat/libmcompat.c diff --git a/include/nautilus/libccompat.h b/include/nautilus/libccompat.h index b0e4f80ce..533b0e97d 100644 --- a/include/nautilus/libccompat.h +++ b/include/nautilus/libccompat.h @@ -35,6 +35,8 @@ extern "C" { #define UNDEF_FUN_ERR() #endif +#define BOGUS_FUN_ERR() ERROR_PRINT("Function (%s) is BOGUS\n", __func__) + #define RAND_MAX 2147483647 typedef int clockid_t; @@ -242,6 +244,9 @@ size_t strftime(char *str, size_t maxsize, const char *format, const struct tm * void (*signal(int sig, void (*func)(int)))(int); +int abs(int x); + + double pow(double x, double y); char *tmpnam(char *s); clock_t clock(void); @@ -260,7 +265,6 @@ double fmod(double y, double x); double frexp(double x, int *e); double ldexp(double x, int exp); double strtod(const char *str, char **endptr); -double abs(double x); double sin(double x); double sinh(double x); double cos(double x); diff --git a/src/compat/Makefile b/src/compat/Makefile index 3e5f919fa..5e262ddfe 100644 --- a/src/compat/Makefile +++ b/src/compat/Makefile @@ -1,5 +1,6 @@ obj-$(NAUT_CONFIG_BASE_LIBC_COMPAT) += libccompat/ +obj-$(NAUT_CONFIG_BASE_LIBM_COMPAT) += libmcompat/ obj-$(NAUT_CONFIG_BASE_LINUX_COMPAT) += linux/ obj-$(NAUT_CONFIG_BASE_PTHREAD_COMPAT) += pthread/ diff --git a/src/compat/libccompat/libccompat.c b/src/compat/libccompat/libccompat.c index 745f23d58..24250e461 100644 --- a/src/compat/libccompat/libccompat.c +++ b/src/compat/libccompat/libccompat.c @@ -52,12 +52,14 @@ int errno=0; -#define GEN_DEF(x) \ - int x (void) { \ - UNDEF_FUN_ERR(); \ - return 0; \ +#define GEN_UNDEF(t,f,v) \ + t f (void) { \ + UNDEF_FUN_ERR(); \ + return v; \ } +#define BOGUS() BOGUS_FUN_ERR() + // Structs needed for LUA @@ -122,6 +124,7 @@ static uint64_t dummy_mono_clock = 0; time_t time (time_t * timer) { + BOGUS(); struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); @@ -135,6 +138,7 @@ time (time_t * timer) void abort(void) { + BOGUS(); printk("Thread called abort\n"); nk_thread_exit(NULL); } @@ -162,6 +166,7 @@ __popcountdi2 (long long a) void exit(int status) { + BOGUS(); printk("Thread called exit (status=%d)\n", status); nk_thread_exit((void*)(long)status); } @@ -170,6 +175,7 @@ int clock_gettime (clockid_t clk_id, struct timespec * tp) { + BOGUS(); if (clk_id != CLOCK_MONOTONIC) { printk("NAUTILUS WARNING: using invalid clock type\n"); return -EINVAL; @@ -217,6 +223,7 @@ vfprintf (FILE * stream, const char * format, va_list arg) UNDEF_FUN_ERR(); return -1; #else + if (stream!=stdout && stream!=stderr) { BOGUS(); } return vprintk(format,arg); #endif } @@ -320,6 +327,7 @@ drand48(void) char* strerror_r(int errnum, char* buf, size_t buflen) { + BOGUS(); snprintf(buf,buflen,"error %d (dunno?)",errnum); return buf; } @@ -327,6 +335,7 @@ char* strerror_r(int errnum, char* buf, size_t buflen) char *strerror (int errnum) { + BOGUS(); static char strerr_buf[128]; return strerror_r(errnum,strerr_buf,128); } @@ -454,8 +463,10 @@ int fflush (FILE * f) return 0; } -void (*signal(int sig, void (*func)(int)))(int ){ +void (*signal(int sig, void (*func)(int)))(int ) +{ // printk("\nSIGNAL Function:"); + BOGUS(); return 0; } @@ -468,6 +479,7 @@ fprintf (FILE * f, const char * s, ...) UNDEF_FUN_ERR(); return -1; #else + if (f!=stdout && f!=stderr) { BOGUS(); } va_list arg; va_start(arg,s); vprintk(s, arg); @@ -520,6 +532,7 @@ int printf (const char * s, ...) int fputc (int c, FILE * f) { + if (f!=stderr && f!=stdout) { BOGUS(); } printk("%c"); return c; } @@ -528,15 +541,17 @@ fputc (int c, FILE * f) int fputs (const char * s, FILE * f) { + if (f!=stderr && f!=stdout) { BOGUS(); } printk("%s\n", s); return 0; } -size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) +size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *f) { - - printk("\n %s",ptr); - //UNDEF_FUN_ERR(); - return (int)size; + + if (f!=stderr && f!=stdout) { BOGUS(); } + printk("\n %s",ptr); + //UNDEF_FUN_ERR(); + return (int)size; } size_t @@ -685,17 +700,19 @@ int getc(FILE* arg) int fileno(FILE* f) { - return 0; + return f==stdin ? 0 : f==stdout ? 1 : f==stderr ? 2 : -1; } int isatty(int fd) { + BOGUS(); return 0; } //LUA SPECIFIC.................... size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) { + UNDEF_FUN_ERR(); return 0; } int feof(FILE * x) @@ -709,10 +726,8 @@ char *fgets(char *str, int n, FILE *stream) UNDEF_FUN_ERR(); return NULL; } -void *memchr(const void *str, int c, size_t n) -{ - return NULL; -} + + /*void longjmp(int *x, int __y) { UNDEF_FUN_ERR(); @@ -722,76 +737,23 @@ int setjmp(int *x) { return 0; } */ -double fabs(double __x){ - return abs(__x); -} -double atan(double __x){ - return 45.000; -} -double atan2(double y, double x){ - return 135.00; -} -double fmod(double y, double x){ - // this is replacement to actual fmod() (/nautilus/libccompat) - // defining own fmod similar to the one defined in (/gcc/libc) - printk("\n in fmod y %d,x %d",(int)y,(int)x); -// return y -x*(y/x); - return (int)y% (int)x; -} - -double fmodnew(int y, int x){ - // this is replacement to actual fmod() (/nautilus/libccompat) - // defining own fmod similar to the one defined in (/gcc/libc) - // printk("\n in fmod y %d,x %d",y,x); - return y -x*(y/x); -} -double modf(double y, double *x){ - *x = 0; -// printk("\n in modf"); - return 0.000; -} -double frexp(double x, int *e){ - *e = 0; - return 0.5; -} -double ldexp(double x, int exp){ - return x; -} - int ischar(unsigned char *str) { - - return 1; + BOGUS(); + // WTF is this??? + return 1; } // strtod is implemented in dtoa.c /*----------*/ -double abs(double x) +int abs(int x) { -//should return absolute value of x -if (x<0) - return -1*x; -else - return x; -} -double sin(double x) -{ -return x; -} -double sinh(double x) -{ -return x; -} -double cos(double x) -{ -return x; -} -double cosh(double x) -{ -return x; -} + return x<0 ? -x : x; +} + + time_t mktime(struct tm *timeptr) { return 0; @@ -808,54 +770,12 @@ int strcoll(const char *str1, const char *str2) { return 0; } -double tan(double x) -{ -return x; -} -double tanh(double x) -{ -return x; -} -double asin(double x) -{ -return x; -} -double acos(double x) -{ -return x; -} -double ceil(double x) -{ -return x; -} -double floor(double x) -{ -return x; -} + double difftime(time_t time1, time_t time2) { + UNDEF_FUN_ERR(); return 0; } -double sqrt(double x) -{ -return x; -} -double pow(double x, double y) -{ -return x; -} -double log(double x) -{ -return x; -} -double log10(double x) -{ -return x; -} -double exp(double x) -{ -return x; -} unsigned long getpid(void) { @@ -909,140 +829,130 @@ int getrlimit(int resource, struct rlimit *rlim) /* became lazy... */ -GEN_DEF(writev) -GEN_DEF(ungetwc) -GEN_DEF(__errno_location) -GEN_DEF(write) -GEN_DEF(wcrtomb) -GEN_DEF(mbrtowc) -//GEN_DEF(getc) -GEN_DEF(__iswctype_l) -GEN_DEF(wcslen) -GEN_DEF(__strtof_l) -//GEN_DEF(stderr) -GEN_DEF(wmemset) -//GEN_DEF(stdin) -//GEN_DEF(fileno) -GEN_DEF(__fxstat64) -GEN_DEF(putc) -GEN_DEF(__wcscoll_l) -GEN_DEF(__towlower_l) -GEN_DEF(wctob) -GEN_DEF(mbsrtowcs) -GEN_DEF(read) -GEN_DEF(wmemmove) -GEN_DEF(__strxfrm_l) -GEN_DEF(wmemchr) -GEN_DEF(__freelocale) -GEN_DEF(__wcsftime_l) -GEN_DEF(wmemcpy) -GEN_DEF(putwc) -GEN_DEF(__stack_chk_fail) -GEN_DEF(__wcsxfrm_l) -GEN_DEF(wcscmp) -GEN_DEF(wcsnrtombs) -GEN_DEF(__strcoll_l) -//GEN_DEF(stdout) -GEN_DEF(btowc) -//GEN_DEF(memchr) -GEN_DEF(strtold_l) -GEN_DEF(wmemcmp) -GEN_DEF(__strtod_l) -//GEN_DEF(setvbuf) -GEN_DEF(__wctype_l) -GEN_DEF(__towupper_l) -GEN_DEF(__uselocale) -GEN_DEF(__strftime_l) -GEN_DEF(mbsnrtowcs) -GEN_DEF(wcscoll) -//GEN_DEF(strcoll) -GEN_DEF(towupper) -GEN_DEF(towlower) -GEN_DEF(iswctype) -//GEN_DEF(strftime) -GEN_DEF(wcsftime) -GEN_DEF(wctype) -GEN_DEF(strtold) -//GEN_DEF(strtod) -GEN_DEF(strtof) -GEN_DEF(__ctype_b_loc) -GEN_DEF(__ctype_toupper_loc) -GEN_DEF(__ctype_tolower_loc) -GEN_DEF(strxfrm) -GEN_DEF(wcsxfrm) -GEN_DEF(__kernel_standard); -GEN_DEF(__get_cpu_features); +GEN_UNDEF(int,writev,0) +GEN_UNDEF(int,ungetwc,0) +GEN_UNDEF(int,__errno_location,0) +GEN_UNDEF(int,write,0) +GEN_UNDEF(int,wcrtomb,0) +GEN_UNDEF(int,mbrtowc,0) +//GEN_UNDEF(int,getc,0) +GEN_UNDEF(int,__iswctype_l,0) +GEN_UNDEF(int,wcslen,0) +GEN_UNDEF(int,__strtof_l,0) +//GEN_UNDEF(int,stderr,0) +GEN_UNDEF(int,wmemset,0) +//GEN_UNDEF(int,stdin,0) +//GEN_UNDEF(int,fileno,0) +GEN_UNDEF(int,__fxstat64,0) +GEN_UNDEF(int,putc,0) +GEN_UNDEF(int,__wcscoll_l,0) +GEN_UNDEF(int,__towlower_l,0) +GEN_UNDEF(int,wctob,0) +GEN_UNDEF(int,mbsrtowcs,0) +GEN_UNDEF(int,read,0) +GEN_UNDEF(int,wmemmove,0) +GEN_UNDEF(int,__strxfrm_l,0) +GEN_UNDEF(int,wmemchr,0) +GEN_UNDEF(int,__freelocale,0) +GEN_UNDEF(int,__wcsftime_l,0) +GEN_UNDEF(int,wmemcpy,0) +GEN_UNDEF(int,putwc,0) +GEN_UNDEF(int,__stack_chk_fail,0) +GEN_UNDEF(int,__wcsxfrm_l,0) +GEN_UNDEF(int,wcscmp,0) +GEN_UNDEF(int,wcsnrtombs,0) +GEN_UNDEF(int,__strcoll_l,0) +//GEN_UNDEF(int,stdout,0) +GEN_UNDEF(int,btowc,0) +//GEN_UNDEF(int,memchr,0) +GEN_UNDEF(int,strtold_l,0) +GEN_UNDEF(int,wmemcmp,0) +GEN_UNDEF(int,__strtod_l,0) +//GEN_UNDEF(int,setvbuf,0) +GEN_UNDEF(int,__wctype_l,0) +GEN_UNDEF(int,__towupper_l,0) +GEN_UNDEF(int,__uselocale,0) +GEN_UNDEF(int,__strftime_l,0) +GEN_UNDEF(int,mbsnrtowcs,0) +GEN_UNDEF(int,wcscoll,0) +//GEN_UNDEF(int,strcoll,0) +GEN_UNDEF(int,towupper,0) +GEN_UNDEF(int,towlower,0) +GEN_UNDEF(int,iswctype,0) +//GEN_UNDEF(int,strftime,0) +GEN_UNDEF(int,wcsftime,0) +GEN_UNDEF(int,wctype,0) +GEN_UNDEF(int,strtold,0) +//GEN_UNDEF(int,strtod,0) +GEN_UNDEF(int,strtof,0) +GEN_UNDEF(int,__ctype_b_loc,0) +GEN_UNDEF(int,__ctype_toupper_loc,0) +GEN_UNDEF(int,__ctype_tolower_loc,0) +GEN_UNDEF(int,strxfrm,0) +GEN_UNDEF(int,wcsxfrm,0) +GEN_UNDEF(int,__kernel_standard,0); +GEN_UNDEF(int,__get_cpu_features,0); // pthread functionality is in the pthread compatability // directory, if it is included #ifndef NAUT_CONFIG_BASE_PTHREAD_COMPAT -GEN_DEF(pthread_mutex_init) -GEN_DEF(pthread_mutex_lock) -GEN_DEF(pthread_mutex_unlock) -GEN_DEF(pthread_atfork) -GEN_DEF(pthread_attr_destroy) -GEN_DEF(pthread_attr_getstack) -GEN_DEF(pthread_attr_init) -GEN_DEF(pthread_attr_setdetachstate) -GEN_DEF(pthread_attr_setstacksize) -GEN_DEF(pthread_cancel) -GEN_DEF(pthread_cond_destroy) -GEN_DEF(pthread_cond_init) -GEN_DEF(pthread_cond_signal) -GEN_DEF(pthread_cond_wait) -GEN_DEF(pthread_condattr_init) -GEN_DEF(pthread_create) -GEN_DEF(pthread_exit) -GEN_DEF(pthread_getattr_np) -GEN_DEF(pthread_getspecific) -GEN_DEF(pthread_join) -GEN_DEF(pthread_key_create) -GEN_DEF(pthread_key_delete) -GEN_DEF(pthread_mutex_destroy) -GEN_DEF(pthread_mutex_trylock) -GEN_DEF(pthread_mutexattr_init) -GEN_DEF(pthread_self) -GEN_DEF(pthread_setcancelstate) -GEN_DEF(pthread_setcanceltype) -GEN_DEF(pthread_setspecific) -GEN_DEF(sched_yield) +GEN_UNDEF(int,pthread_mutex_init,0) +GEN_UNDEF(int,pthread_mutex_lock,0) +GEN_UNDEF(int,pthread_mutex_unlock,0) +GEN_UNDEF(int,pthread_atfork,0) +GEN_UNDEF(int,pthread_attr_destroy,0) +GEN_UNDEF(int,pthread_attr_getstack,0) +GEN_UNDEF(int,pthread_attr_init,0) +GEN_UNDEF(int,pthread_attr_setdetachstate,0) +GEN_UNDEF(int,pthread_attr_setstacksize,0) +GEN_UNDEF(int,pthread_cancel,0) +GEN_UNDEF(int,pthread_cond_destroy,0) +GEN_UNDEF(int,pthread_cond_init,0) +GEN_UNDEF(int,pthread_cond_signal,0) +GEN_UNDEF(int,pthread_cond_wait,0) +GEN_UNDEF(int,pthread_condattr_init,0) +GEN_UNDEF(int,pthread_create,0) +GEN_UNDEF(int,pthread_exit,0) +GEN_UNDEF(int,pthread_getattr_np,0) +GEN_UNDEF(int,pthread_getspecific,0) +GEN_UNDEF(int,pthread_join,0) +GEN_UNDEF(int,pthread_key_create,0) +GEN_UNDEF(int,pthread_key_delete,0) +GEN_UNDEF(int,pthread_mutex_destroy,0) +GEN_UNDEF(int,pthread_mutex_trylock,0) +GEN_UNDEF(int,pthread_mutexattr_init,0) +GEN_UNDEF(int,pthread_self,0) +GEN_UNDEF(int,pthread_setcancelstate,0) +GEN_UNDEF(int,pthread_setcanceltype,0) +GEN_UNDEF(int,pthread_setspecific,0) +GEN_UNDEF(int,sched_yield,0) #endif -// KMP - -// SOFT FLOAT - NOT SURE WHY IT IS USING THESE -GEN_DEF(__mulxc3) -GEN_DEF(__muldc3) -GEN_DEF(__mulsc3) -GEN_DEF(__divxc3) -GEN_DEF(__divdc3) -GEN_DEF(__divsc3) - - -// Other stuff KMP needs, for a start -GEN_DEF(atexit) -GEN_DEF(catclose) -GEN_DEF(catgets) -GEN_DEF(catopen) -GEN_DEF(close) -GEN_DEF(closedir) -GEN_DEF(dlsym) -GEN_DEF(environ) -GEN_DEF(fgetc) -GEN_DEF(gethostname) -GEN_DEF(getrusage) -GEN_DEF(open) -GEN_DEF(opendir) -GEN_DEF(readdir) -GEN_DEF(sigaction) -GEN_DEF(sigaddset) -GEN_DEF(sigdelset) -GEN_DEF(sigemptyset) -GEN_DEF(sigfillset) -GEN_DEF(sigismember) -GEN_DEF(sleep) -GEN_DEF(strtok_r) -GEN_DEF(times) -GEN_DEF(unsetenv) -GEN_DEF(vfscanf) +GEN_UNDEF(int,atexit,0) +GEN_UNDEF(int,catclose,0) +GEN_UNDEF(int,catgets,0) +GEN_UNDEF(int,catopen,0) +GEN_UNDEF(int,close,0) +GEN_UNDEF(int,closedir,0) +GEN_UNDEF(int,dlsym,0) +GEN_UNDEF(int,environ,0) +GEN_UNDEF(int,fgetc,0) +GEN_UNDEF(int,gethostname,0) +GEN_UNDEF(int,getrusage,0) +GEN_UNDEF(int,open,0) +GEN_UNDEF(int,opendir,0) +GEN_UNDEF(int,readdir,0) +GEN_UNDEF(int,sigaction,0) +GEN_UNDEF(int,sigaddset,0) +GEN_UNDEF(int,sigdelset,0) +GEN_UNDEF(int,sigemptyset,0) +GEN_UNDEF(int,sigfillset,0) +GEN_UNDEF(int,sigismember,0) +GEN_UNDEF(int,sleep,0) +GEN_UNDEF(int,strtok_r,0) +GEN_UNDEF(int,times,0) +GEN_UNDEF(int,unsetenv,0) +GEN_UNDEF(int,vfscanf,0) + + diff --git a/src/compat/libmcompat/Makefile b/src/compat/libmcompat/Makefile new file mode 100644 index 000000000..b24b6d378 --- /dev/null +++ b/src/compat/libmcompat/Makefile @@ -0,0 +1 @@ +obj-y += libmcompat.o diff --git a/src/compat/libmcompat/libmcompat.c b/src/compat/libmcompat/libmcompat.c new file mode 100644 index 000000000..60c677a49 --- /dev/null +++ b/src/compat/libmcompat/libmcompat.c @@ -0,0 +1,189 @@ +/* + * This file is part of the Nautilus AeroKernel developed + * by the Hobbes and V3VEE Projects with funding from the + * United States National Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. The Hobbes Project is a collaboration + * led by Sandia National Laboratories that includes several national + * laboratories and universities. You can find out more at: + * http://www.v3vee.org and + * http://xstack.sandia.gov/hobbes + * + * Copyright (c) 2015, Kyle C. Hale + * Copyright (c) 2015, The V3VEE Project + * The Hobbes Project + * All rights reserved. + * + * Authors: Kyle C. Hale + * Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "LICENSE.txt". + */ + +/* + * + * This file is intended to support libm functions + * + * + */ + + +#define LIBMCOMPAT 1 + +#include +#include + + +#ifdef NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT +#define DEBUG(fmt, args...) DEBUG_PRINT("libm: " fmt, ##args) +#else +#define DEBUG(fmt, args...) +#endif +#define INFO(fmt, args...) INFO_PRINT("libm: " fmt, ##args) +#define ERROR(fmt, args...) ERROR_PRINT("libm: " fmt, ##args) +#define WARN(fmt, args...) WARN_PRINT("libm: " fmt, ##args) + + +#define GEN_UNDEF(t,f,v) \ + t f () { \ + UNDEF_FUN_ERR(); \ + return v; \ + } + + +#define BOGUS() BOGUS_FUN_ERR() + + + +union dbl { + double d; + uint64_t ui; + struct { + uint64_t frac:52; + uint32_t exp:11; + uint32_t sign:1; + } __packed; +} __packed; + +union flt { + float f; + uint32_t ui; + struct { + uint32_t frac:23; + uint32_t exp:8; + uint32_t sign:1; + } __packed; +} __packed; + + +double fabs(double x) +{ + union dbl f = {.d = x}; + f.sign = 0; + return f.d; +} + +double fmod(double y, double x) +{ + BOGUS(); + return (int)y % (int)x; +} + +double fmodnew(int y, int x) +{ + BOGUS(); + return y -x*(y/x); +} + +double modf(double y, double *x) +{ + BOGUS(); + *x = 0; + return 0.000; +} + + +double frexp(double x, int *e) +{ + BOGUS(); + *e = 0; + return 0.5; +} + +double ldexp(double x, int exp) +{ + BOGUS(); + union dbl f = {.d = x}; + f.exp+=exp; + return f.d; +} + +GEN_UNDEF(double,sin,0.0) +GEN_UNDEF(double,sinh,0.0) +GEN_UNDEF(double,cos,0.0) +GEN_UNDEF(double,cosh,0.0) +GEN_UNDEF(double,tan,0.0) +GEN_UNDEF(double,tanh,0.0) +GEN_UNDEF(double,asin,0.0) +GEN_UNDEF(double,acos,0.0) +GEN_UNDEF(double,atan,0.0) +GEN_UNDEF(double,atan2,0.0) + +double ceil(double x) +{ + BOGUS(); + return x; +} + +double floor(double x) +{ + BOGUS(); + return x; +} + +double sqrt(double x) +{ + BOGUS(); + return x; +} + +double pow(double x, double y) +{ + BOGUS(); + union dbl f = {.d = x}; + f.exp*=y; + return f.d; +} + +double log(double x) +{ + BOGUS(); + return x; +} + +double log10(double x) +{ + BOGUS(); + return x; +} + +double exp(double x) +{ + BOGUS(); + return x; +} + +#define CLD double // complex long double +#define CD double // complex double +#define CF float // complex float + +GEN_UNDEF(CLD,__mulxc3,0.0) +GEN_UNDEF(CD,__muldc3,0.0) +GEN_UNDEF(CF,__mulsc3,0.0) +GEN_UNDEF(CLD,__divxc3,0.0) +GEN_UNDEF(CD,__divdc3,0.0) +GEN_UNDEF(CF,__divsc3,0.0) + + diff --git a/src/nautilus/naut_string.c b/src/nautilus/naut_string.c index b4ee54a62..f4de28371 100644 --- a/src/nautilus/naut_string.c +++ b/src/nautilus/naut_string.c @@ -730,4 +730,18 @@ str_toupper (char * s) } +void *memchr(const void *str, int c, size_t n) +{ + while (n) { + if (*((const char *)str)==c) { + return (void*)str; + } + str++; + n--; + } + + return 0; +} + + From 971f8affe155a1a4dba83bccc36bb0786f80edc7 Mon Sep 17 00:00:00 2001 From: MJC Date: Sun, 19 Jul 2020 19:04:43 -0500 Subject: [PATCH 23/36] Add glue code and test code for libomp --- src/rt/openmp/omp/Makefile | 12 +- src/rt/openmp/omp/glue.c | 29 ++- src/rt/openmp/omp/omp.c | 48 ----- src/rt/openmp/omp/omptest/Makefile | 7 + src/rt/openmp/omp/omptest/ompsimpletest.c | 40 ++++ src/rt/openmp/omp/omptest/omptest.c | 231 ++++++++++++++++++++++ 6 files changed, 317 insertions(+), 50 deletions(-) delete mode 100644 src/rt/openmp/omp/omp.c create mode 100644 src/rt/openmp/omp/omptest/Makefile create mode 100644 src/rt/openmp/omp/omptest/ompsimpletest.c create mode 100644 src/rt/openmp/omp/omptest/omptest.c diff --git a/src/rt/openmp/omp/Makefile b/src/rt/openmp/omp/Makefile index b9d17d13c..47f131cf9 100644 --- a/src/rt/openmp/omp/Makefile +++ b/src/rt/openmp/omp/Makefile @@ -1,2 +1,12 @@ -obj-y = omp.o glue.o +CFLAGS += -w +obj-y += glue.o +obj-y += omptest/ + +# Note that we link with a patched version of the +# libopenmp.a library from LLVM, so there is very little +# implementation here except glue code +# +# Note also that libc, linux, and pthread compatibility +# features must be turned on +# diff --git a/src/rt/openmp/omp/glue.c b/src/rt/openmp/omp/glue.c index c4daee554..eb9c59457 100644 --- a/src/rt/openmp/omp/glue.c +++ b/src/rt/openmp/omp/glue.c @@ -1 +1,28 @@ -int some_glue_thing_for_omp; +// These functions don't need to do anything for the libomp.a version + +int nk_openmp_init() +{ + return 0; +} + +void nk_openmp_deinit() +{ + return; +} + +int nk_openmp_thread_init() +{ + return 0; +} + +int nk_openmp_thread_deinit() +{ + return 0; +} + +char **nk_environ(void) +{ + return 0; +} + + diff --git a/src/rt/openmp/omp/omp.c b/src/rt/openmp/omp/omp.c deleted file mode 100644 index 9b29f2ff3..000000000 --- a/src/rt/openmp/omp/omp.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the Nautilus AeroKernel developed - * by the Hobbes and V3VEE Projects with funding from the - * United States National Science Foundation and the Department of Energy. - * - * The V3VEE Project is a joint project between Northwestern University - * and the University of New Mexico. The Hobbes Project is a collaboration - * led by Sandia National Laboratories that includes several national - * laboratories and universities. You can find out more at: - * http://www.v3vee.org and - * http://xstack.sandia.gov/hobbes - * - * Copyright (c) 2020, Peter Dinda - * Copyright (c) 2020, The V3VEE Project - * The Hobbes Project - * All rights reserved. - * - * Author: Peter Dinda - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "LICENSE.txt". - */ - - -#include -#include - -int nk_openmp_init() -{ - return 0; -} - -void nk_openmp_deinit() -{ -} - - -int nk_openmp_thread_init() -{ - return 0; -} - -int nk_openmp_thread_deinit() -{ - return 0; -} - - diff --git a/src/rt/openmp/omp/omptest/Makefile b/src/rt/openmp/omp/omptest/Makefile new file mode 100644 index 000000000..7a5747fd7 --- /dev/null +++ b/src/rt/openmp/omp/omptest/Makefile @@ -0,0 +1,7 @@ +CFLAGS += -fopenmp -Iinclude/rt/openmp \ + -w + +obj-y += \ + ompsimpletest.o \ + omptest.o + diff --git a/src/rt/openmp/omp/omptest/ompsimpletest.c b/src/rt/openmp/omp/omptest/ompsimpletest.c new file mode 100644 index 000000000..be12bdeba --- /dev/null +++ b/src/rt/openmp/omp/omptest/ompsimpletest.c @@ -0,0 +1,40 @@ +#include +#include +#include +#ifndef NAUT_CONFIG_DEBUG_GPUDEV +#undef DEBUG_PRINT +#define DEBUG_PRINT(fmt, args...) +#endif + +#define ERROR(fmt, args...) ERROR_PRINT("gpudev: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("gpudev: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("gpudev: " fmt, ##args) +extern int pthread_init(void); + +static int handle_gputest (char * buf, void * priv) +{ + int i; + #pragma omp parallel + { + + /* long id = getpid(); */ + /* nk_vc_printf("****omptest==thread id %d", id); */ + #pragma omp for private(i) schedule(static, 1) + for( i=0;i<8;i++){ + long id = getpid(); + nk_vc_printf("****omptest==thread id %d\n", id); + nk_vc_printf("*****working %d\n",i); + } + + } + return 0; +} + + +static struct shell_cmd_impl omptest_impl = { + .cmd = "ompstest", + .help_str = "openmp simple test", + .handler = handle_gputest, +}; +nk_register_shell_cmd(omptest_impl); + diff --git a/src/rt/openmp/omp/omptest/omptest.c b/src/rt/openmp/omp/omptest/omptest.c new file mode 100644 index 000000000..4047b346b --- /dev/null +++ b/src/rt/openmp/omp/omptest/omptest.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +//#include +#ifndef NAUT_CONFIG_DEBUG_GPUDEV +#undef DEBUG_PRINT +#define DEBUG_PRINT(fmt, args...) +#endif + +#define ERROR(fmt, args...) ERROR_PRINT("omptest: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("omptest: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("omptest: " fmt, ##args) + +static inline uint16_t random() +{ + uint16_t t; + nk_get_rand_bytes((uint8_t *)&t,sizeof(t)); + return t; +} + +#define MAXN 5100 /* Max value of N */ +int N; /* Matrix size */ +int procs; /* Number of processors to use */ + +/* Matrices and vectors */ +volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; +volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; +/* A * X = B, solve for X */ + +int seed; +/* Prototype */ +void gauss(); /* The function you will provide. + * It is this routine that is timed. + * It is called only on the parent. + */ + +/* Initialize A and B (and X to 0.0s) */ +void initialize_inputs() { + int row, col; + + printf("\nInitializing...\n"); + // #pragma omp parallel num_threads(8) + { + // #pragma omp for private(row,col) schedule(static,1) nowait + for (col = 0; col < N; col++) { + + for (row = 0; row < N; row++) { + ORA[col][row] = (float) random()/32768.0; + } + ORB[col] = (float)random()/32768.0; + } + } +} + +void reset_inputs(){ + int row, col; + printf("\n reseting...\n"); + for (col = 0; col < N; col++) { + for (row = 0; row < N; row++) { + A[row][col] = ORA[row][col]; + } + B[col] = ORB[col]; + X[col] = 0.0; + } + +} + +/* Print input matrices */ +void print_inputs() { + int row, col; + + if (N < 1000) { + printf("\nA =\n\t"); + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + printf("%5.2f%s", A[row][col], (col < N-1) ? ", " : ";\n\t"); + } + } + printf("\nB = ["); + for (col = 0; col < N; col++) { + printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); + } + } +} + +void serialgauss(){ + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + + printf("Computing serially.\n"); + + /* Gaussian elimination */ + + for (norm = 0; norm < N - 1; norm++) { + + // int num = N - norm; + + + { + + //printf("%f ", A[norm][norm]); + + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm] / A[norm][norm]; + + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + //printf("%5.2f ", X[row]); + } + +} + +void ompgauss() { + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + //doneflag[0] = 1; + + printf("Computing using omp.\n"); + + /* Gaussian elimination */ + +#pragma omp parallel private(row, col, multiplier, norm) num_threads(procs) + { + for (norm = 0; norm < N - 1; norm++) { + #pragma omp for schedule(static,1) + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm]/A[norm][norm]; + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + nk_vc_printf("I am done\n"); + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + } +} + + +#define TIME() (double)nk_sched_get_realtime(); +static int handle_omptest (char * buf, void * priv) +{ + + int seed, size, np; + + if ((sscanf(buf,"omptest %d %d %d",&seed,&size,&np)!=3)) { + nk_vc_printf("Don't understand %s please input seed, matrix size and nprocs\n",buf); + return -1; + } + nk_rand_seed(seed); + N = size; + procs = np; + nk_vc_printf("seed %d, size, %d, nprocs: %d\n", seed, N, procs); + + initialize_inputs(); + reset_inputs(); + // print_inputs(); + + unsigned mxcsr; + __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + printf("ld %04x \n", mxcsr); + mxcsr = mxcsr ^ 0x0200; + printf("st %08x \n", mxcsr); + __asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); + __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + printf("ld %08x \n", mxcsr); + + double start = TIME(); + ompgauss(); + double end = TIME(); + double omp = end-start; + nk_vc_printf("openmp done %lf\n", omp); + float OMP[N]; + for(int row =0; row Date: Tue, 21 Jul 2020 11:51:20 -0500 Subject: [PATCH 24/36] Further changes to pthread library port --- src/compat/pthread/Makefile | 4 - src/compat/pthread/Makefile.PSP | 194 ------------------ src/compat/pthread/nk/nk_osal.c | 3 +- src/compat/pthread/nk/pte_types.h | 1 - src/compat/pthread/pte_threadStart.c | 4 +- src/compat/pthread/pthread_mutex_init.c | 13 +- src/compat/pthread/pthread_once.c | 4 +- .../pthread/pthread_timechange_handler_np.c | 2 +- 8 files changed, 12 insertions(+), 213 deletions(-) delete mode 100644 src/compat/pthread/Makefile.PSP diff --git a/src/compat/pthread/Makefile b/src/compat/pthread/Makefile index 71f2dfb49..11fa76b5d 100644 --- a/src/compat/pthread/Makefile +++ b/src/compat/pthread/Makefile @@ -1,10 +1,6 @@ -CFLAGS += -w NK_LIB =\ nk/ -PTHREAD_TEST =\ - pthreadtest/ - MUTEX_OBJS = \ pthread_mutex_unlock.o \ pthread_mutex_init.o \ diff --git a/src/compat/pthread/Makefile.PSP b/src/compat/pthread/Makefile.PSP deleted file mode 100644 index f9491e1f6..000000000 --- a/src/compat/pthread/Makefile.PSP +++ /dev/null @@ -1,194 +0,0 @@ - -CLEANUP_TYPE=C -#CLEANUP_TYPE=CPP - -VPATH = ../..:../helper - -TARGET_LIB = libpthread-psp.a - - -MUTEX_OBJS = \ - pthread_mutex_unlock.o \ - pthread_mutex_init.o \ - pthread_mutex_destroy.o \ - pthread_mutex_lock.o \ - pthread_mutex_timedlock.o \ - pthread_mutex_trylock.o - -MUTEXATTR_OBJS = \ - pthread_mutexattr_destroy.o \ - pthread_mutexattr_getkind_np.o \ - pthread_mutexattr_getpshared.o \ - pthread_mutexattr_gettype.o \ - pthread_mutexattr_init.o \ - pthread_mutexattr_setkind_np.o \ - pthread_mutexattr_setpshared.o \ - pthread_mutexattr_settype.o - -SUPPORT_OBJS = \ - pte_relmillisecs.o \ - pte_mutex_check_need_init.o \ - pte_threadDestroy.o \ - pte_new.o \ - pte_threadStart.o \ - global.o \ - pte_reuse.o \ - pthread_init.o \ - pthread_terminate.o - -THREAD_OBJS = \ - create.o \ - pthread_self.o \ - pthread_equal.o \ - pthread_join.o \ - pthread_detach.o \ - pte_detach.o \ - pte_callUserDestroyRoutines.o \ - pte_tkAssocDestroy.o \ - pthread_kill.o \ - pthread_attr_destroy.o \ - pthread_attr_getdetachstate.o \ - pthread_attr_getinheritsched.o \ - pthread_attr_getschedparam.o \ - pthread_attr_getschedpolicy.o \ - pthread_attr_getscope.o \ - pthread_attr_getstackaddr.o \ - pthread_attr_getstacksize.o \ - pthread_attr_init.o \ - pthread_attr_setdetachstate.o \ - pthread_attr_setinheritsched.o \ - pthread_attr_setschedparam.o \ - pthread_attr_setschedpolicy.o \ - pthread_attr_setscope.o \ - pthread_attr_setstackaddr.o \ - pthread_attr_setstacksize.o \ - pte_is_attr.o \ - pthread_exit.o \ - pthread_getschedparam.o \ - pthread_setschedparam.o \ - sched_get_priority_max.o \ - sched_get_priority_min.o - - -TLS_OBJS = \ - pthread_key_create.o \ - pthread_key_delete.o \ - pthread_getspecific.o \ - pthread_setspecific.o \ - pte_tkAssocCreate.o - -MISC_OBJS = \ - sched_yield.o \ - pthread_delay_np.o \ - pthread_testcancel.o \ - pte_throw.o \ - cleanup.o \ - pthread_once.o \ - pthread_num_processors_np.o \ - pte_getprocessors.o \ - pte_spinlock_check_need_init.o \ - global.o \ - pthread_timechange_handler_np.o \ - pte_cond_check_need_init.o \ - pthread_getconcurrency.o \ - pthread_setconcurrency.o \ - pte_cancellable_wait.o - -SEM_OBJS = \ - sem_close.o \ - sem_destroy.o \ - sem_getvalue.o \ - sem_init.o \ - sem_open.o \ - sem_post.o \ - sem_post_multiple.o \ - sem_timedwait.o \ - sem_trywait.o \ - sem_unlink.o \ - sem_wait.o - -BARRIER_OBJS = \ - pthread_barrier_init.o \ - pthread_barrier_destroy.o \ - pthread_barrier_wait.o \ - pthread_barrierattr_init.o \ - pthread_barrierattr_destroy.o \ - pthread_barrierattr_getpshared.o \ - pthread_barrierattr_setpshared.o \ - -SPIN_OBJS = \ - pthread_spin_destroy.o \ - pthread_spin_init.o \ - pthread_spin_lock.o \ - pthread_spin_trylock.o \ - pthread_spin_unlock.o - -CONDVAR_OBJS = \ - pthread_cond_destroy.o \ - pthread_cond_init.o \ - pthread_cond_signal.o \ - pthread_cond_wait.o \ - pthread_condattr_destroy.o \ - pthread_condattr_getpshared.o \ - pthread_condattr_init.o \ - pthread_condattr_setpshared.o - -RWLOCK_OBJS = \ - pthread_rwlock_init.o \ - pthread_rwlock_destroy.o \ - pthread_rwlock_rdlock.o \ - pthread_rwlock_timedrdlock.o \ - pthread_rwlock_timedwrlock.o \ - pthread_rwlock_tryrdlock.o \ - pthread_rwlock_trywrlock.o \ - pthread_rwlock_unlock.o \ - pthread_rwlock_wrlock.o \ - pthread_rwlockattr_init.o \ - pthread_rwlockattr_destroy.o \ - pthread_rwlockattr_getpshared.o \ - pthread_rwlockattr_setpshared.o \ - pte_rwlock_check_need_init.o \ - pte_rwlock_cancelwrwait.o - -CANCEL_OBJS = \ - pthread_cancel.o \ - pthread_setcanceltype.o \ - pthread_setcancelstate.o - -OS_OBJS = \ - psp_osal.o \ - tls-helper.o - -OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) - -INCDIR = -CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper -CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX -ASFLAGS = $(CFLAGS) - -LDFLAGS = -LIBS = - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - - -ifeq ($(CLEANUP_TYPE),CPPXX) - -CC=psp-g++ - -pte_throw.o: pte_throw.c - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c ../../pte_throw.c -o pte_throw.o - -pte_threadStart.o: pte_threadStart.c - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c ../../pte_threadStart.c -o pte_threadStart.o - -endif - -install: $(TARGET_LIB) - @cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib - @cp -v *.h `psp-config --psp-prefix`/include - @echo "Done." - diff --git a/src/compat/pthread/nk/nk_osal.c b/src/compat/pthread/nk/nk_osal.c index ce38c7641..95703e22a 100644 --- a/src/compat/pthread/nk/nk_osal.c +++ b/src/compat/pthread/nk/nk_osal.c @@ -3,7 +3,6 @@ #include "pte_types.h" #include "pte_osal.h" #include -#include #include #include #include @@ -22,7 +21,7 @@ //retrive osHandle from thread #define poffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define pcontainer_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + const typeof( ((type *)0)->member ) *__mptr = (typeof(((type *)0)->member)) (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define TIME() (unsigned int)nk_sched_get_realtime(); diff --git a/src/compat/pthread/nk/pte_types.h b/src/compat/pthread/nk/pte_types.h index 50c9d1830..a7d319b34 100644 --- a/src/compat/pthread/nk/pte_types.h +++ b/src/compat/pthread/nk/pte_types.h @@ -3,7 +3,6 @@ #define PTE_TYPES_H #include #include -#include #include #include #include diff --git a/src/compat/pthread/pte_threadStart.c b/src/compat/pthread/pte_threadStart.c index e8e206e89..e7ef8f413 100644 --- a/src/compat/pthread/pte_threadStart.c +++ b/src/compat/pthread/pte_threadStart.c @@ -242,7 +242,9 @@ int pte_threadStart (void *vthreadParms, void ** out) * Never reached. */ - return (unsigned) status; + //mjc from unsigned to unsigned * + // return (unsigned) status; + return (unsigned long int)status; } /* pte_threadStart */ diff --git a/src/compat/pthread/pthread_mutex_init.c b/src/compat/pthread/pthread_mutex_init.c index 581045ce6..3bed8b0b5 100644 --- a/src/compat/pthread/pthread_mutex_init.c +++ b/src/compat/pthread/pthread_mutex_init.c @@ -69,14 +69,11 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) { mx->lock_idx = 0; mx->recursive_count = 0; - DEBUG("attr addr %08x\n", attr); - DEBUG("attr kind %08x\n", *attr); - - mx->kind = PTHREAD_MUTEX_DEFAULT; - //mjc - //mx->kind = (attr == NULL || *attr == NULL \ - ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); - DEBUG("pass mxkind\n"); + //DEBUG("attr addr %08x\n", attr); + //DEBUG("attr kind %08x\n", *attr); + //mx->kind = PTHREAD_MUTEX_DEFAULT; + mx->kind = (attr == NULL || *attr == NULL ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); + //DEBUG("pass mxkind\n"); mx->ownerThread.p = NULL; pte_osSemaphoreCreate(0,&mx->handle); diff --git a/src/compat/pthread/pthread_once.c b/src/compat/pthread/pthread_once.c index 5faba0f83..ce4faa779 100644 --- a/src/compat/pthread/pthread_once.c +++ b/src/compat/pthread/pthread_once.c @@ -148,7 +148,7 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) pte_osSemaphoreCreate(0, (pte_osSemaphoreHandle*) &sema); if (PTE_ATOMIC_COMPARE_EXCHANGE((int *) &once_control->semaphore, - (int) sema, + (unsigned long int) sema, 0)) { pte_osSemaphoreDelete((pte_osSemaphoreHandle)sema); @@ -168,7 +168,7 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) { /* we were last */ if ((sema = - (pte_osSemaphoreHandle)PTE_ATOMIC_EXCHANGE((int *) &once_control->semaphore,0))) + (pte_osSemaphoreHandle)(unsigned long int)PTE_ATOMIC_EXCHANGE((int *) &once_control->semaphore,0))) { pte_osSemaphoreDelete(sema); } diff --git a/src/compat/pthread/pthread_timechange_handler_np.c b/src/compat/pthread/pthread_timechange_handler_np.c index 58f3111dc..2460bbc91 100644 --- a/src/compat/pthread/pthread_timechange_handler_np.c +++ b/src/compat/pthread/pthread_timechange_handler_np.c @@ -110,5 +110,5 @@ pthread_timechange_handler_np (void *arg) pte_osMutexUnlock(pte_cond_list_lock); - return (void *)(result != 0 ? EAGAIN : 0); + return (void *)(unsigned long int)(result != 0 ? EAGAIN : 0); } From aefe49bcf3c77fd9cd39a4b4ed2643b62f08db88 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Tue, 21 Jul 2020 12:24:44 -0500 Subject: [PATCH 25/36] A bit more cleanup of pthread and omp tests --- Kconfig | 7 +++++++ src/compat/pthread/Makefile | 3 ++- src/rt/openmp/omp/omptest/ompsimpletest.c | 17 ++++++----------- src/rt/openmp/omp/omptest/omptest.c | 22 +++++++++------------- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Kconfig b/Kconfig index c6ac34d5f..609230b4d 100644 --- a/Kconfig +++ b/Kconfig @@ -879,6 +879,13 @@ menu "Compatability" help POSIX threads + config BASE_PTHREAD_COMPAT_TESTS + bool "Add POSIX threads compatability layer tests" + depends on BASE_PTHREAD_COMPAT + default n + help + Enable tests for this layer + config DEBUG_BASE_PTHREAD_COMPAT bool "Debug basic POSIX threads compatability layer" depends on BASE_PTHREAD_COMPAT diff --git a/src/compat/pthread/Makefile b/src/compat/pthread/Makefile index 11fa76b5d..20ea25028 100644 --- a/src/compat/pthread/Makefile +++ b/src/compat/pthread/Makefile @@ -155,6 +155,7 @@ CANCEL_OBJS = \ OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) obj-y +=$(OBJS) \ $(NK_LIB) \ - $(PTHREAD_TEST) + +obj-$(NAUT_CONFIG_BASE_PTHREAD_COMPAT_TESTS) += pthreadtest/ diff --git a/src/rt/openmp/omp/omptest/ompsimpletest.c b/src/rt/openmp/omp/omptest/ompsimpletest.c index be12bdeba..87c6525b2 100644 --- a/src/rt/openmp/omp/omptest/ompsimpletest.c +++ b/src/rt/openmp/omp/omptest/ompsimpletest.c @@ -1,17 +1,12 @@ #include #include #include -#ifndef NAUT_CONFIG_DEBUG_GPUDEV -#undef DEBUG_PRINT -#define DEBUG_PRINT(fmt, args...) -#endif -#define ERROR(fmt, args...) ERROR_PRINT("gpudev: " fmt, ##args) -#define DEBUG(fmt, args...) DEBUG_PRINT("gpudev: " fmt, ##args) -#define INFO(fmt, args...) INFO_PRINT("gpudev: " fmt, ##args) -extern int pthread_init(void); +#define ERROR(fmt, args...) ERROR_PRINT("ompstest: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("ompstest: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("ompstest: " fmt, ##args) -static int handle_gputest (char * buf, void * priv) +static int handle_test (char * buf, void * priv) { int i; #pragma omp parallel @@ -33,8 +28,8 @@ static int handle_gputest (char * buf, void * priv) static struct shell_cmd_impl omptest_impl = { .cmd = "ompstest", - .help_str = "openmp simple test", - .handler = handle_gputest, + .help_str = "ompstest (openmp simple test)", + .handler = handle_test, }; nk_register_shell_cmd(omptest_impl); diff --git a/src/rt/openmp/omp/omptest/omptest.c b/src/rt/openmp/omp/omptest/omptest.c index 4047b346b..cf6f4390e 100644 --- a/src/rt/openmp/omp/omptest/omptest.c +++ b/src/rt/openmp/omp/omptest/omptest.c @@ -2,11 +2,6 @@ #include #include #include -//#include -#ifndef NAUT_CONFIG_DEBUG_GPUDEV -#undef DEBUG_PRINT -#define DEBUG_PRINT(fmt, args...) -#endif #define ERROR(fmt, args...) ERROR_PRINT("omptest: " fmt, ##args) #define DEBUG(fmt, args...) DEBUG_PRINT("omptest: " fmt, ##args) @@ -20,23 +15,24 @@ static inline uint16_t random() } #define MAXN 5100 /* Max value of N */ -int N; /* Matrix size */ -int procs; /* Number of processors to use */ + +static int N; /* Matrix size */ +static int procs; /* Number of processors to use */ /* Matrices and vectors */ -volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; -volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; +static volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; +static volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; /* A * X = B, solve for X */ -int seed; +static int seed; /* Prototype */ -void gauss(); /* The function you will provide. +static void gauss(); /* The function you will provide. * It is this routine that is timed. * It is called only on the parent. */ /* Initialize A and B (and X to 0.0s) */ -void initialize_inputs() { +static void initialize_inputs() { int row, col; printf("\nInitializing...\n"); @@ -224,7 +220,7 @@ static int handle_omptest (char * buf, void * priv) static struct shell_cmd_impl omptest_impl = { .cmd = "omptest", - .help_str = "openmp test", + .help_str = "omptest seed size np (openmp Gaussian elimination test)", .handler = handle_omptest, }; nk_register_shell_cmd(omptest_impl); From df0f2dc745129f3951d95c9d9861d03647b1f720 Mon Sep 17 00:00:00 2001 From: MJC Date: Wed, 22 Jul 2020 15:12:08 +0800 Subject: [PATCH 26/36] add two missing pthread functions --- src/compat/pthread/pthread_attr_getstack.c | 57 ++++++++++++++++++++++ src/compat/pthread/pthread_getattr_np.c | 11 +++++ 2 files changed, 68 insertions(+) create mode 100644 src/compat/pthread/pthread_attr_getstack.c create mode 100644 src/compat/pthread/pthread_getattr_np.c diff --git a/src/compat/pthread/pthread_attr_getstack.c b/src/compat/pthread/pthread_attr_getstack.c new file mode 100644 index 000000000..50dd97dfa --- /dev/null +++ b/src/compat/pthread/pthread_attr_getstack.c @@ -0,0 +1,57 @@ +/* + * pthread_attr_getstackaddr.c + * + * Description: + * This translation unit implements operations on thread attribute objects. + * + * -------------------------------------------------------------------------- + * + * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems + * Copyright(C) 2008 Jason Schmidlapp + * + * Contact Email: jschmidlapp@users.sourceforge.net + * + * + * Based upon Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The original list of contributors to the Pthreads-win32 project + * is contained in the file CONTRIBUTORS.ptw32 included with the + * source code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +int +pthread_attr_getstack (const pthread_attr_t * attr, void **stackaddr, size_t *stacksize) +{ + int addr = pthread_attr_getstackaddr(attr, stackaddr); + int size = pthread_attr_getstacksize(attr,stacksize); + if ((addr == size) == 0){ + return 0; + } + + return 0; +} diff --git a/src/compat/pthread/pthread_getattr_np.c b/src/compat/pthread/pthread_getattr_np.c new file mode 100644 index 000000000..5118b4893 --- /dev/null +++ b/src/compat/pthread/pthread_getattr_np.c @@ -0,0 +1,11 @@ +#include "pthread.h" +#include "implement.h" + + +int +pthread_getattr_np (pthread_t thread ,pthread_attr_t * attr) +{ + // *attr = thread.attr; + return 0; + +} From 989e623b4c98bb37175878499967eb86ba53ede4 Mon Sep 17 00:00:00 2001 From: MJC Date: Wed, 22 Jul 2020 14:41:49 +0800 Subject: [PATCH 27/36] For omptest to run, hwtls has to be allocated some space, the trivial workaround is allocated some space for hw-tls in heap. However this change is not in this patch since it's not decided yet. ------------------------------------------------------------------- major changes in this patch: pthread_mutex_init: mx->kind will fault at original line, changed to default kind setenv: env search returns -1 will result in success by if(-1), set it to ==0; nk_environ: this return char **, but it can't be null/0; allocate dummy space for now; pthread_atfork: not supported and change to return 0, since return -1 will fail openmp runtime; omp/glue.c: add initialization of pthread and env; otherwise openmp can't initialize; omptest.c: the part to detect floating point error is turned off; --- src/compat/libccompat/libccompat.c | 6 ++++-- src/compat/pthread/nk/nk_osal.c | 11 +++++++---- src/compat/pthread/pthread_mutex_init.c | 7 +++++-- src/rt/openmp/omp/glue.c | 18 +++++++++++++++--- src/rt/openmp/omp/omptest/omptest.c | 16 ++++++++-------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/compat/libccompat/libccompat.c b/src/compat/libccompat/libccompat.c index 24250e461..3ae0bd165 100644 --- a/src/compat/libccompat/libccompat.c +++ b/src/compat/libccompat/libccompat.c @@ -396,11 +396,13 @@ int setenv(const char *key, const char *value, int overwrite) { char *curval; struct nk_env * env = nk_env_find(NK_ENV_GLOBAL_NAME); - if (nk_env_search(env,(char*)key,&curval)) { + if (nk_env_search(env,(char*)key,&curval)==0) { if (overwrite) { return nk_env_update(env,(char*)key,(char*)value); } else { - return -1; + //no action + return 0; + // return -1; } } else { return nk_env_insert(env, (char*)key, (char*)value); diff --git a/src/compat/pthread/nk/nk_osal.c b/src/compat/pthread/nk/nk_osal.c index 95703e22a..1d78a49d7 100644 --- a/src/compat/pthread/nk/nk_osal.c +++ b/src/compat/pthread/nk/nk_osal.c @@ -374,7 +374,7 @@ pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTi if(pTimeout == NULL){ while(1){ - //DEBUG("osSemaphoreBusyWaitPend\n"); + DEBUG("osSemaphoreBusyWaitPend\n"); handle->flags = STATE_LOCK(&(handle->lock)); if(handle->count > 0){ handle->count--; @@ -394,7 +394,7 @@ pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTi } // We are ZOMBIE NOW! GO to sleep! while(1){ - ERROR("osSemaphoreSleepPend\n"); + DEBUG("osSemaphoreSleepPend\n"); handle->flags = STATE_LOCK(&(handle->lock)); if(handle->count > 0){ handle->count--; @@ -415,7 +415,7 @@ pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTi // and go to sleep - this will also release the lock // and reenable preemption nk_sched_sleep(&(handle->lock)); - DEBUG("*********wake up******\n"); + DEBUG("thread wake up from sleep\n"); irq_enable_restore(handle->flags); } @@ -673,5 +673,8 @@ int ftime(struct timeb *tb){ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { DEBUG("no support for pthrad_atfork()\n"); - return -1; + + //kmp fail at __kmp_register_atfork() with return -1 + return 0; + // return -1; } diff --git a/src/compat/pthread/pthread_mutex_init.c b/src/compat/pthread/pthread_mutex_init.c index 3bed8b0b5..ecff1aafa 100644 --- a/src/compat/pthread/pthread_mutex_init.c +++ b/src/compat/pthread/pthread_mutex_init.c @@ -71,8 +71,11 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) mx->recursive_count = 0; //DEBUG("attr addr %08x\n", attr); //DEBUG("attr kind %08x\n", *attr); - //mx->kind = PTHREAD_MUTEX_DEFAULT; - mx->kind = (attr == NULL || *attr == NULL ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); + + //this is mx->kind assignment is new + mx->kind = PTHREAD_MUTEX_DEFAULT; + // below is original assignment, it fails + // mx->kind = (attr == NULL || *attr == NULL ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); //DEBUG("pass mxkind\n"); mx->ownerThread.p = NULL; diff --git a/src/rt/openmp/omp/glue.c b/src/rt/openmp/omp/glue.c index eb9c59457..cd1824760 100644 --- a/src/rt/openmp/omp/glue.c +++ b/src/rt/openmp/omp/glue.c @@ -1,7 +1,14 @@ // These functions don't need to do anything for the libomp.a version - +#include +#include +extern int pthread_init(void); int nk_openmp_init() { + nk_env_create(NK_ENV_GLOBAL_NAME, + NK_ENV_GLOBAL_MAX_NUM_KEYS, + NK_ENV_GLOBAL_MAX_KEY_SIZE, + NK_ENV_GLOBAL_MAX_VAL_SIZE); + pthread_init(); return 0; } @@ -21,8 +28,13 @@ int nk_openmp_thread_deinit() } char **nk_environ(void) -{ - return 0; +{ + char **dummy_space = malloc(sizeof(char*)); + memset(dummy_space,0,sizeof(char*)); + return dummy_space; + + //return null will fail at openmplib + //return 0; } diff --git a/src/rt/openmp/omp/omptest/omptest.c b/src/rt/openmp/omp/omptest/omptest.c index cf6f4390e..0300eb81d 100644 --- a/src/rt/openmp/omp/omptest/omptest.c +++ b/src/rt/openmp/omp/omptest/omptest.c @@ -182,14 +182,14 @@ static int handle_omptest (char * buf, void * priv) reset_inputs(); // print_inputs(); - unsigned mxcsr; - __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - printf("ld %04x \n", mxcsr); - mxcsr = mxcsr ^ 0x0200; - printf("st %08x \n", mxcsr); - __asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); - __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - printf("ld %08x \n", mxcsr); + //unsigned mxcsr; + //__asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + //printf("ld %04x \n", mxcsr); + //mxcsr = mxcsr ^ 0x0200; + //printf("st %08x \n", mxcsr); + //__asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); + // __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + //printf("ld %08x \n", mxcsr); double start = TIME(); ompgauss(); From 180238450028d5ac96080a0b033454689ca02a78 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Wed, 22 Jul 2020 13:38:14 -0500 Subject: [PATCH 28/36] More detailed output from omptest and ptest - avoid nan issue in printing --- src/compat/libccompat/libccompat.c | 2 +- src/rt/openmp/omp/omptest/omptest.c | 53 ++++++++++++++++++----------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/compat/libccompat/libccompat.c b/src/compat/libccompat/libccompat.c index 3ae0bd165..904a4bff6 100644 --- a/src/compat/libccompat/libccompat.c +++ b/src/compat/libccompat/libccompat.c @@ -223,7 +223,7 @@ vfprintf (FILE * stream, const char * format, va_list arg) UNDEF_FUN_ERR(); return -1; #else - if (stream!=stdout && stream!=stderr) { BOGUS(); } + if (stream!=stdout && stream!=stderr) { return 0; BOGUS(); } return vprintk(format,arg); #endif } diff --git a/src/rt/openmp/omp/omptest/omptest.c b/src/rt/openmp/omp/omptest/omptest.c index 0300eb81d..f8a89c960 100644 --- a/src/rt/openmp/omp/omptest/omptest.c +++ b/src/rt/openmp/omp/omptest/omptest.c @@ -35,7 +35,7 @@ static void gauss(); /* The function you will provide. static void initialize_inputs() { int row, col; - printf("\nInitializing...\n"); + nk_vc_printf("\nInitializing...\n"); // #pragma omp parallel num_threads(8) { // #pragma omp for private(row,col) schedule(static,1) nowait @@ -49,9 +49,9 @@ static void initialize_inputs() { } } -void reset_inputs(){ +static void reset_inputs(){ int row, col; - printf("\n reseting...\n"); + nk_vc_printf("\n reseting...\n"); for (col = 0; col < N; col++) { for (row = 0; row < N; row++) { A[row][col] = ORA[row][col]; @@ -62,30 +62,35 @@ void reset_inputs(){ } -/* Print input matrices */ -void print_inputs() { +static void print_state() { int row, col; + nk_vc_printf("A=%p, B=%p, X=%p\n", A, B, X); + if (N < 1000) { - printf("\nA =\n\t"); + nk_vc_printf("\nA =\n\t"); for (row = 0; row < N; row++) { for (col = 0; col < N; col++) { - printf("%5.2f%s", A[row][col], (col < N-1) ? ", " : ";\n\t"); + nk_vc_printf("%f%s ", A[row][col], (col < N-1) ? ", " : ";\n\t"); } } - printf("\nB = ["); + nk_vc_printf("\nB = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); + } + nk_vc_printf("\nX = ["); for (col = 0; col < N; col++) { - printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); + nk_vc_printf("%f%s ", X[col], (col < N-1) ? "; " : "]\n"); } } } -void serialgauss(){ +static void serialgauss(){ int norm, row, col; /* Normalization row, and zeroing * element row and col */ float multiplier; - printf("Computing serially.\n"); + nk_vc_printf("Computing serially.\n"); /* Gaussian elimination */ @@ -96,7 +101,7 @@ void serialgauss(){ { - //printf("%f ", A[norm][norm]); + //nk_vc_printf("%f ", A[norm][norm]); for (row = norm + 1; row < N; row++) { @@ -119,18 +124,18 @@ void serialgauss(){ X[row] -= A[row][col] * X[col]; } X[row] /= A[row][row]; - //printf("%5.2f ", X[row]); + //nk_vc_printf("%5.2f ", X[row]); } } -void ompgauss() { +static void ompgauss() { int norm, row, col; /* Normalization row, and zeroing * element row and col */ float multiplier; //doneflag[0] = 1; - printf("Computing using omp.\n"); + nk_vc_printf("Computing using omp.\n"); /* Gaussian elimination */ @@ -166,9 +171,10 @@ void ompgauss() { #define TIME() (double)nk_sched_get_realtime(); static int handle_omptest (char * buf, void * priv) { - + setenv("OMP_WHATEVER","53"); int seed, size, np; + if ((sscanf(buf,"omptest %d %d %d",&seed,&size,&np)!=3)) { nk_vc_printf("Don't understand %s please input seed, matrix size and nprocs\n",buf); return -1; @@ -180,20 +186,23 @@ static int handle_omptest (char * buf, void * priv) initialize_inputs(); reset_inputs(); - // print_inputs(); + nk_vc_printf("state before openmp run\n"); + print_state(); //unsigned mxcsr; //__asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - //printf("ld %04x \n", mxcsr); + //nk_vc_printf("ld %04x \n", mxcsr); //mxcsr = mxcsr ^ 0x0200; - //printf("st %08x \n", mxcsr); + //nk_vc_printf("st %08x \n", mxcsr); //__asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); // __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - //printf("ld %08x \n", mxcsr); + //nk_vc_printf("ld %08x \n", mxcsr); double start = TIME(); ompgauss(); double end = TIME(); + nk_vc_printf("state after openmp run\n"); + print_state(); double omp = end-start; nk_vc_printf("openmp done %lf\n", omp); float OMP[N]; @@ -202,9 +211,13 @@ static int handle_omptest (char * buf, void * priv) } reset_inputs(); + nk_vc_printf("state before serial run\n"); + print_state(); start = TIME(); serialgauss(); end = TIME(); + nk_vc_printf("state after serial run\n"); + print_state(); double serial = end-start; nk_vc_printf("serial done %lf\n", serial); float difference = 0.0; From f554c8a87f90042e8fe8e9274d04a42935c9875b Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Thu, 23 Jul 2020 15:29:36 -0500 Subject: [PATCH 29/36] Fix more floating point output bugs: - make doprnt work identically to the printk engine - handle negative nan correctly / string bug --- src/nautilus/doprnt.c | 25 +++++++++++++++++++------ src/nautilus/dtoa.c | 1 + src/nautilus/printk.c | 2 ++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/nautilus/doprnt.c b/src/nautilus/doprnt.c index 61bd87b04..4244957a9 100644 --- a/src/nautilus/doprnt.c +++ b/src/nautilus/doprnt.c @@ -530,17 +530,30 @@ void _doprnt (register const char * fmt, case 'F': case 'G': { - char buf[160]; + char dbuf[160]; char *c; - int dec, sign; - int pos; + int numdigits, myprec; + + // BOGUS stuff here, precision, etc, not handled to spec + if (length != 0) { + numdigits = length; + } else { + numdigits = 6; + } + + if (prec != -1) { + myprec = prec; + } else { + myprec = 6; + } + d = (double) va_arg(args, double); + - dtoa_printf_helper(d,*fmt,length,prec,buf,160); + dtoa_printf_helper(d,*fmt,numdigits,myprec,dbuf,160); - c = buf; - (*putc)(putc_arg,'@'); + c = dbuf; while (*c) { (*putc)(putc_arg, *c++); } diff --git a/src/nautilus/dtoa.c b/src/nautilus/dtoa.c index afaf49036..c847b5082 100644 --- a/src/nautilus/dtoa.c +++ b/src/nautilus/dtoa.c @@ -6257,6 +6257,7 @@ int dtoa_printf_helper(double x, char pf_type, int ndigits, int prec, char *buf if (s) { *c++ = '-'; + *c=0; } // handle special cases first diff --git a/src/nautilus/printk.c b/src/nautilus/printk.c index f6bffd23c..d3ea9869a 100644 --- a/src/nautilus/printk.c +++ b/src/nautilus/printk.c @@ -1233,6 +1233,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) char *c; int numdigits, prec; int k; + + // BOGUS stuff here, precision, etc, not handled to spec if (spec.precision != -1) { numdigits = spec.precision; From 2ed0f17f8391730f138b6d26737b809ab630bf2e Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Fri, 21 Aug 2020 19:51:39 -0500 Subject: [PATCH 30/36] Bug caught => xmm use in interrupt handlers breaking floating point code --- src/asm/excp_early.S | 36 +- src/rt/openmp/omp/omptest/omptest-internal.c | 240 +++++++++++ src/rt/openmp/omp/omptest/omptest-modified.c | 425 +++++++++++++++++++ src/rt/openmp/omp/omptest/omptest.c | 241 +---------- 4 files changed, 701 insertions(+), 241 deletions(-) create mode 100644 src/rt/openmp/omp/omptest/omptest-internal.c create mode 100644 src/rt/openmp/omp/omptest/omptest-modified.c mode change 100644 => 120000 src/rt/openmp/omp/omptest/omptest.c diff --git a/src/asm/excp_early.S b/src/asm/excp_early.S index 788ca0fd4..1d0a69ba7 100644 --- a/src/asm/excp_early.S +++ b/src/asm/excp_early.S @@ -75,6 +75,15 @@ GLOBAL(early_irq_common) SAVE_GPRS() +#ifdef NAUT_CONFIG_FPU_SAVE + /* Save the FPRs */ + movq %gs:0x0, %rax + movzwq 16(%rax), %rbx + leaq (%rax, %rbx, 1), %rbx + fxsave (%rbx) +#endif + + #ifdef NAUT_CONFIG_WATCHDOG // this call can nuke registers, but we don't // care because it is first, and we don't depend on @@ -197,6 +206,14 @@ thr_return: skip_cat_exit: +#endif + +#ifdef NAUT_CONFIG_FPU_SAVE + /* Restore the FPRs */ + movq %gs:0x0, %rax + movzwq 16(%rax), %rbx + leaq (%rax, %rbx, 1), %rbx + fxrstor (%rbx) #endif RESTORE_GPRS() @@ -224,6 +241,15 @@ GLOBAL(early_excp_common) SAVE_GPRS() +#ifdef NAUT_CONFIG_FPU_SAVE + /* Save the FPRs */ + movq %gs:0x0, %rax + movzwq 16(%rax), %rbx + leaq (%rax, %rbx, 1), %rbx + fxsave (%rbx) +#endif + + // Exceptions may occur before gsbase is set, for example breakpoints // or bugs in early code - so we need to guard // execution of the following code @@ -271,7 +297,15 @@ skip_per_cpu_update1: // we may now be outside of interrupt context skip_per_cpu_update2: - + +#ifdef NAUT_CONFIG_FPU_SAVE + /* Restore the FPRs */ + movq %gs:0x0, %rax + movzwq 16(%rax), %rbx + leaq (%rax, %rbx, 1), %rbx + fxrstor (%rbx) +#endif + RESTORE_GPRS() /* pop error code and excp number */ addq $16, %rsp diff --git a/src/rt/openmp/omp/omptest/omptest-internal.c b/src/rt/openmp/omp/omptest/omptest-internal.c new file mode 100644 index 000000000..f8a89c960 --- /dev/null +++ b/src/rt/openmp/omp/omptest/omptest-internal.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include + +#define ERROR(fmt, args...) ERROR_PRINT("omptest: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("omptest: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("omptest: " fmt, ##args) + +static inline uint16_t random() +{ + uint16_t t; + nk_get_rand_bytes((uint8_t *)&t,sizeof(t)); + return t; +} + +#define MAXN 5100 /* Max value of N */ + +static int N; /* Matrix size */ +static int procs; /* Number of processors to use */ + +/* Matrices and vectors */ +static volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; +static volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; +/* A * X = B, solve for X */ + +static int seed; +/* Prototype */ +static void gauss(); /* The function you will provide. + * It is this routine that is timed. + * It is called only on the parent. + */ + +/* Initialize A and B (and X to 0.0s) */ +static void initialize_inputs() { + int row, col; + + nk_vc_printf("\nInitializing...\n"); + // #pragma omp parallel num_threads(8) + { + // #pragma omp for private(row,col) schedule(static,1) nowait + for (col = 0; col < N; col++) { + + for (row = 0; row < N; row++) { + ORA[col][row] = (float) random()/32768.0; + } + ORB[col] = (float)random()/32768.0; + } + } +} + +static void reset_inputs(){ + int row, col; + nk_vc_printf("\n reseting...\n"); + for (col = 0; col < N; col++) { + for (row = 0; row < N; row++) { + A[row][col] = ORA[row][col]; + } + B[col] = ORB[col]; + X[col] = 0.0; + } + +} + +static void print_state() { + int row, col; + + nk_vc_printf("A=%p, B=%p, X=%p\n", A, B, X); + + if (N < 1000) { + nk_vc_printf("\nA =\n\t"); + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", A[row][col], (col < N-1) ? ", " : ";\n\t"); + } + } + nk_vc_printf("\nB = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); + } + nk_vc_printf("\nX = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", X[col], (col < N-1) ? "; " : "]\n"); + } + } +} + +static void serialgauss(){ + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + + nk_vc_printf("Computing serially.\n"); + + /* Gaussian elimination */ + + for (norm = 0; norm < N - 1; norm++) { + + // int num = N - norm; + + + { + + //nk_vc_printf("%f ", A[norm][norm]); + + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm] / A[norm][norm]; + + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + //nk_vc_printf("%5.2f ", X[row]); + } + +} + +static void ompgauss() { + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + //doneflag[0] = 1; + + nk_vc_printf("Computing using omp.\n"); + + /* Gaussian elimination */ + +#pragma omp parallel private(row, col, multiplier, norm) num_threads(procs) + { + for (norm = 0; norm < N - 1; norm++) { + #pragma omp for schedule(static,1) + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm]/A[norm][norm]; + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + nk_vc_printf("I am done\n"); + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + } +} + + +#define TIME() (double)nk_sched_get_realtime(); +static int handle_omptest (char * buf, void * priv) +{ + setenv("OMP_WHATEVER","53"); + int seed, size, np; + + + if ((sscanf(buf,"omptest %d %d %d",&seed,&size,&np)!=3)) { + nk_vc_printf("Don't understand %s please input seed, matrix size and nprocs\n",buf); + return -1; + } + nk_rand_seed(seed); + N = size; + procs = np; + nk_vc_printf("seed %d, size, %d, nprocs: %d\n", seed, N, procs); + + initialize_inputs(); + reset_inputs(); + nk_vc_printf("state before openmp run\n"); + print_state(); + + //unsigned mxcsr; + //__asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + //nk_vc_printf("ld %04x \n", mxcsr); + //mxcsr = mxcsr ^ 0x0200; + //nk_vc_printf("st %08x \n", mxcsr); + //__asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); + // __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); + //nk_vc_printf("ld %08x \n", mxcsr); + + double start = TIME(); + ompgauss(); + double end = TIME(); + nk_vc_printf("state after openmp run\n"); + print_state(); + double omp = end-start; + nk_vc_printf("openmp done %lf\n", omp); + float OMP[N]; + for(int row =0; row +#include +#include +#include +#include +#include "gomptestdata.h" + +#define ERROR(fmt, args...) ERROR_PRINT("omptest: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("omptest: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("omptest: " fmt, ##args) + +#define ALLOC(size) ({ void *__fake = malloc(size); if (!__fake) { ERROR("Failed to allocate %lu bytes\n",size); } __fake; }) + +static inline uint16_t random() +{ + uint16_t t; + nk_get_rand_bytes((uint8_t *)&t,sizeof(t)); + return t; +} + +#define MAXN 5100 /* Max value of N */ + +//static int N; /* Matrix size */ +static int procs; /* Number of processors to use */ + +/* Matrices and vectors */ +//static volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; +//static volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; + +static float **A; +static float *B, *X, *ORX; +/* A * X = B, solve for X */ + +static int seed; +/* Prototype */ +static void gauss(); /* The function you will provide. + * It is this routine that is timed. + * It is called only on the parent. + */ + +int ISNAN(float f) +{ + uint32_t val = *(uint32_t*)&f; + val &= 0x7fffffff; + + // S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF + // 11111111 => special FFF=0 => infinity, any F not zero => nan + + return ((val>>23)==0xff) && (val & 0x7fffff != 0); +} + + +uint32_t read_mxcsr() +{ + uint32_t val; + asm volatile ("stmxcsr %[_m]" : [_m] "=m" (val) : : "memory"); + return val; +} + +void write_mxcsr(uint32_t val) +{ + asm volatile ("ldmxcsr %[_m]" :: [_m] "m" (val) : "memory"); +} + +/* Initialize A and B (and X to 0.0s) */ +static void initialize_inputs() { + int row, col; + //ORA = ALLOC(N * sizeof(float *)); + A = ALLOC (N * sizeof(float *)); + for(int i = 0; i < N ; i++ ){ + //ORA[i] = ALLOC(N * sizeof(float)); + A[i] = ALLOC(N * sizeof(float)); + } + + //ORB = ALLOC(N * sizeof(float)); + B = ALLOC(N * sizeof(float)); + ORX = ALLOC(N * sizeof(float)); + X = ALLOC(N * sizeof(float)); + + /* nk_vc_printf("\nInitializing...\n"); */ + /* // #pragma omp parallel num_threads(8) */ + /* { */ + /* // #pragma omp for private(row,col) schedule(static,1) nowait */ + /* for (col = 0; col < N; col++) { */ + + /* for (row = 0; row < N; row++) { */ + /* ORA[col][row] = (float) random()/32768.0; */ + /* } */ + /* ORB[col] = (float)random()/32768.0; */ + /* } */ + /* } */ +} + +static void reset_inputs(){ + int row, col; + nk_vc_printf("\n reseting...\n"); + for (col = 0; col < N; col++) { + for (row = 0; row < N; row++) { + A[row][col] = ORA[row][col]; + } + B[col] = ORB[col]; + X[col] = 0.0; + } + +} + +static void print_state() { + int row, col; + + nk_vc_printf("A=%p, B=%p, X=%p\n", A, B, X); + + if (N < 3000) { + nk_vc_printf("\nA =\n\t"); + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", A[row][col], (col < N-1) ? ", " : ";\n\t"); + } + } + nk_vc_printf("\nB = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); + } + nk_vc_printf("\nX = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", X[col], (col < N-1) ? "; " : "]\n"); + } + } +} + +void check_state(int after) { + int row, col; + + // nk_vc_printf("A=%p, B=%p, X=%p\n", A, B, X); + nk_vc_printf("check_init_state(after=%d) mxcsr=%08x\n",after,read_mxcsr()); + + if (N < 3000) { + nk_vc_printf("check A\n"); + if (!after) { + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + if (ISNAN(ORA[row][col])) { + nk_vc_printf("found ORA nan at %d %d\n",row,col); + } + if (ISNAN(A[row][col])) { + nk_vc_printf("found A nan at %d %d\n",row,col); + } + if (A[row][col] != ORA[row][col]) { + nk_vc_printf("found flt A != ORA at %d %d (%f (%08x) addr %p <-> %f (%08x) addr %p mxcsr=%08x intr=%lu excp=%l\n",row,col,A[row][col],*(uint32_t*)&A[row][col], &A[row][col], ORA[row][col], *(uint32_t*)&ORA[row][col], &ORA[row][col],read_mxcsr(),get_cpu()->interrupt_count,get_cpu()->exception_count); + } + if (*(uint32_t *)&A[row][col] != *(uint32_t *)&ORA[row][col]) { + nk_vc_printf("found int A != ORA at %d %d (%f (%08x) addr %p <-> %f (%08x) addr %p\n",row,col,A[row][col],*(uint32_t*)&A[row][col], &A[row][col], ORA[row][col], *(uint32_t*)&ORA[row][col], &ORA[row][col]); + } + } + } + } + + nk_vc_printf("check B\n"); + + if (!after) { + for (col = 0; col < N; col++) { + if (ISNAN(ORB[col])) { + nk_vc_printf("found ORB nan at %d\n",col); + continue; + } + if (ISNAN(B[col])) { + nk_vc_printf("found B nan at %d\n",col); + continue; + } + if (B[col] != ORB[col]) { + nk_vc_printf("found B != ORB at %d\n",col); + continue; + } + } + } + + if (!after) { + for (col = 0; col < N; col++) { + if (ISNAN(X[col])) { + nk_vc_printf("found X nan at %d\n",col); + continue; + } + if (X[col] != 0) { + nk_vc_printf("found X !=0 at %d\n",col); + continue; + } + } + } + } +} + + +static void serialgauss(){ + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + + nk_vc_printf("Computing serially.\n"); + + /* Gaussian elimination */ + + for (norm = 0; norm < N - 1; norm++) { + + // int num = N - norm; + + + { + + //nk_vc_printf("%f ", A[norm][norm]); + + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm] / A[norm][norm]; + + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + //nk_vc_printf("%5.2f ", X[row]); + } + +} + +static void ompgauss() { + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + //doneflag[0] = 1; + + nk_vc_printf("Computing using omp.\n"); + + /* Gaussian elimination */ + +#pragma omp parallel private(row, col, multiplier, norm) num_threads(procs) + { + for (norm = 0; norm < N - 1; norm++) { + #pragma omp for schedule(static,1) + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm]/A[norm][norm]; + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + nk_vc_printf("I am done\n"); + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + } +} + + +#define TIME() (double)nk_sched_get_realtime(); +static int handle_omptest (char * buf, void * priv) +{ + setenv("OMP_WHATEVER","53"); + int seed, size, np; + + +#if 1 // BUG + nk_vc_printf("Initializing\n"); + nk_vc_printf("mxcsr=%08x\n",read_mxcsr()); + initialize_inputs(); + + nk_vc_printf("Round 1\n"); + reset_inputs(); + + float *SGAUSS; + SGAUSS = ALLOC(N*sizeof(float)); + + int nan_output_r1=0; + + reset_inputs(); + // while (1) { check_state(0); } + + check_state(0); + serialgauss(); + check_state(1); + + for(int row = 0; row < N; row++){ + if (ISNAN(X[row])) { + nan_output_r1 = 1; + } + SGAUSS[row] = X[row]; + } + + if (nan_output_r1) { + nk_vc_printf("Encountered nan in r1 solution\n"); + } + + int nan_output_r2=0; + + reset_inputs(); + check_state(0); + serialgauss(); + check_state(1); + + float diff2 = 0.0; + for(int row =0; row -#include -#include -#include - -#define ERROR(fmt, args...) ERROR_PRINT("omptest: " fmt, ##args) -#define DEBUG(fmt, args...) DEBUG_PRINT("omptest: " fmt, ##args) -#define INFO(fmt, args...) INFO_PRINT("omptest: " fmt, ##args) - -static inline uint16_t random() -{ - uint16_t t; - nk_get_rand_bytes((uint8_t *)&t,sizeof(t)); - return t; -} - -#define MAXN 5100 /* Max value of N */ - -static int N; /* Matrix size */ -static int procs; /* Number of processors to use */ - -/* Matrices and vectors */ -static volatile float A[MAXN][MAXN], B[MAXN], X[MAXN]; -static volatile float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; -/* A * X = B, solve for X */ - -static int seed; -/* Prototype */ -static void gauss(); /* The function you will provide. - * It is this routine that is timed. - * It is called only on the parent. - */ - -/* Initialize A and B (and X to 0.0s) */ -static void initialize_inputs() { - int row, col; - - nk_vc_printf("\nInitializing...\n"); - // #pragma omp parallel num_threads(8) - { - // #pragma omp for private(row,col) schedule(static,1) nowait - for (col = 0; col < N; col++) { - - for (row = 0; row < N; row++) { - ORA[col][row] = (float) random()/32768.0; - } - ORB[col] = (float)random()/32768.0; - } - } -} - -static void reset_inputs(){ - int row, col; - nk_vc_printf("\n reseting...\n"); - for (col = 0; col < N; col++) { - for (row = 0; row < N; row++) { - A[row][col] = ORA[row][col]; - } - B[col] = ORB[col]; - X[col] = 0.0; - } - -} - -static void print_state() { - int row, col; - - nk_vc_printf("A=%p, B=%p, X=%p\n", A, B, X); - - if (N < 1000) { - nk_vc_printf("\nA =\n\t"); - for (row = 0; row < N; row++) { - for (col = 0; col < N; col++) { - nk_vc_printf("%f%s ", A[row][col], (col < N-1) ? ", " : ";\n\t"); - } - } - nk_vc_printf("\nB = ["); - for (col = 0; col < N; col++) { - nk_vc_printf("%5.2f%s", B[col], (col < N-1) ? "; " : "]\n"); - } - nk_vc_printf("\nX = ["); - for (col = 0; col < N; col++) { - nk_vc_printf("%f%s ", X[col], (col < N-1) ? "; " : "]\n"); - } - } -} - -static void serialgauss(){ - int norm, row, col; /* Normalization row, and zeroing - * element row and col */ - float multiplier; - - nk_vc_printf("Computing serially.\n"); - - /* Gaussian elimination */ - - for (norm = 0; norm < N - 1; norm++) { - - // int num = N - norm; - - - { - - //nk_vc_printf("%f ", A[norm][norm]); - - for (row = norm + 1; row < N; row++) { - - multiplier = A[row][norm] / A[norm][norm]; - - for (col = norm; col < N; col++) { - A[row][col] -= A[norm][col] * multiplier; - } - B[row] -= B[norm] * multiplier; - } - } - } - /* (Diagonal elements are not normalized to 1. This is treated in back - * substitution.) - */ - /* Back substitution */ - for (row = N - 1; row >= 0; row--) { - X[row] = B[row]; - for (col = N-1; col > row; col--) { - X[row] -= A[row][col] * X[col]; - } - X[row] /= A[row][row]; - //nk_vc_printf("%5.2f ", X[row]); - } - -} - -static void ompgauss() { - int norm, row, col; /* Normalization row, and zeroing - * element row and col */ - float multiplier; - //doneflag[0] = 1; - - nk_vc_printf("Computing using omp.\n"); - - /* Gaussian elimination */ - -#pragma omp parallel private(row, col, multiplier, norm) num_threads(procs) - { - for (norm = 0; norm < N - 1; norm++) { - #pragma omp for schedule(static,1) - for (row = norm + 1; row < N; row++) { - - multiplier = A[row][norm]/A[norm][norm]; - for (col = norm; col < N; col++) { - A[row][col] -= A[norm][col] * multiplier; - } - B[row] -= B[norm] * multiplier; - } - } - } - nk_vc_printf("I am done\n"); - /* (Diagonal elements are not normalized to 1. This is treated in back - * substitution.) - */ - /* Back substitution */ - for (row = N - 1; row >= 0; row--) { - X[row] = B[row]; - for (col = N-1; col > row; col--) { - X[row] -= A[row][col] * X[col]; - } - X[row] /= A[row][row]; - } -} - - -#define TIME() (double)nk_sched_get_realtime(); -static int handle_omptest (char * buf, void * priv) -{ - setenv("OMP_WHATEVER","53"); - int seed, size, np; - - - if ((sscanf(buf,"omptest %d %d %d",&seed,&size,&np)!=3)) { - nk_vc_printf("Don't understand %s please input seed, matrix size and nprocs\n",buf); - return -1; - } - nk_rand_seed(seed); - N = size; - procs = np; - nk_vc_printf("seed %d, size, %d, nprocs: %d\n", seed, N, procs); - - initialize_inputs(); - reset_inputs(); - nk_vc_printf("state before openmp run\n"); - print_state(); - - //unsigned mxcsr; - //__asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - //nk_vc_printf("ld %04x \n", mxcsr); - //mxcsr = mxcsr ^ 0x0200; - //nk_vc_printf("st %08x \n", mxcsr); - //__asm__ volatile("stmxcsr %0"::"m"(*&mxcsr):"memory"); - // __asm__ volatile("ldmxcsr %0"::"m"(*&mxcsr):"memory"); - //nk_vc_printf("ld %08x \n", mxcsr); - - double start = TIME(); - ompgauss(); - double end = TIME(); - nk_vc_printf("state after openmp run\n"); - print_state(); - double omp = end-start; - nk_vc_printf("openmp done %lf\n", omp); - float OMP[N]; - for(int row =0; row Date: Wed, 29 Jul 2020 13:37:30 -0500 Subject: [PATCH 31/36] Add pthread test code --- src/compat/pthread/pthreadtest/Makefile | 6 + src/compat/pthread/pthreadtest/pthreadtest.c | 326 +++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 src/compat/pthread/pthreadtest/Makefile create mode 100644 src/compat/pthread/pthreadtest/pthreadtest.c diff --git a/src/compat/pthread/pthreadtest/Makefile b/src/compat/pthread/pthreadtest/Makefile new file mode 100644 index 000000000..ee13ba472 --- /dev/null +++ b/src/compat/pthread/pthreadtest/Makefile @@ -0,0 +1,6 @@ +CFLAGS +=\ + -w + +obj-y += \ + pthreadtest.o + diff --git a/src/compat/pthread/pthreadtest/pthreadtest.c b/src/compat/pthread/pthreadtest/pthreadtest.c new file mode 100644 index 000000000..749f972c4 --- /dev/null +++ b/src/compat/pthread/pthreadtest/pthreadtest.c @@ -0,0 +1,326 @@ +#include +#include +#include +#include +#include +#include "../pthread.h" +#include "../semaphore.h" + +#define ERROR(fmt, args...) ERROR_PRINT("pthreadtest: " fmt, ##args) +#define DEBUG(fmt, args...) DEBUG_PRINT("pthreadtest: " fmt, ##args) +#define INFO(fmt, args...) INFO_PRINT("pthreadtest: " fmt, ##args) + +static inline uint16_t random() +{ + uint16_t t; + nk_get_rand_bytes((uint8_t *)&t,sizeof(t)); + return t; +} + +#define MAXN 5100 /* Max value of N */ +static int N; /* Matrix size */ +static int procs; /* Number of processors to use */ + +/* Matrices and vectors */ +static float A[MAXN][MAXN], B[MAXN], X[MAXN]; +static float ORA[MAXN][MAXN], ORB[MAXN], ORX[MAXN]; +/* A * X = B, solve for X */ + +//int seed; +/* Prototype */ +static void gauss(); /* The function you will provide. + * It is this routine that is timed. + * It is called only on the parent. + */ + +//Initialize A and B (and X to 0.0s) +static void initialize_inputs() { + int row, col; + + printf("\nInitializing...\n"); + #pragma omp parallel private(col, row) no_wait num_threads(8) + for (col = 0; col < N; col++) { + #pragma omp for schedule(dynamic) + for (row = 0; row < N; row++) { + ORA[row][col] = (float) random()/32768.0; + } + ORB[col] = (float)random()/32768.0; + ORX[col] = 0.0; + } +} + +static void reset_inputs(){ + int row, col; + printf("\n reseting...\n"); + for (col = 0; col < N; col++) { + for (row = 0; row < N; row++) { + A[row][col] = ORA[row][col]; + } + B[col] = ORB[col]; + X[col] = 0.0; + } + +} + +static void print_state_hex() { + int row, col; + + if (N < 100) { + nk_vc_printf("\nA =\n\t"); + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + nk_vc_printf("%08x%s ", *(unsigned *)&(A[row][col]), (col < N-1) ? ", " : ";\n\t"); + } + } + nk_vc_printf("\nB = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%08x%s ", *(unsigned *)&(B[col]), (col < N-1) ? "; " : "]\n"); + } + nk_vc_printf("\nX = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%08x%s ", *(unsigned *)&(X[col]), (col < N-1) ? "; " : "]\n"); + } + } +} + +static void print_state() { + int row, col; + + if (N < 100) { + nk_vc_printf("\nA =\n\t"); + for (row = 0; row < N; row++) { + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", A[row][col], (col < N-1) ? ", " : ";\n\t"); + } + } + nk_vc_printf("\nB = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", B[col], (col < N-1) ? "; " : "]\n"); + } + nk_vc_printf("\nX = ["); + for (col = 0; col < N; col++) { + nk_vc_printf("%f%s ", X[col], (col < N-1) ? "; " : "]\n"); + } + } + + // print_state_hex(); +} + + + +//pthread_barrier_t barrier; +static sem_t mutex; +static sem_t barrier; +static int count = 0; +static int wait = 0; + +static int doneflag[MAXN] = {0}; +static pthread_mutex_t lock; +static void* cal_zero(void* threadid); + +static void serialgauss(){ + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + + nk_vc_printf("Computing serially.\n"); + + /* Gaussian elimination */ + + for (norm = 0; norm < N - 1; norm++) { + + // int num = N - norm; + + + { + + //nk_vc_printf("%f ", A[norm][norm]); + + for (row = norm + 1; row < N; row++) { + + multiplier = A[row][norm] / A[norm][norm]; + + for (col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + } + } + } + /* (Diagonal elements are not normalized to 1. This is treated in back + * substitution.) + */ + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + //nk_vc_printf("%5.2f ", X[row]); + } + +} + +static void pthreadgauss() { + int norm, row, col; /* Normalization row, and zeroing + * element row and col */ + float multiplier; + int numthreads = N-1; + doneflag[0] = 1; + pthread_t threads[procs]; + nk_vc_printf("Computing Using Pthread\n"); + pthread_mutex_init(&lock,NULL);; + // sem_init(&mutex,0,1); + // sem_init(&barrier,0,0); + //pthread_barrier_init(&barrier, NULL, numthreads); + for (int i=0; i < procs; i++) + { + pthread_create(&threads[i],NULL, &cal_zero, (void *)i); + } + + for(int i=0; i < procs; i++) + { + pthread_join(threads[i], NULL); + } + /* Back substitution */ + for (row = N - 1; row >= 0; row--) { + X[row] = B[row]; + for (col = N-1; col > row; col--) { + X[row] -= A[row][col] * X[col]; + } + X[row] /= A[row][row]; + } +} + +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static void *cal_zero(void* threadid) { + long id = (long) threadid; + float multiplier; + for (long norm = 0; norm < N-1 ; norm++){ + + //busy wait with relinquish cpu + while(1){ + pthread_mutex_lock(&lock); + + if( doneflag[norm] == 1){ + pthread_mutex_unlock(&lock); + break; + }else{ + pthread_mutex_unlock(&lock); + nk_yield(); + } + } + for(int row = id; row < N; row+=procs){ + if(row <= norm) + continue; + multiplier = A[row][norm] / A[norm][ norm]; + for (int col = norm; col < N; col++) { + A[row][col] -= A[norm][col] * multiplier; + } + B[row] -= B[norm] * multiplier; + + if(row == norm+1 ){ + //critical region + pthread_mutex_lock(&lock); + // for(int k=0;k<) + // nk_vc_printf("%d", doneflag); + doneflag[norm+1] = 1; + pthread_mutex_unlock(&lock); + } + } + } +} + + +#define TIME() (double)nk_sched_get_realtime()/1e9; +static int handle_pthreadtest (char * buf, void * priv) +{ + + int seed, size, np; + + if ((sscanf(buf,"ptest %d %d %d",&seed,&size,&np)!=3)) { + nk_vc_printf("Don't understand %s please input seed, matrix size and nprocs\n",buf); + return -1; + } + nk_rand_seed(seed); + N = size; + procs = np; + nk_vc_printf("seed %d, size, %d, nprocs: %d\n", seed, N, procs); + initialize_inputs(); + reset_inputs(); + nk_vc_printf("state before pthread run\n"); + print_state(); + double start = TIME(); + pthreadgauss(); + double end = TIME(); + nk_vc_printf("state after pthread run\n"); + print_state(); + double omp = end-start; + nk_vc_printf("openmp done %lf\n", omp); + float OMP[N]; + for(int row =0; row Date: Mon, 28 Dec 2020 17:00:17 -0600 Subject: [PATCH 32/36] Cleanup --- ENV | 1 - run | 1 - find_undef.pl => tools/find_undef.pl | 0 3 files changed, 2 deletions(-) delete mode 100644 ENV delete mode 100755 run rename find_undef.pl => tools/find_undef.pl (100%) diff --git a/ENV b/ENV deleted file mode 100644 index 2a203b6a6..000000000 --- a/ENV +++ /dev/null @@ -1 +0,0 @@ -export PATH=/home/pdinda/llvm/bin:$PATH diff --git a/run b/run deleted file mode 100755 index 7268d49fd..000000000 --- a/run +++ /dev/null @@ -1 +0,0 @@ -make -j isoimage && qemu-system-x86_64 -smp 1 -m 2048 -vga std -serial stdio -cdrom nautilus.iso -gdb tcp::1234 diff --git a/find_undef.pl b/tools/find_undef.pl similarity index 100% rename from find_undef.pl rename to tools/find_undef.pl From 72bd80ee095fbd747e6475ded1c41cca48f04d01 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 28 Dec 2020 17:48:24 -0600 Subject: [PATCH 33/36] More cleanup, update default testing config to match new features --- configs/testing/default.config | 12 +++++- src/compat/libmcompat/libmcompat.c | 59 ++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/configs/testing/default.config b/configs/testing/default.config index 938f5716f..5bd599c4c 100644 --- a/configs/testing/default.config +++ b/configs/testing/default.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Mon Dec 21 15:41:45 2020 +# Mon Dec 28 17:45:09 2020 # # @@ -70,6 +70,7 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # # NAUT_CONFIG_WATCHDOG is not set # NAUT_CONFIG_ISOCORE is not set +# NAUT_CONFIG_HARDWARE_TLS is not set # NAUT_CONFIG_CACHEPART is not set # @@ -82,6 +83,15 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # # NAUT_CONFIG_XSAVE_SUPPORT is not set +# +# Compatability +# +NAUT_CONFIG_BASE_LIBC_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBC_COMPAT is not set +NAUT_CONFIG_BASE_LIBM_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT is not set +# NAUT_CONFIG_BASE_LINUX_COMPAT is not set + # # Optimizations # diff --git a/src/compat/libmcompat/libmcompat.c b/src/compat/libmcompat/libmcompat.c index 60c677a49..ba4975d12 100644 --- a/src/compat/libmcompat/libmcompat.c +++ b/src/compat/libmcompat/libmcompat.c @@ -47,7 +47,13 @@ #define GEN_UNDEF(t,f,v) \ - t f () { \ + t f (double x) { \ + UNDEF_FUN_ERR(); \ + return v; \ + } + +#define GEN_UNDEF2(t,f,v) \ + t f (double x, double y) { \ UNDEF_FUN_ERR(); \ return v; \ } @@ -129,7 +135,7 @@ GEN_UNDEF(double,tanh,0.0) GEN_UNDEF(double,asin,0.0) GEN_UNDEF(double,acos,0.0) GEN_UNDEF(double,atan,0.0) -GEN_UNDEF(double,atan2,0.0) +GEN_UNDEF2(double,atan2,0.0) double ceil(double x) { @@ -175,15 +181,46 @@ double exp(double x) return x; } -#define CLD double // complex long double -#define CD double // complex double -#define CF float // complex float -GEN_UNDEF(CLD,__mulxc3,0.0) -GEN_UNDEF(CD,__muldc3,0.0) -GEN_UNDEF(CF,__mulsc3,0.0) -GEN_UNDEF(CLD,__divxc3,0.0) -GEN_UNDEF(CD,__divdc3,0.0) -GEN_UNDEF(CF,__divsc3,0.0) +// Complex intrinsics in case the compiler uses them... +// Weirdly, these sometimes need to exist even if you are not +// compiling for C99+ + +#include // creates the "complex" attribute + +complex long double __mulxc3(long double a, long double b, long double c, long double d) +{ + BOGUS(); + return (complex long double)0; +} + +complex double __muldc3(double a, double b, double c, double d) +{ + BOGUS(); + return (complex double)0; +} +complex float __mulsc3(float a, float b, float c, float d) +{ + BOGUS(); + return (complex float)0; +} + +complex long double __divxc3(long double a, long double b, long double c, long double d) +{ + BOGUS(); + return (complex long double)0; +} + +complex double __divdc3(double a, double b, double c, double d) +{ + BOGUS(); + return (complex double)0; +} + +complex float __divsc3(float a, float b, float c, float d) +{ + BOGUS(); + return (complex float)0; +} From 501b7191247fcbe4a0adc33b57477db8d2e15bbd Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 28 Dec 2020 18:14:22 -0600 Subject: [PATCH 34/36] More cleanup (HWTLS config, FP save on IRQ/EXCP config) --- Kconfig | 8 ++++++++ configs/testing/default.config | 11 ++++++++--- src/asm/excp_early.S | 8 ++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Kconfig b/Kconfig index 609230b4d..cdcc3c997 100644 --- a/Kconfig +++ b/Kconfig @@ -904,6 +904,14 @@ menu "Optimizations" Compiles the kernel to save FPU state on every context switch. This is not strictly necessary if processors are not virtualized (by the HRT). + + config FPU_SAVE_IRQ_EXCP + bool "Save FPU state on all interrupts and exceptions" + default y + help + Compiles the kernel to save FPU state on every exception and interrupt. + This is necessary if it is possible for the compiler to use + FP/SSE/AVX/etc state during an exception or interrupt handler config KICK_SCHEDULE bool "Kick cores with IPIs on scheduling events" diff --git a/configs/testing/default.config b/configs/testing/default.config index 5bd599c4c..c43b83139 100644 --- a/configs/testing/default.config +++ b/configs/testing/default.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Mon Dec 28 17:45:09 2020 +# Mon Dec 28 18:12:42 2020 # # @@ -70,7 +70,7 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # # NAUT_CONFIG_WATCHDOG is not set # NAUT_CONFIG_ISOCORE is not set -# NAUT_CONFIG_HARDWARE_TLS is not set +NAUT_CONFIG_HARDWARE_TLS=y # NAUT_CONFIG_CACHEPART is not set # @@ -90,12 +90,17 @@ NAUT_CONFIG_BASE_LIBC_COMPAT=y # NAUT_CONFIG_DEBUG_BASE_LIBC_COMPAT is not set NAUT_CONFIG_BASE_LIBM_COMPAT=y # NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT is not set -# NAUT_CONFIG_BASE_LINUX_COMPAT is not set +NAUT_CONFIG_BASE_LINUX_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LINUX_COMPAT is not set +NAUT_CONFIG_BASE_PTHREAD_COMPAT=y +# NAUT_CONFIG_BASE_PTHREAD_COMPAT_TESTS is not set +# NAUT_CONFIG_DEBUG_BASE_PTHREAD_COMPAT is not set # # Optimizations # NAUT_CONFIG_FPU_SAVE=y +NAUT_CONFIG_FPU_SAVE_IRQ_EXCP=y NAUT_CONFIG_KICK_SCHEDULE=y NAUT_CONFIG_HALT_WHILE_IDLE=y # NAUT_CONFIG_THREAD_OPTIMIZE is not set diff --git a/src/asm/excp_early.S b/src/asm/excp_early.S index 1d0a69ba7..b36b0e21e 100644 --- a/src/asm/excp_early.S +++ b/src/asm/excp_early.S @@ -75,7 +75,7 @@ GLOBAL(early_irq_common) SAVE_GPRS() -#ifdef NAUT_CONFIG_FPU_SAVE +#ifdef NAUT_CONFIG_FPU_SAVE_IRQ_EXCP /* Save the FPRs */ movq %gs:0x0, %rax movzwq 16(%rax), %rbx @@ -208,7 +208,7 @@ skip_cat_exit: #endif -#ifdef NAUT_CONFIG_FPU_SAVE +#ifdef NAUT_CONFIG_FPU_SAVE_IRQ_EXCP /* Restore the FPRs */ movq %gs:0x0, %rax movzwq 16(%rax), %rbx @@ -241,7 +241,7 @@ GLOBAL(early_excp_common) SAVE_GPRS() -#ifdef NAUT_CONFIG_FPU_SAVE +#ifdef NAUT_CONFIG_FPU_SAVE_IRQ_EXCP /* Save the FPRs */ movq %gs:0x0, %rax movzwq 16(%rax), %rbx @@ -298,7 +298,7 @@ skip_per_cpu_update1: skip_per_cpu_update2: -#ifdef NAUT_CONFIG_FPU_SAVE +#ifdef NAUT_CONFIG_FPU_SAVE_IRQ_EXCP /* Restore the FPRs */ movq %gs:0x0, %rax movzwq 16(%rax), %rbx From 005ad564e6e74e9ef45327f03ed8f034a28cdaff Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 28 Dec 2020 18:21:09 -0600 Subject: [PATCH 35/36] Missing file --- include/compat/linux/sysconf.h | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 include/compat/linux/sysconf.h diff --git a/include/compat/linux/sysconf.h b/include/compat/linux/sysconf.h new file mode 100644 index 000000000..3188aa142 --- /dev/null +++ b/include/compat/linux/sysconf.h @@ -0,0 +1,7 @@ +#ifndef _SYS_CONF_H_ +#define _SYS_CONF_H_ +extern long __sysconf(int name); + + + +#endif From b1f52cde8b9c6444ff0d9da6d7fae86f25a62186 Mon Sep 17 00:00:00 2001 From: Peter Dinda Date: Mon, 28 Dec 2020 18:27:21 -0600 Subject: [PATCH 36/36] Update testing configs --- configs/testing/default.config | 6 ++---- configs/testing/full-debug.config | 16 +++++++++++++++- configs/testing/prov_test.config | 16 +++++++++++++++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/configs/testing/default.config b/configs/testing/default.config index c43b83139..cd832fa59 100644 --- a/configs/testing/default.config +++ b/configs/testing/default.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Mon Dec 28 18:12:42 2020 +# Mon Dec 28 18:26:53 2020 # # @@ -92,9 +92,7 @@ NAUT_CONFIG_BASE_LIBM_COMPAT=y # NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT is not set NAUT_CONFIG_BASE_LINUX_COMPAT=y # NAUT_CONFIG_DEBUG_BASE_LINUX_COMPAT is not set -NAUT_CONFIG_BASE_PTHREAD_COMPAT=y -# NAUT_CONFIG_BASE_PTHREAD_COMPAT_TESTS is not set -# NAUT_CONFIG_DEBUG_BASE_PTHREAD_COMPAT is not set +# NAUT_CONFIG_BASE_PTHREAD_COMPAT is not set # # Optimizations diff --git a/configs/testing/full-debug.config b/configs/testing/full-debug.config index f8ab8b36f..4c18b26cd 100644 --- a/configs/testing/full-debug.config +++ b/configs/testing/full-debug.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Wed Jul 29 15:53:34 2020 +# Mon Dec 28 18:26:21 2020 # # @@ -77,6 +77,7 @@ NAUT_CONFIG_TEST_FIBERS=y # # NAUT_CONFIG_WATCHDOG is not set # NAUT_CONFIG_ISOCORE is not set +NAUT_CONFIG_HARDWARE_TLS=y # NAUT_CONFIG_CACHEPART is not set # @@ -89,10 +90,22 @@ NAUT_CONFIG_TEST_FIBERS=y # # NAUT_CONFIG_XSAVE_SUPPORT is not set +# +# Compatability +# +NAUT_CONFIG_BASE_LIBC_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBC_COMPAT is not set +NAUT_CONFIG_BASE_LIBM_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT is not set +NAUT_CONFIG_BASE_LINUX_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LINUX_COMPAT is not set +# NAUT_CONFIG_BASE_PTHREAD_COMPAT is not set + # # Optimizations # NAUT_CONFIG_FPU_SAVE=y +NAUT_CONFIG_FPU_SAVE_IRQ_EXCP=y # NAUT_CONFIG_KICK_SCHEDULE is not set # NAUT_CONFIG_HALT_WHILE_IDLE is not set # NAUT_CONFIG_THREAD_OPTIMIZE is not set @@ -119,6 +132,7 @@ NAUT_CONFIG_ENABLE_ASSERTS=y # NAUT_CONFIG_DEBUG_SHELL is not set # NAUT_CONFIG_DEBUG_SFI is not set # NAUT_CONFIG_DEBUG_CXX is not set +# NAUT_CONFIG_DEBUG_ENVS is not set # NAUT_CONFIG_DEBUG_THREADS is not set NAUT_CONFIG_DEBUG_FIBERS=y NAUT_CONFIG_DEBUG_TASKS=y diff --git a/configs/testing/prov_test.config b/configs/testing/prov_test.config index 858131307..5535220f6 100644 --- a/configs/testing/prov_test.config +++ b/configs/testing/prov_test.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit #Nautilus: -# Wed Jul 29 11:42:35 2020 +# Mon Dec 28 18:33:18 2020 # # @@ -71,6 +71,7 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # # NAUT_CONFIG_WATCHDOG is not set # NAUT_CONFIG_ISOCORE is not set +NAUT_CONFIG_HARDWARE_TLS=y # NAUT_CONFIG_CACHEPART is not set # @@ -83,10 +84,22 @@ NAUT_CONFIG_APERIODIC_ROUND_ROBIN=y # # NAUT_CONFIG_XSAVE_SUPPORT is not set +# +# Compatability +# +NAUT_CONFIG_BASE_LIBC_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBC_COMPAT is not set +NAUT_CONFIG_BASE_LIBM_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LIBM_COMPAT is not set +NAUT_CONFIG_BASE_LINUX_COMPAT=y +# NAUT_CONFIG_DEBUG_BASE_LINUX_COMPAT is not set +# NAUT_CONFIG_BASE_PTHREAD_COMPAT is not set + # # Optimizations # NAUT_CONFIG_FPU_SAVE=y +NAUT_CONFIG_FPU_SAVE_IRQ_EXCP=y # NAUT_CONFIG_KICK_SCHEDULE is not set # NAUT_CONFIG_HALT_WHILE_IDLE is not set # NAUT_CONFIG_THREAD_OPTIMIZE is not set @@ -115,6 +128,7 @@ NAUT_CONFIG_DEBUG_PROVENANCE=y # NAUT_CONFIG_DEBUG_SHELL is not set # NAUT_CONFIG_DEBUG_SFI is not set # NAUT_CONFIG_DEBUG_CXX is not set +# NAUT_CONFIG_DEBUG_ENVS is not set # NAUT_CONFIG_DEBUG_THREADS is not set # NAUT_CONFIG_DEBUG_TASKS is not set # NAUT_CONFIG_DEBUG_WAITQUEUES is not set