Skip to content

Commit

Permalink
Added 2.2.80-129
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Jul 13, 2020
1 parent 1d5cf4e commit a47808b
Show file tree
Hide file tree
Showing 15 changed files with 507 additions and 62 deletions.
1 change: 1 addition & 0 deletions libspe2.spec
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ rm -rf $RPM_BUILD_ROOT
%if %{build_common}
%preun -n elfspe2
[ -f %{_initdir}/elfspe ] && /sbin/chkconfig --del elfspe
[ -f %{_bindir}/elfspe-unregister ] && %{_bindir}/elfspe-unregister

%post -n elfspe2
[ -f %{_initdir}/elfspe ] && /sbin/chkconfig --add elfspe
Expand Down
6 changes: 4 additions & 2 deletions spebase/elf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,17 @@ apply_relocations(spe_program_handle_t *handle, Elf32_Shdr *rh, Elf32_Shdr *sh)
for (; r < r_end; ++r)
{
if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU32)) {
/* v is in ._ea */
Elf32_Word *loc = reloc_base + r->r_offset;
Elf32_Word v = (Elf32_Word)(long)start + r->r_addend;
Elf32_Word v = (unsigned long)start + r->r_addend;
/* Don't dirty pages unnecessarily. */
if (*loc != v)
*loc = v;
DEBUG_PRINTF("PPU32(%p) = %#x\n", loc, v);
} else if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU64)) {
/* v is in ._ea */
Elf64_Xword *loc = reloc_base + r->r_offset;
Elf64_Xword v = (Elf64_Xword)(long)start + r->r_addend;
Elf64_Xword v = (unsigned long)start + r->r_addend;
if (*loc != v)
*loc = v;
DEBUG_PRINTF("PPU64(%p) = %#llx\n", loc, v);
Expand Down
6 changes: 4 additions & 2 deletions spebase/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>


#include "info.h"
Expand All @@ -31,7 +32,7 @@ int _base_spe_count_physical_cpus(int cpu_node)
{
const char *buff = "/sys/devices/system/cpu";
DIR *dirp;
int ret = -2;
int ret = 0;
struct dirent *dptr;

DEBUG_PRINTF ("spe_count_physical_cpus()\n");
Expand All @@ -50,7 +51,8 @@ int _base_spe_count_physical_cpus(int cpu_node)
return -1;
}
while((dptr=readdir(dirp))) {
ret++;
if(strncmp("cpu",dptr->d_name,3) == 0)
ret++;
}
closedir(dirp);
return ret/THREADS_PER_BE;
Expand Down
174 changes: 148 additions & 26 deletions speevent/spe_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <stdlib.h>
#include "speevent.h"

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/epoll.h>
Expand Down Expand Up @@ -56,6 +57,75 @@ void _event_spe_context_unlock(spe_context_ptr_t spe)
pthread_mutex_unlock(&__SPE_EVENT_CONTEXT_PRIV_GET(spe)->lock);
}

static void stop_event_lock(spe_context_event_priv_ptr_t evctx)
{
pthread_mutex_lock(&evctx->stop_event_lock);
}

static void stop_event_unlock(spe_context_event_priv_ptr_t evctx)
{
pthread_mutex_unlock(&evctx->stop_event_lock);
}

static int stop_event_pipe_close(spe_context_event_priv_ptr_t evctx)
{
if (evctx->stop_event_pipe[0] != -1) {
close(evctx->stop_event_pipe[0]);
evctx->stop_event_pipe[0] = -1;
}
if (evctx->stop_event_pipe[1] != -1) {
close(evctx->stop_event_pipe[1]);
evctx->stop_event_pipe[1] = -1;
}

return 0;
}

static int stop_event_pipe_open(spe_context_event_priv_ptr_t evctx)
{
int rc;

rc = pipe(evctx->stop_event_pipe);
if (rc == -1) {
return -1;
}
rc = fcntl(evctx->stop_event_pipe[0], F_GETFL);
if (rc != -1) {
rc = fcntl(evctx->stop_event_pipe[0], F_SETFL, rc | O_NONBLOCK);
}
if (rc == -1) {
stop_event_pipe_close(evctx);
return -1;
}

return 0;
}

static int stop_event_pipe_acquire(spe_context_event_priv_ptr_t evctx)
{
if (evctx->stop_event_handler_count == 0) {
if (stop_event_pipe_open(evctx) == -1) {
return -1;
}
evctx->stop_event_buffer_count = 0; /* invalidate the buffer */
}

evctx->stop_event_handler_count++;

return 0;
}

static int stop_event_pipe_release(spe_context_event_priv_ptr_t evctx)
{
evctx->stop_event_handler_count--;

if (evctx->stop_event_handler_count == 0) {
stop_event_pipe_close(evctx);
}

return 0;
}

int _event_spe_stop_info_read (spe_context_ptr_t spe, spe_stop_info_t *stopinfo)
{
spe_context_event_priv_ptr_t evctx;
Expand All @@ -64,13 +134,32 @@ int _event_spe_stop_info_read (spe_context_ptr_t spe, spe_stop_info_t *stopinfo)
size_t total;

evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe);

stop_event_lock(evctx); /* for atomic read */

fd = evctx->stop_event_pipe[0];

pthread_mutex_lock(&evctx->stop_event_read_lock); /* for atomic read */
if (fd == -1) { /* no stop event handler */
if (evctx->stop_event_buffer_count) {
/* return the last stop info for backward compatibility */
memcpy(stopinfo, &evctx->stop_event_buffer, sizeof(*stopinfo));
evctx->stop_event_buffer_count--;
rc = 0;
}
else {
/* there is no valid stop info in the buffer */
errno = EAGAIN;
rc = -1;
}
stop_event_unlock(evctx);
return rc;
}

/* any stop event handler. */

rc = read(fd, stopinfo, sizeof(*stopinfo));
if (rc == -1) {
pthread_mutex_unlock(&evctx->stop_event_read_lock);
stop_event_unlock(evctx);
return -1;
}

Expand Down Expand Up @@ -98,7 +187,7 @@ int _event_spe_stop_info_read (spe_context_ptr_t spe, spe_stop_info_t *stopinfo)
}
}

pthread_mutex_unlock(&evctx->stop_event_read_lock);
stop_event_unlock(evctx);

return rc == -1 ? -1 : 0;
}
Expand Down Expand Up @@ -248,6 +337,15 @@ int _event_spe_event_handler_register(spe_event_handler_ptr_t evhandler, spe_eve
}

if (event->events & SPE_EVENT_SPE_STOPPED) {
/* prevent reading stop info while registering */
stop_event_lock(evctx);

if (stop_event_pipe_acquire(evctx) == -1) {
stop_event_unlock(evctx);
_event_spe_context_unlock(event->spe);
return -1;
}

fd = evctx->stop_event_pipe[0];

ev_buf = &evctx->events[__SPE_EVENT_SPE_STOPPED];
Expand All @@ -257,9 +355,13 @@ int _event_spe_event_handler_register(spe_event_handler_ptr_t evhandler, spe_eve
ep_event.events = EPOLLIN;
ep_event.data.ptr = ev_buf;
if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) {
stop_event_pipe_release(evctx);
stop_event_unlock(evctx);
_event_spe_context_unlock(event->spe);
return -1;
}

stop_event_unlock(evctx);
}

_event_spe_context_unlock(event->spe);
Expand Down Expand Up @@ -340,12 +442,20 @@ int _event_spe_event_handler_deregister(spe_event_handler_ptr_t evhandler, spe_e
}

if (event->events & SPE_EVENT_SPE_STOPPED) {
/* prevent reading stop info while unregistering */
stop_event_lock(evctx);

fd = evctx->stop_event_pipe[0];
if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) {
stop_event_unlock(evctx);
_event_spe_context_unlock(event->spe);
return -1;
}
evctx->events[__SPE_EVENT_SPE_STOPPED].events = 0;

stop_event_pipe_release(evctx);

stop_event_unlock(evctx);
}

_event_spe_context_unlock(event->spe);
Expand Down Expand Up @@ -424,12 +534,11 @@ int _event_spe_context_finalize(spe_context_ptr_t spe)

evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe);
__SPE_EVENT_CONTEXT_PRIV_SET(spe, NULL);

close(evctx->stop_event_pipe[0]);
close(evctx->stop_event_pipe[1]);

stop_event_pipe_close(evctx);

pthread_mutex_destroy(&evctx->lock);
pthread_mutex_destroy(&evctx->stop_event_read_lock);
pthread_mutex_destroy(&evctx->stop_event_lock);

free(evctx);

Expand All @@ -439,37 +548,23 @@ int _event_spe_context_finalize(spe_context_ptr_t spe)
struct spe_context_event_priv * _event_spe_context_initialize(spe_context_ptr_t spe)
{
spe_context_event_priv_ptr_t evctx;
int rc;
int i;

evctx = calloc(1, sizeof(*evctx));
if (!evctx) {
return NULL;
}

rc = pipe(evctx->stop_event_pipe);
if (rc == -1) {
free(evctx);
return NULL;
}
rc = fcntl(evctx->stop_event_pipe[0], F_GETFL);
if (rc != -1) {
rc = fcntl(evctx->stop_event_pipe[0], F_SETFL, rc | O_NONBLOCK);
}
if (rc == -1) {
close(evctx->stop_event_pipe[0]);
close(evctx->stop_event_pipe[1]);
free(evctx);
errno = EIO;
return NULL;
}
/* the pipe will be created when any stop event handler is registered */
evctx->stop_event_pipe[0] = -1;
evctx->stop_event_pipe[1] = -1;

for (i = 0; i < sizeof(evctx->events) / sizeof(evctx->events[0]); i++) {
evctx->events[i].spe = spe;
}

pthread_mutex_init(&evctx->lock, NULL);
pthread_mutex_init(&evctx->stop_event_read_lock, NULL);
pthread_mutex_init(&evctx->stop_event_lock, NULL);

return evctx;
}
Expand All @@ -479,17 +574,44 @@ int _event_spe_context_run (spe_context_ptr_t spe, unsigned int *entry, unsigned
spe_context_event_priv_ptr_t evctx;
spe_stop_info_t stopinfo_buf;
int rc;
int errno_saved;
int fd;

if (!stopinfo) {
stopinfo = &stopinfo_buf;
}
rc = _base_spe_context_run(spe, entry, runflags, argp, envp, stopinfo);
errno_saved = errno;

evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe);
if (write(evctx->stop_event_pipe[1], stopinfo, sizeof(*stopinfo)) != sizeof(*stopinfo)) {

stop_event_lock(evctx);

fd = evctx->stop_event_pipe[1];
/* don't write stop info to the pipe if no stop event handler is registered */
if (fd == -1) {
/* store the last stop info in the internal buffer for backward
* compatibility */
memcpy(&evctx->stop_event_buffer, stopinfo, sizeof(*stopinfo));
evctx->stop_event_buffer_count = 1; /* overwrite the buffer */
stop_event_unlock(evctx);
return rc;
}

stop_event_pipe_acquire(evctx); /* to avoid closing the pipe after unlocked */
stop_event_unlock(evctx); /* unlock here to avoid deadlocks */

if (write(fd, stopinfo, sizeof(*stopinfo)) != sizeof(*stopinfo)) {
/* error check. */
}

/* release the pipe */
stop_event_lock(evctx);
stop_event_pipe_release(evctx);
stop_event_unlock(evctx);

errno = errno_saved;

return rc;
}

5 changes: 4 additions & 1 deletion speevent/speevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ enum __spe_event_types {
typedef struct spe_context_event_priv
{
pthread_mutex_t lock;
pthread_mutex_t stop_event_read_lock;
pthread_mutex_t stop_event_lock;
int stop_event_pipe[2];
int stop_event_handler_count;
int stop_event_buffer_count;
spe_stop_info_t stop_event_buffer;
spe_event_unit_t events[__NUM_SPE_EVENT_TYPES];
} spe_context_event_priv_t, *spe_context_event_priv_ptr_t;

Expand Down
8 changes: 7 additions & 1 deletion tests/libspe2.event/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ main_progs = \
test_event_tag_group.elf \
test_event_wbox.elf \
test_event.elf \
test_event_error.elf
test_event_error.elf \
test_event_stop_no_read.elf \
test_event_stop_no_handler.elf


include $(TEST_TOP)/make.rules
Expand All @@ -44,6 +46,10 @@ test_event_wbox.elf: spu_event_wbox.embed.o

test_event.elf: spu_event.embed.o

test_event_stop_no_read.elf: spu_event_stop.embed.o

test_event_stop_no_handler.elf: spu_event_stop.embed.o

spu_ibox.c: ../libspe2.mfc/spu_ibox.c
ln -sf $< $@

Expand Down
8 changes: 8 additions & 0 deletions tests/libspe2.event/test_event_stop.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ static int test(int argc, char **argv)
for (i = 0; i < NUM_SPES; i++) {
pthread_join(params[i].tid, NULL);

event[0].spe = params[i].spe;
event[0].events = SPE_EVENT_SPE_STOPPED;
ret = spe_event_handler_deregister(evhandler, event);
if (ret == -1) {
eprintf("spe_event_handler_deregister: %s\n", strerror(errno));
fatal();
}

if (params[i].num_stop > COUNT) {
eprintf("spe[%u]: too many events (%u/%u).\n", i, params[i].num_stop, COUNT);
failed();
Expand Down
Loading

0 comments on commit a47808b

Please sign in to comment.